From: Brad Smith Subject: Re: UPDATE: recoil-rts - arm64 To: Thomas Frohwein Cc: fabienromano@gmail.com, ports@openbsd.org Date: Thu, 3 Sep 2026 01:26:25 -0400 On Tue, Sep 01, 2026 at 10:08:51PM -0400, Brad Smith wrote: > On Thu, Aug 27, 2026 at 01:19:23AM -0400, Brad Smith wrote: > > On Mon, Jul 27, 2026 at 01:14:34PM -0700, Thomas Frohwein wrote: > > > On Sat, 25 Jul 2026 18:24:57 -0400 > > > Brad Smith wrote: > > > > > > > Within the last few months recoil-rts has gained support for building > > > > on aarch64. The following diff fixes building the port on aarch64. > > > > > > Thanks, Brad. This is a fairly big port and I'm reluctant to enable it > > > for arm64 without reports on the test suite (`make test`) and runtime. > > > > I had ran the test suite, ran into some that were failing. I tracked > > down why one was failing and had the bug fixed upstream. The testClampRad > > failure upstream is aware of and is undefined beavior for the failing test. > > The test needs to be fixed. > > > > > > 93% tests passed, 2 tests failed out of 29 > > > > Total Test time (real) = 108.72 sec > > > > The following tests FAILED: > > 17 - testCreg (Failed) > > 25 - testClampRad (Failed) > > > > I can run beyond-all-reason and it downloads assets and the game runs. > > I can run the Scenarios, the maps download and load. Its just slow as > > I am running it remotely. > > > > > A convenient way to test runtime (if you don't mind the assets that are > > > downloaded into ~/.local/state/BAR) is running > > > > > > $ beyond-all-reason > > > > > > and then testing something from "Scenarios" (button on the left). The > > > first one, "Fortress Assault" would be good one to just load up and give > > > some commands to the units. > > > > > > Benchmarking can be done in the scenarios at the bottom, "Benchmark > > > BAR" and "Benchmark pathfinding" will give some times for rendering and > > > don't require input. > > > > Being this is remote and it is not quick at all. > > > > I am just trying to get the package to build and make sure it works as a > > start on aarch64; since I noticed upstream added aarch64 support very > > recently by a team of people working on macOS and Linux support. > > An updated diff. > > I fixed the other 2 issues found by the unit tests. And last rev. A small tweak to the last fix. Index: Makefile =================================================================== RCS file: /cvs/ports/games/recoil-rts/Makefile,v retrieving revision 1.29 diff -u -p -u -p -r1.29 Makefile --- Makefile 13 Aug 2026 13:53:11 -0000 1.29 +++ Makefile 2 Sep 2026 20:52:26 -0000 @@ -9,6 +9,7 @@ COMMENT = real-time strategy game engin V = 2026.07.04 PKGNAME = recoil-rts-${V} +REVISION = 0 DIST_TUPLE += github beyond-all-reason RecoilEngine ${V} . DIST_TUPLE += github mikke89 RmlUi \ Index: patches/patch-rts_Sim_Objects_SolidObject_cpp =================================================================== RCS file: patches/patch-rts_Sim_Objects_SolidObject_cpp diff -N patches/patch-rts_Sim_Objects_SolidObject_cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-rts_Sim_Objects_SolidObject_cpp 2 Sep 2026 20:52:26 -0000 @@ -0,0 +1,15 @@ +- fix a failing creg unit test + 4ab6518dc3469dd143305927071828acc85a3c58 + +Index: rts/Sim/Objects/SolidObject.cpp +--- rts/Sim/Objects/SolidObject.cpp.orig ++++ rts/Sim/Objects/SolidObject.cpp +@@ -51,6 +51,8 @@ CR_REG_METADATA(CSolidObject, + CR_MEMBER(team), + CR_MEMBER(allyteam), + ++ CR_MEMBER_UN(paletteIndex), ++ + CR_MEMBER(creationFrame), + + CR_MEMBER(pieceHitFrames), Index: patches/patch-rts_System_creg_SerializeLuaState_cpp =================================================================== RCS file: patches/patch-rts_System_creg_SerializeLuaState_cpp diff -N patches/patch-rts_System_creg_SerializeLuaState_cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-rts_System_creg_SerializeLuaState_cpp 2 Sep 2026 20:52:26 -0000 @@ -0,0 +1,15 @@ +- fix a unit test failing on OpenBSD/aarch64 + fa50380be027b66f702efb4bc5a37b1d2c35f4f2 + +Index: rts/System/creg/SerializeLuaState.cpp +--- rts/System/creg/SerializeLuaState.cpp.orig ++++ rts/System/creg/SerializeLuaState.cpp +@@ -1042,7 +1042,7 @@ void creg_lua_State::PostLoad() + } + + size_t savedpc_offset = * (size_t *) &savedpc; +- savedpc = GetProtoFromCallInfo(ci)->code + savedpc_offset; ++ savedpc = GetProtoFromCallInfo(ci - 1)->code + savedpc_offset; + } + + Index: patches/patch-test_engine_System_testClampRad_cpp =================================================================== RCS file: patches/patch-test_engine_System_testClampRad_cpp diff -N patches/patch-test_engine_System_testClampRad_cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-test_engine_System_testClampRad_cpp 2 Sep 2026 20:52:26 -0000 @@ -0,0 +1,41 @@ +- tests: fix undefined float-to-short conversion in testClampRad + c1dea15fa0f1c1beb593133fc4061f9c684f6a15 + +Index: test/engine/System/testClampRad.cpp +--- test/engine/System/testClampRad.cpp.orig ++++ test/engine/System/testClampRad.cpp +@@ -8,6 +8,19 @@ + + #include + ++// COB scripts encode angles as TA units where a full turn is COBSCALE (65536), ++// so any angle past a half turn exceeds the range of a signed short and is meant ++// to wrap around (it is a circular 16-bit angle). Truncating the scaled value to ++// int first is well defined for the bounded angles the sim feeds in, and the ++// following int->short narrowing performs that modular wrap deterministically. ++// Converting straight from float to short would be undefined behaviour once the ++// value leaves short's range, and produced different results on arm64 vs x86, ++// desyncing multiplayer. ++static inline short RadAngleToCobShort(float radAngle) ++{ ++ return static_cast(static_cast(radAngle * RAD2TAANG)); ++} ++ + InitSpringTime ist; + + TEST_CASE("ClampRad") +@@ -43,10 +56,10 @@ TEST_CASE("ClampRad") + CHECK_FALSE(std::signbit(ClampRad(0.0f))); + + // Test TAANG2RAD conversion to short for [0, 2pi) +- CHECK(static_cast(ClampRad(0.0f) * RAD2TAANG) == short(0)); +- CHECK(static_cast(ClampRad(+std::nextafterf(math::TWOPI, -std::numeric_limits::infinity())) * RAD2TAANG) == short(-1)); +- CHECK(static_cast(ClampRad(+std::nextafterf( 0.0f, +std::numeric_limits::infinity())) * RAD2TAANG) == short( 0)); +- CHECK(static_cast(ClampRad(+std::nextafterf(TAANG2RAD , +std::numeric_limits::infinity())) * RAD2TAANG) == short(+1)); ++ CHECK(RadAngleToCobShort(ClampRad(0.0f)) == short(0)); ++ CHECK(RadAngleToCobShort(ClampRad(+std::nextafterf(math::TWOPI, -std::numeric_limits::infinity()))) == short(-1)); ++ CHECK(RadAngleToCobShort(ClampRad(+std::nextafterf( 0.0f, +std::numeric_limits::infinity()))) == short( 0)); ++ CHECK(RadAngleToCobShort(ClampRad(+std::nextafterf(TAANG2RAD , +std::numeric_limits::infinity()))) == short(+1)); + } + + TEST_CASE("ClampRadPi")