Skip to content

Port: keep blended colours within [0, 1] - #1

Closed
bnunu wants to merge 1 commit into
OpenCommunityEdition:mainfrom
bnunu:halo-ce-universal/fix-colour-asserts
Closed

bnunu wants to merge 1 commit into
OpenCommunityEdition:mainfrom
bnunu:halo-ce-universal/fix-colour-asserts

Conversation

@bnunu

@bnunu bnunu commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Starting a system link game on Blood Gulch in the Windows build (a default build, with assertions) stops on colour range asserts:

  • bitmap_utilities.c (0x95D): rgb_colors_interpolate's result, a structure decal's random tint;
  • rasterizer_xbox_transparent_geometry.c (lines 1256-1258): a transparent shader stage's animated constant colour.

Both blend two valid colours by a factor in [0, 1]. The native builds' x87 code (-mfpmath=387, since c1fa519) can carry such values, and periodic_function_evaluate's 255*(1.0f/255.0f), at more than single precision, a hair past 1.0. Under #ifdef HALO_LINUX the blends are now pinned to [0, 1] before the asserts, and periodic functions return values in [0, 1].

The same asserts also stopped campaign maps with otherwise unmodified sources. That was seen at c1fa519; the files and compiler flags involved haven't changed since. Release builds (--release) skip assertions, so they don't stop, but they draw with the same out-of-range values.

port/linux/README.md lists the three files with the other HALO_LINUX-only edits.

Byte matching

Everything is under #ifdef HALO_LINUX. All 621 MSVC objects compare identical to main's, section by section: code, data, relocations and symbols.

Testing

  • Windows build: a system link game on Blood Gulch starts and plays past the point where it stopped before.

🤖 Generated with Claude Code

Starting a system link game on Blood Gulch in the Windows build stopped
on two colour range asserts: rgb_colors_interpolate's result (a
structure decal's random tint) and a transparent shader stage's
animated constant colour. Both blend two valid colours by a factor in
[0, 1], and the native builds' x87 code can carry such values (and
periodic_function_evaluate's 255*(1.0f/255.0f)) at more than single
precision, a hair past 1. Under HALO_LINUX the blends are pinned to
[0, 1] before the asserts, and periodic functions return values in
[0, 1]. Not related to the session limits; the byte-matching build is
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bnunu

bnunu commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator Author

Closing: this worked around colour values that the x87 maths pushed a hair past 1.0. 13d1ae2 (Re-enable SIMD on Windows) put Windows back on SSE single-precision maths, and on the current main a 128-machine Blood Gulch game (host, a real client and 126 stand-ins) runs without these asserts firing. The system link work continues in #2, which no longer includes this commit.

@bnunu bnunu closed this Sep 26, 2026
damiantw referenced this pull request in damiantw/halo-ce-web-multiplayer Sep 30, 2026
Add a headless dedicated server mode (Linux)
innerhat-dev referenced this pull request in innerhat-dev/OpenCE Oct 4, 2026
Add native Apple ports and Mac invite multiplayer
xshxdex98 referenced this pull request in xshxdex98/DamnationCE Oct 5, 2026
The co-op player's unit was given its owner only after it was made, so a
player's Elite chose its first animation slots from the Elite's own graph
and then used them against the Spartan's, which it switches to once owned:
a slot past the Spartan's graph halted a debug build as the player
respawned (tag_groups.c, "#2 is not a valid index in [#0,#1)"). The unit
is now made already owned.
Spartan0285 pushed a commit to Spartan0285/PowerSpark that referenced this pull request Oct 19, 2026
…net.c does

The game learns whose connection it accepted from getpeername on the new
socket, not from accept. The Mac's getpeername returned the tunnel proxy's
127.0.0.1, so a joining machine of a co-op game over internet play was
recorded at the host's own address ("machine OpenCommunityEdition#1 at 127.0.0.1") and its
players never received the game. The Mac now gives internet play the address
to translate, as peer_incoming_address does for xnet.c's getpeername.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Spartan0285 pushed a commit to Spartan0285/PowerSpark that referenced this pull request Oct 19, 2026
…s byte order, not by an inline swap

get_endpoint_address swapped the socket's address and port to the host's number
with the original's inline shifts, and distributed_real_address swapped a
stand-in's address to p2p.c's network order and back: right only on a
little-endian host. On the PowerPC a G4 host filed its client machine under
88.51.94.100 for 100.94.51.88 (the log's 'machine OpenCommunityEdition#1 at 88.51.94.100'), sent it
no datagram and took none of its datagrams for a machine's: the Intel client
saw 'player: dead' for the whole run and was timed out after 15 seconds,
though it had joined and loaded. They now use halo_be32 and halo_be16, as the
rest of the transport does.

The harness test runs the statements as a little-endian and as a big-endian
host does; the old inline swap fails the big-endian run. No change on the wire
or on any little-endian build: network version stays 30.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant