59 Commits
Author SHA1 Message Date
MrBruh 86a1173f14 Merge pull request #366 from BirchWoodGod/fix/unicode-pipe-terminator
Keep a unicode string that ends in '|' from being read past its end
2026-10-20 00:07:30 +13:00
MrBruh 0110c16001 Merge bnunu/halo-1 main into testing, keeping OpenCE's code where both changed it and leaving out its matching tooling and logs 2026-10-18 22:31:23 +13:00
MrBruh 90dd65cab4 Add a streamer mode that hides slurs, swearing and insults in text from other players, maps and mods 2026-10-18 15:16:12 +13:00
MrBruh 4ac609f0df Revert "Add an in-game text chat for network games" 2026-10-18 15:03:39 +13:00
Jonas VolmanandClaude Opus 5.5 f9676b2962 Replace bad words in players' names wherever streamer mode draws them
Streamer mode replaced the words of its list only in the chat's lines and
names, but a player named with a slur showed it on the scoreboard, above
their head, in the kills and in the lobby. Every text the game draws or
measures now goes through the filter at draw_string.c's start, both
draw_string and draw_unicode_string, so names are replaced wherever they
show and the text's width matches what is drawn. A text's format codes (a
| and the character after it) are kept, each run between them filtered on
its own, so a code never joins the words beside it ("|t" before "its").
The same strings are drawn every frame, so a cache of 48 keeps it cheap; a
text too long for its entries is drawn as it is rather than cut short.
The chat no longer filters its own lines (the draw does), so the line you
type shows replaced too. "hoe" now shows as "rake": "garden hoe" held the
word it replaced.

debug.network_test_name names a machine's player in an automated test
game, to test this.

Checked: tools/harness/tests/test_chat_filter.py (the format codes, the
cache, every replacement passed through the filter again unchanged, with
negative controls); a host on Xvfb, streamer mode on, named "fuckhead",
with a client named "n1gger": the chat showed "fudgehead" and the
scoreboard "nugget" and "fudgehead", while debug.txt kept the names as
they were; the CI Linux test step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 18:02:07 -07:00
BirchWoodGodandClaude Opus 5.5 2dea8f6c70 Keep a unicode string that ends in '|' from being read past its end.
parse_unicode_string took the character after every '|' and only then
looked for the 'n' of "|n", so a string ending in '|' skipped its
terminator and was drawn on through whatever followed it, until a zero.
Players' names, server messages and a map's string lists are drawn this
way, so any player can send one. Any other '|' also ate the character
after it, and kept the result of the character before (on a string's
first character, the parser's uninitialized one). The next character is
now taken only when it is 'n'; any other '|' is a character, as
parse_string has it. "|n" is unchanged.

Checked: new harness test unicode_line_breaks takes parse_unicode_string
from draw_string.c; its cases are bar-n-ends-a-line, bar-is-a-character and
bar-at-the-end. On the old code the last two fail, and each of its 2
negative controls (the next character taken whatever it is, the '|' left
with the last result) fails its case. tools/harness and test_touch_menu:
347 passed. ninja linux (debug and release) and ninja web build with no
new warnings; Android not built here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ucYZ9cvWn3nrnk7kK3S5X
2026-10-14 23:57:18 -05:00
Paul Hontz fb9f03cf2c Split HALO_ANDROID into the guest's ABI, the ES renderer and the app
HALO_ANDROID meant three things at once. The port's code now names each:
HALO_ARM64_GUEST for the ILP32 AArch64 guest's code paths (the inline
assembly's C, the bss pragmas, the CRT's), HALO_GLES for the OpenGL ES
renderer (its GL header and function list, shaders and capabilities), and
HALO_ANDROID for the app alone (its display, input, files and lifecycle).

The Android build defines all three, so nothing changes for it, nor for
Linux and Windows, which define none. A build for another platform can
then take one part without the others: the ES renderer, or the guest's
ABI, without the Android app.

port/android/README.md also no longer says that the widescreen changes are
in #ifdef HALO_ANDROID: none have been since 50eae19b.
2026-10-09 09:05:44 -04:00
Jonas Volman 14ec9fc4a2 Remove three no-op BSS pragma blocks without byte changes 2026-10-09 04:23:56 -07:00
Jonas Volman 73677cf26d Remove empty header stubs and unused shader-stage enums
Zero credit: remove 51 guard-only headers, 50 project-list entries, four useless includes and two unused enum definitions. Preserve source assertion locations and both repositories existing READMEs. Clean rebuild, unchanged 8252-row strict snapshot, unchanged code/data credit and admissions, 1663 tests plus 159 subtests pass. Disclose 76 compiler-local label renumberings and two warning source-line shifts; runtime sections and relocations remain identical. No private assets or scratch tooling published.
2026-10-09 02:58:59 -07:00
MrBruh 65cd4c29d8 usnprintf as MSVC's again, map formats' widths bounded (#197-#199)
usnprintf terminated every string it wrote, so an exact fit lost its last character on Windows (a score limit of 100 shown as 10); the strings the PRs bound are terminated where they are written, as the rest of the game's are. The title copies are ustrncpy again (title_string[79] is terminated after). A map's format takes flags, then at most three digits of width and three of precision, so %5-d, %1.2.3d and huge widths are not passed to Windows's printf.
2026-10-09 21:06:25 +13:00
MrBruh 5e08c09e78 Merge pull request #199 from ChupathingyCE/upstream-fix/map-format-arguments
Map strings used as formats only with the game's own arguments (with #197 and #198, which it stacks on)
2026-10-09 21:05:46 +13:00
MrBruh 9407db4bc3 Merge pull request #202 from ChupathingyCE/upstream-fix/string-list-size
String lists: a one-byte string is not terminated before its data
2026-10-09 18:46:28 +13:00
MrBruh a7c8eac379 Lucide speaker icons for voice chat
Voice chat's speaker and muted speaker are Lucide's volume-2 and volume-x (1.53.0, ISC: port/assets/icons/lucide, credited in AUTHORS.md, its licence shipped beside the game), drawn white into the menus' bitmap voice/speaker by tools/ce_menus.py and tinted, in place of the speaker made of rectangles. In the lobby, on the scoreboard and in the list of who talks, the icon is centred on the middle of the text's capitals (draw_unicode_string_capital_middle).
2026-10-09 17:11:42 +13:00
Milenko 40bb5ea4a6 Map strings used as formats only with the arguments the game gives
The multiplayer messages, scores and saved games' names are formatted
with map strings, and one whose conversions differ from the arguments
passed (a string where the game gives a number) made the game read an
argument as a type it is not. Each site now passes its arguments'
signature to ustring_format_checked: a format whose conversions are not a
prefix of it gives an empty message, logged once. The shipped strings
all pass.
2026-10-08 08:36:36 -04:00
Milenko 5ec67a8db4 String lists: a string of one byte is not terminated before its data
unicode_string_list_get_string terminates a string at its last
character, size / 2 - 1, so a string whose data is one byte long had its
terminator written two bytes before its data. Strings shorter than one
character are now not used.
2026-10-08 08:36:10 -04:00
Milenko c1694f607f HUD item messages: map text formatted only when it takes the count, and bounded
An item's pickup message is a map string that the HUD used as the format
of an unbounded usprintf into a 256-character buffer. It is now used as a
format only if its one conversion is the count the game passes
(ustring_format_takes), with usnprintf, and shown as plain text
otherwise. usnprintf now also terminates a string it cuts short, and
ustrncpy_terminated is a bounded copy that always terminates.
2026-10-08 08:35:30 -04:00
MrBruh 30cd63678a List Custom Edition maps in the menus 2026-10-07 19:02:06 +13:00
MrBruh 761210d405 Harden map and network input 2026-10-06 13:26:43 +13:00
MrBruh 0182da8172 Add high-res text and OpenCE titles 2026-10-02 13:39:17 +13:00
MrBruh 4adc3a87a5 Remove matching tooling and HALO_LINUX ifdefs 2026-09-30 21:49:46 +13:00
MrBruh a17d89c6f1 Merge bnunu/halo-1 main 2026-09-30 18:13:05 +13:00
Jonas Volman 6bfd956737 Reconcile approved Halo fidelity packets and bounded data credit
Recover transparent geometry submit (+1,285 meaningful code, zero exact losses); reconcile COMMON ownership and Q10 85+EXT1 credit, actions/main data, and separately disclosed denominator corrections. Preserve canonical-only repairs and all held research. C09 is ordinary disclosed cleanup, not a claim of proven scaffolding intent. Clean rebuild, 1,663 tests, parks, audits, provider links and independent EXT1 check pass. Local reconciliation only.
2026-09-29 13:52:37 -07:00
MrBruh 3c1d956703 Add NTSC multiplayer strings 2026-09-28 19:27:52 +13:00
Jonas Volman 709bfc3a3c Reconcile approved frontier ownership and admission packets
Import only independently reviewed production changes. Preserve canonical physics and virtual-keyboard repairs; keep B3 and all unresolved holds out.

Record exactly four approved canary debits (6987 meaningful bytes), six Halo admissions and two revocations. Keep vendor ioinit/storage work separate. Full build, 8252-row sweep, 1318 tests, park/admission/fake audits and 621-object binding pass within approved debit bounds.

Do not publish donor research dumps or private assets. README and unrelated user research remain untouched. See frontier_publication_reconciliation_20260927.md for complete evidence limits and accounting.
2026-09-27 17:12:48 -07:00
MrBruh e29125b50e Port decomp to Android 2026-09-26 16:16:00 +12:00
Jonas VolmanandClaude Opus 5.5 1cd5e4ede2 R2 batch 2: reviewed zero-credit ownership/storage packets; two '$'-defect data entries
All packets passed a precedent audit and an independent adversarial review.
No object changes status.
- Storage per cachebeta publics (source static + symbols.json rows):
  - bink_playback: four globals;
  - weapons: 11 rows + weapon_magazine_finish_reload;
  - object_lights: 4 helpers; should_render_lights is the /Od-attested call and
    its prototype leaves the public header;
  - vehicles: _update_turret_physics;
  - weather_particle_systems: one_over_char_max is external (cachebeta public,
    HCEX Global); its globals are static;
  - rasterizer_xbox_debug: 8 D3DINLINE wrapper rows (already Matching: audit
    FAIL(8) -> PASS, pdb 8 -> 0).
- draw_string: the invented external draw_string_globals aggregate (pads, blob,
  #define aliases) becomes four HCEX-attested file statics in /Od declaration
  order with = { 0 } (a595bbc2 precedent); typed multitexture params.
- render_debug: three rule-6 hand expansions become real point_from_line3d
  calls (ruling #1/#2); the opaque vehicle view gives way to struct
  vehicle_datum + vehicle_datum_try_and_get; the six debug_* toggles become
  tentative definitions (COMMON evidence).
- vehicles: the TU-wide REAL_MATH_EXTERNAL_POINT_FROM_LINE3D define is gone and
  the pathfinding hand expansion becomes the genuine call (ruling #1).
- rasterizer_xbox_profile V1R (reviewer-amended): byte-inert /Od parameter
  order, the BUG marker comment, detail_objects via the rasterizer_xbox.h API,
  and a rejection text that keeps the SDK-table policy question open.
- semantic_data_matches.json: single-section '$'-defect entries with
  allow_incomplete_unit for projectiles _projectile_update_section (1,548 B) and
  object_lights _lights_section (1,541 B) (leaf_map / editor_flying_camera /
  race precedents).

Gate (full ninja, objdiff 3.3.1): objects 384 (unchanged), code unchanged,
data +3,089; stable diff 0 regressions; parks 83/0/0; admission 10/0/2/0; fake
scan 26; pytest 1159 passed; diff --check clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 15:12:09 -07:00
Jonas VolmanandClaude Opus 5.5 dc58693c9f Match stack walk, main render and small systems functions
Lane D refresh packet 4: systems, +3,984 padded bytes strict exact
(11 functions), zero stable-verdict regressions; stack_walk_windows.obj is
now a whole-object code match (16/16).

- stack_walk_windows.c: _walk_up, _is_valid_ebp, _walk_stack,
  _walk_stack_context and _stack_walk_with_context exact. The debug build
  attests `if (ignore_levels) while (--ignore_levels) walk_up();`, the
  global re-reads and the four instruction-byte locals.
- main.c: _compute_subframe_counts (debug-build byte local and ?: column
  test) and _main_game_render (PIN, goto-free player-window assignment).
- bink_playback.c: _bink_draw_frame (the ((index+1)&2) corner idiom used by
  interface.c and hud_draw.c; debug locals scoped to the debug block).
- draw_string.c: _parse_string; styled_font_get takes (font_index, style)
  per the debug build's parameter homes.
- prime_numbers.c: _primegen as a plain sieve.
- transport_endpoint_set_winsock.c: _add_endpoint_to_set single exit.
  fake_match_scan flags its listening-bit test as identical branches; the
  debug build has two separate FD_SET expansions under the same test and
  January's bytes carry the test, so the shape is original (commented).
  _poll_endpoint_set moves to the target's 560-byte size (fuzzy 72.3% ->
  98.5%); its park is re-measured in place.
- parked.json: unpark the six newly exact parked functions; refresh
  _poll_endpoint_set.

Gate: ninja PASS, parks 134 active / 0 stale / 0 invalid, admission 0
contradicted / 0 revoked, castcheck clean; fake scan adds only the
adjudicated identical-branches lead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 01:09:42 -07:00
Jonas VolmanandClaude Opus 5 3083f800b5 Reopen four parks: detail objects, character draw, hud sound and bink cache
Wave n1 of the next-150K lane (fresh structural portfolio at ae10935da).

- structures _structure_render_detail_objects (+1136): reopened with the natural
  array initializer, which the w2 verifier asked for when it rejected the
  hand-written a[0]=0/memset expansion (R6).
- draw_string _bitmap_draw_character (+944).
- hud_sounds _hud_play_sound (+352): closed by removing the one-use index alias
  and reading sound_indices directly (A5), NOT by the volatile/goto body that the
  park record shows was deliberately replaced.
- bink_playback _bink_free_texture_cache (+96): the park premise was the repo's
  own match_dassert wrapper; the user-supplied Bungie random_math.c spells the
  same two sites vassert, and the tree is 874 match_vassert to 14 match_dassert.
- structures _structure_get_planar_fog: zero-credit remeasure. Adding the
  discarded fog-plane lookup January provably executes (its 15th
  _tag_block_get_element_with_size relocation at +0x16d) closes both structural
  tags; 448/448 and 15/15, residual now one register-naming window.

Rejected by the verifiers and not landed: _bink_alloc@4 (exact only with an __asm
block in a pool allocator - house rule 10 allows asm only for evidenced
helper/math routines), the progress_bar _code_000d16d0 rename (standing hold),
and the _portal_hull_from_points remeasure. wind _wind_variance_get is HELD for an
owner ruling (see its ledger).

Full ninja, parks 274 active / 0 stale / 0 invalid, stable diff vs
scratch/opus5-next150-before.json: gained 4 / 2,528 padded, regressions 0; fake
scan 0 leads.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 21:43:58 -07:00
Jonas VolmanandClaude Opus 5 e34edcd087 draw_string: reopen styled_font_get, pick_draw_character and the draw_string/unicode string family exact
parse_string park re-measured as the coupled January stack-ABI prerequisite (evidence appended); bitmap_draw_string stays parked (its exact form reproduces a NULL dereference). 6 park(s) removed. Adversarially verified (wave D park re-investigation); full build of the combined wave D set: 0 regressions, parks 402/0/0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 23:09:11 -07:00
Jonas Volman 73e6f3d7b8 Close draw-string tab-stop setter 2026-09-03 23:50:39 -07:00
Jonas Volman e2f51904df Preserve draw string header schedule 2026-09-02 23:24:14 -07:00
Jonas Volman 1bab4c6a5a Reconstruct draw string object 2026-09-02 23:19:53 -07:00
Jonas Volman 734dd02e1f Match draw string picking 2026-08-28 15:17:13 -07:00
Jonas Volman d9a77e3edc Match Unicode object 2026-07-16 22:50:14 -07:00
Jonas Volman b6ef40d1b4 Match Unicode string families and ASCII conversion 2026-07-16 22:29:10 -07:00
Jonas Volman dcc30d3d8d Match Unicode memory stream and file wrappers 2026-07-16 22:12:34 -07:00
Jonas Volman b6762f95e8 Match Unicode bounded and formatted wrappers 2026-07-16 22:07:19 -07:00
Jonas Volman 7ab1c55a76 Match Unicode string and conversion wrappers 2026-07-16 21:57:06 -07:00
Jonas Volman fe060e3e95 Match Unicode memory file and time wrappers 2026-07-16 21:52:22 -07:00
Jonas Volman 8376090b02 Match draw string configuration leaves 2026-07-16 21:47:22 -07:00
Jonas Volman 477840b0ca Match Unicode character wrappers 2026-07-16 21:17:41 -07:00
Jonas Volman 3377c1dc3f Match draw string map lifecycle 2026-07-15 10:24:55 -07:00
Jonas Volman 9a8a47dcf6 Match draw string lifecycle 2026-07-15 08:39:21 -07:00
Jonas Volman 3cd314ca3b Align typed accessors with HCEX conventions 2026-07-14 19:03:06 -07:00
Jonas Volman 76485bad44 Match unicode_string_list_get_string 2026-07-14 15:47:14 -07:00
Jonas Volman 01eabff4b6 Match string_list_get_string 2026-07-14 15:47:14 -07:00
Jonas Volman e1867aadc5 Match previous character traversal 2026-07-14 14:59:33 -07:00
Jonas Volman c3a4c38ebe Match character alignment bounds 2026-07-14 14:59:33 -07:00
Jonas Volman 7c5171d978 Match double-byte character parsing 2026-07-14 14:59:33 -07:00
Jonas Volman 49b169fa57 Match font_get_character_by_ascii_code 2026-07-14 14:19:37 -07:00