OpenCE took OpenCE#486: a client tells the host where its players'
shots leave from when that is not the camera (distributed message 93),
and the host's line of sight check also looks from there, within the
shape a hand firing at the target can have (network.fire_origins).
network_vr.c now registers the VR weapon hand as that source, so VR
players keep their hits around corners on every OpenCE host of this
version, and our own host-side use of the VR poses for the line of sight
is dropped for the PR's.
Conflicts: d3d8_gl.c's shaders are made by our shader_make (the Android
program cache) and their hashes recorded for upstream's desktop program
cache, whose linking moves into program_make's desktop branch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Backing out loads the screen focused on its first row, then focuses the
row you left from. Giving the focus clears focused_child along the old
path, so the first row's spinner is unlinked. When the d-pad or keys come
back to that row, left and right reach nothing, and only the mouse could
change it (Video Setup: open Graphics, back out, go up to V-Sync).
A row that only passes events on now gets its first child that takes
events back whenever it takes the focus, as it had when its screen was
loaded. The idea is from mastercheese-dev/CoreCE's
widget_instance_refocus_passthrough.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Split out, to come back as their own pull requests:
- The pose another player's aim turns through with Smooth Motion off, and
the correction glide drawn on the tick's frame for it
(render_interpolation.c, network_distributed.c, NETCODE.md). A remote
passenger lagged behind the vehicle it rode, and a player who stood
still and then turned glided across the whole time they stood.
- The particle crossfade (particles.c, render_particles.c). It doubled
the sprites of every animated particle, not only a muzzle flash.
Fixed:
- Light volumes: the viewmodel's marker and the two passes come
together from one helper, light_volume_marker, used by both the draw
and the submit. Campaign keeps the object's marker and one pass, as
before; it had the two passes without the viewmodel's marker. The
stencil mode is put back as it was, not to 0; the modes are named; the
flashlight is found with csstrcmp; the prototypes sit with the others.
- The flashlight: first_person_weapon_center_flashlight says whether the
viewmodel placed it, in place of comparing six floats. The stray
#include <math.h> is gone, and the change is marked port:.
- Nav markers: the 40 ms easing matched markers by distance, so two
within 8 units could swap, and never freed its slots. A marker on an
object is now moved as far as the frame draws the object from its tick
position (render_interpolation_object_point), with no state and no
lag. A game engine goal (no object) stays on the tick.
- render_particles.c's viewmodel particle is marked port:.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The picture's function values are kept in the rasterizer's memory for
the frame where they are made (render_objects.c, first_person_weapons.c),
not on the stack and copied later: rasterizer_model_copy_animation is
gone. A modifier's group, a queued transparent part and a child that
copies the modifier read the values after the block that made them, and
the overshield finds its own values by their address
(overshield_effect.c), which the copy broke (the overshield lost its
rise, fade and color on the body and the arms). The values outliving
their stack frame were what halted a match on a meter; with them kept
there is no stale read, so decals.c's clamp is gone and the original
assert is back.
- The values are at the picture's moment, between the previous tick and
this one (render_interpolation_fraction), not a tick ahead of it, and are
the tick's own with Smooth Motion off.
- The first-person charge's visuals are out of this pull request, for one
of their own with a setting: the lens flares (and their depth state),
the glow and widget on the viewmodel, the widget flag and the near plane
(view_fov.c).
- object_function_addition, the original loop's body as one function, is
marked port:.
Checked: objects.c, render_objects.c, first_person_weapons.c and render.c
compile for the web and Android (also with -Wimplicit-function-declaration,
-Wint-conversion, -Wincompatible-pointer-types and -Wuninitialized on:
none in the changed code); merged with main, CI's test suite passes (1488).
Not run: net_compare.py (objects_update's functions are computed by the
split-out helper, the same steps in the same order).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dedicated servers (halo --server, web admin, RCON, master server
listings, the server browser's DEDICATED tab; network version 39), each
client telling the host its build (distributed message 92), the
dedicated servers' chat filter, Gun Game's plasma weapons.
Conflicts: our join state enum for the VR menus is renamed
P2P_JOIN_STATE_* beside upstream's join progress (P2P_JOIN_*), and both
are kept in p2p.c; the entry sizes of message 92 and our 240 both;
config_write_file keeps our rename over the file and takes upstream's
dedicated server branch; hud_hires.c takes upstream's null renderer
check; build.yml and README.md stay ours. The new server-image workflow's
jobs are off (Mjolnir VR ships no server image).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New gametypes (SWAT, Infection, Gun Game, Hardcore), shield effects the
host's choice in network games, co-op ally friendly fire, network fixes
(scenery shields, tripmines, co-op teleports), Custom Edition HUD and
texture fixes, ASTC for Android GPUs without S3TC.
Left out on purpose: upstream's two Android workarounds for Mali phones,
the GL shadow state refreshed before every draw (prepare_draw) and the
geometry cache bypassed (mirror_range). Both would cost every draw of
both eyes on the Quest, which never showed the corruption they work
around; their tests are skipped. Conflicts: the GL capabilities log
keeps multiview and adds ASTC; xbox_textures.c keeps vr.c's texture work
counters; README.md stays the player's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Match stock CE resource sheets by pixel identity and translate stock meter
redraws to CE layouts. Preserve custom artwork, correct mixed-use meter
channels and warning placement, and draw aligned controller glyphs with
High-Res HUD enabled or disabled. Scope Bigass Open v1.1 ammo changes to
its known map name and checksum.
Based on OpenCE testing 4cb621cd. Keep upstream Android texture ownership,
eviction and validation unchanged; use its residency helper in the new
stock CE upscale lookup. No unrelated main-branch commits, networking
changes, regression test files or investigation documents are included.
Validation: Windows portable release build passed; 175 local CE HUD and
Android regression checks passed, 4 asset-dependent checks skipped.
Additional residency checks cover Android-managed pixels, desktop cache
entries, identity rejection and map reset. git diff --check passed.
Android/Web targets are unavailable in this Windows build graph; no new
runtime gameplay validation was performed for this rebase.
Player-Note: Fix Custom Edition HUDs, ammo counters and prompts while preserving custom artwork.
Ringfall's side of it:
- The bots: OpenCE's own (bots.c, a local split screen game's) are not
used in VR builds (their lobby hook would take Ringfall's host bots
off, and their bots.count and bots.skill differ); Ringfall's are now
host_bots.c, so that OpenCE's bots.c merges as it changes. Each
platform's bots.count and bots.skill are its own (config_setting_index
takes this platform's of two of a name).
- HDR is never on in VR (d3d8_gl.c); the flat window's present is
OpenCE's, inside the VR port's branch for it.
- The VR frame begins where the events are pumped (sdl_platform.c), as
before, now that exit_after_check is apart.
- The message numbers: OpenCE's aim assist policy (90) before the VR
port's poses (240), which stay last.
- The visibility counters keep the VR port's snapshot ring (both eyes'
counts halved); OpenCE's tone mapping goes before the antialiasing, off
the VR eyes' pass.
- Join codes, the online list and OpenCE's probes all in the signalling
topics; the HUD's PNG helpers both ways; the disc import keeps the
language file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
progress_bar_download_display, progress_bar_download_end and
progress_bar_downloading were for a download screen that is not merged; they
are removed and progress_bar_eachframe is as it was. Without loading.tga the
texture is no longer filled with clouds the port made: it is left as
created, black, as the game leaves it, so that no invented picture ships.
The disc image importers' comments say so.
Checked: node --test "port/web/tests/*.test.js", pytest tools/harness and
tools/test_web_build.py; the changed C files compile (-fsyntax-only) with
the Linux, Android guest and web commands; XisoExtractor.java with javac.
The loading screen (interface/progress_bar.c: a light sweeping from left to
right over a picture, with a glowing trail) drew nothing: it uses the
fixed-function pipeline (SetVertexShader with 0), which d3d8_gl.c did not
have, and its picture, loading.tga, is on no retail disc.
- d3d8_gl.c draws fixed-function immediate-mode draws with a vertex shader
of its own (nv2a_fixed_function_glsl), positions transformed by the
world, view and projection matrices; and keeps a front buffer (a 640x480
render target taking the middle of the frame at BlockUntilVerticalBlank)
for GetBackBuffer with -1, the frame before, whose blur makes the light's
trail. The screen is drawn in the middle 640 columns, as the menus are on
a wide screen.
- After it, the rasterizer's caches of the device's states and of its
vertex shader are made the device's again (rasterizer_forget_hardware_state,
rasterizer_vertex_shader_runtime_forget): it sets them itself; and
SelectVertexShader (a packed program) always leaves the fixed-function
pipeline.
- On OpenGL ES (Android, the web) the fixed-function shader turns
Direct3D's clip space as the others do (HALO_GLES); without OpenGL
(debug.null_renderer) it is not compiled.
- The picture is the Xbox's own: the retail default.xbe holds it (320 by
240, runs of 4-bit greys after its width and height), and importing a disc
image now writes it into the maps folder as loading.tga: port/linux/src/
xiso.c, the Android app's XisoExtractor.java and the web page's
xiso-worker.js. Without one (a maps folder copied by hand) the light
sweeps over clouds the game makes. No game data is in the repository.
- progress_bar.c also has a mode a download screen over the menus can use
(a share given, from 0, drawn over the menus, and let go of).
- A picture that cannot be written whole is not left cut short (the
loading screen would read past it).
Checked: port/web/tests/xiso.test.js takes the picture out of made-up
executables (and an image's default.xbe); the Java decoder gives the same
bytes as the JavaScript one; xiso.c's picture from a Rev 2 disc image
matched a separate decoder's byte for byte; the Linux CI steps and the
web build and its tests in Docker; the Windows release build.
[The disc image parts (xiso.c, xiso-worker.js, XisoExtractor.java and
xiso.test.js) redone on the rewritten disc-image readers.]
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 010110026e719c3e8c38d36b93d57cf67b616230)
OpenCE moved from CC0 1.0 to AGPL-3.0-or-later (4b09168e7), and Ringfall:
Mjolnir VR moves with it: README's Legal section and THIRD_PARTY_NOTICES
say so (releases before this one stay CC0 1.0, LICENSES/CC0-1.0.txt).
Its disc image readers were written again from a description of the
format, extract-xiso's code and notice gone. The app's (XisoExtractor.java)
is OpenCE's new one with Ringfall's language folders (maps_es, maps_it)
added again; the Steam Frame's (steam_frame_xiso.py) is written anew the
same way, the language folders kept; the bundle and the release job no
longer carry extract-xiso's licence. Also in: bnunu/halo-1's latest
matches, the web build's WebRTC and loading fixes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Several of the fixes taken from the forks changed source/ without the
port: comment that marks a change from the original (the second copy's
datagram ports, the downloaded maps' refusals, the main menu's clock,
the one-magazine HUD states, the render lists' sizes and others), and a
comment still named a function of that fork's. Each change now says so.
A tick waits for an input update with an action for each player, and the
menus change who the local players are (signing profiles in and out, a
lobby's network game owning the queues). In a lobby, or once a client's
clock waited for a game, the main menu's scene stopped ticking; and a
screen flagged to pause game time (Mods, the map and gametype screens of
setting up a game) paused the clock that runs the scene, which then
started again from its beginning as the screen closed.
The main menu's scene now always ticks on this machine's clock
(game_time_menu_scene), its players idle where the queues have no input
for them, and at the main menu those screens no longer pause it. The
distributed netcode's per-tick work is not done for the scene: a lobby's
machines do not share it.
(cherry picked from commits 8444785804f8cfb413020da5a03fc5dd65f918e9, 6267d199117f87e56a3f41fc8932966a39a3feb2
and 3a4097bb48f34245b750028a5c0ae28e03bae037, made again on OpenCE's game_time_update,
which has no separate clock connection for the scene)
The high-res HUD draws a message's controller button by its place among
the HUD globals' button icons, but only once the map's message icons
bitmap had a picture at the button's sequence. Halo PC's message icons
have 13 sequences to the Xbox's 24, so on a Custom Edition map a prompt's
button past them was not drawn at all, and the rest only because the map
had some other picture there ("Hold [rocket launcher] to swap" on
coldsnap, with the high-res HUD off). The high-res button is now tried
first. With display.high_res_hud off, a Custom Edition map still draws
its own pictures.
Found in commit 4c3e74cf29341ff344aca09febc0fab7e1d19919, which instead
reads the Xbox's button pictures out of ui.map for every Custom Edition
map; that is not taken.
The Join Game server browser shows each ping coloured: green under 80 ms,
yellow under 160, red above. A text colour hook of the menus'
(pc_menu_text_color) gives the ping its colour; the rest keep their own.
(cherry picked from commit 335c6522e9fb7aa33762e3f2cf27c518ac0e48ce, without that fork's
Online Games screen, the thresholds and colours kept in menu_functions.c)
In Join Game's server browser a click selects a game, its row in the
yellow-outlined picture Custom Edition draws for it, and a click on the
selected game, a double click, A, Enter or JOIN joins it; one click
joined it before. The keys move the selection.
(cherry picked from commit 472d232246568ed2e3ee56bc93d97a3530feea54, without that fork's
Online Games screen; OpenCE's rows already take the focus only from a
click, not from the pointer passing over them)
The debug build this port comes from unlocked every campaign level on
every difficulty for each new profile. Retail Xbox Halo does not: a new
profile starts at The Pillar of Autumn and each level opens when the one
before it is finished. New profiles now start that way.
- game.unlock_all_levels (off by default) keeps the old behavior for new
profiles, for those who want it.
- profile_reset_campaign in the console clears the current profile's
finished levels and last played level, after a confirmation
("profile_reset_campaign yes"). Profiles made by earlier versions had
every level open and cannot be told apart from a real full clear, so
nothing is changed automatically.
(cherry picked from commit 224d9a757575509efb0dedab094bd0d34df59e96, without its top README
table, which OpenCE does not have)
A one-magazine weapon's second magazine, read as empty, still set off the
secondary states: the secondary trigger ready, flash, reload and "no ammo
for reload" crosshair states, and the draw states of its total and loaded
ammunition (flashing, disabled), which coldsnap's and hugeass's master HUD
draws as NO FUEL beside the weapon's own NO AMMO. These now apply only to a
weapon with a second magazine.
(cherry picked from commit 488bd83eafaabf26a7e392eaf8b240b1319e07c3; OpenCE already cleared
the state first, kept the overlays off and checked two of the crosshair
states, so only the rest is taken, and no CHANGELOG.md)
"event handler function failed" said nothing of which: the gametype
editor logged it fifteen times. It names the function's number and the
widget's tag, taken before the function runs (it may delete the widget).
(cherry picked from commit 5f4494f42b1919dc1e38c6f8e168b646768e74f1)
A screen's button bar (SELECT and BACK under a list) steps sideways, so
once the wheel scrolled past a list's last row onto the bar it went back
and forth between the two buttons until a row was chosen again with the
mouse. A touch drag already left the bar with up and down, as the d-pad
does; the wheel now does the same.
(cherry picked from commit 2ddad079fa5435a70a383d757de16b960c421505)
On a network client the overshield's drain arrives with the host's updates
after the HUD has taken its last shield value for the tick, so every frame
the shield looked a step lower than the HUD remembered and the shield
damage sound played for the whole overshield. The Xbox plays nothing.
The meter's flash already told the drain from a hit (a step of 0.05 or
less from past full); the sound now uses the same test, so a drain is
silent on host and client while a real hit on an overshield still flashes
and sounds.
(cherry picked from commit fd9c918313076ecc686209a0f4c75a6ef23340c4)
OpenCE's leak fix releases the surfaces the capture took; the device's
depth buffer may be none (D3DDevice_GetDepthStencilSurface's NOTFOUND),
and D3DResource_Release reads the resource it is given.
(cherry picked from commit ff654a774061c74d30f31ce986d7ebdefcafad74)
The virtual keyboard kept its keyboard tag from the main menu's map after
that map was unloaded, so Change Name in Settings from a game's pause
menu opened it on a stale tag and the game stopped. The keyboard is now
let go with the old map's interface, as its tags are; at the main menu it
is set up again, and in a game Change Name does nothing.
(cherry picked from commit 4c05c5b3237330669f55c2bdb123b7cde4e4e056)
The Xbox's postgame map select wrappers already carry
main_menu_if_no_history, with which the stock event code calls
main_goto_main_menu() when Back closes the last screen. The PC menus'
connected_map_select_wrapper, which menu_tags.c opens in their place,
was given the same flag by tools/port_settings.py in 4301ca88d, so the
hard-coded names and the network_game_abort() call in
widget_instance_go_back_to_previous were not needed, and they changed
stock split-screen behaviour (a split-screen game is a local server).
widget_instance_go_back_to_previous is as it was before 7d128e1bd.
Checked: the harness and touch menu tests (491 passed), test_web_build
(11 passed), ui_widget.c compiled for Linux and the Android guest.
A press pauses as before, now as it is let go; held 0.4 s, the scores
show as long as it is, as the Xbox's Back. In the menus it is Start at
once. The Quest's controls page says so.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The touch controls stay off in VR alongside the chat's on-screen
keyboard (xinput_sdl.c); the join codes and the online list beside the
server browser's listed hosts (p2p.c).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This reverts 4ac609f0, the revert of #395, so the chat is back as it was
merged: T, Y and Tab, team and vehicle lines, the host's /mute, the
VOICE AND TEXT CHAT settings page and the Android placement.
The one conflict is source/text/draw_string.c, where #395's streamer mode
and testing's (90dd65ca, text_filter.c) both hook the drawn text; testing's
hook is kept. #395's own filter (chat_filter.c, game.streamer_mode) is left
in place, unhooked, for the next commit to take out.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
testing's SOUND PROCESSING page and the chat's VOICE AND TEXT CHAT page
both split rows off Audio Setup in tools/port_settings.py. Both are kept,
as two category rows, sound processing first. The settings screens and
menus.json are regenerated from it, so they match testing's apart from the
chat's page, its row on Audio Setup and Controls Setup's COMMUNICATION
group.
Checked after the merge: the Linux debug build, the network format check,
the CI Linux test step (467 passed, 6 skipped), and the three-machine
system-link chat test, /mute and /unmute included.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Network games had voice chat but no way to type to the other players, as
the PC version's chat did. T (controls.chat) types a line to everyone and
Y (controls.team_chat) one to the team; Enter sends it, Escape cancels it.
The lines are drawn above the motion sensor with the HUD's font: the
player's name in their team's colour (blue without teams), then the text
in a pale blue, and fade after ten seconds (port/linux/game/network_chat.c).
A client sends its line to the host (_distributed_message_chat_up), which
takes it only from the client's own stream and one of that machine's
players, five at once and one each 1.5 seconds after, its text cut to 63
characters of printable ASCII, and sends it on to the machines that hear
it (_distributed_message_chat_down): all, or a team's line those with a
player of the team. Older builds drop both kinds as unknown, so the
network version stays 29, as for the vote kick; network_format.txt
records the two kinds.
While a line is typed the keyboard drives no player, as with the console
(xinput_sdl.c), nor voice chat's push to talk or the debug keys. Controls
Setup gets a COMMUNICATION group with PUSH TO TALK, CHAT and TEAM CHAT
(the controls screen's spinner strings changed by hand to what
port_settings.py writes: ce_menus.py needs the PC version's tags).
Checked: tools/harness/tests/test_chat_logic.py (the text's cleaning, the
host's rate, who hears a team's line, the fade, with negative controls);
the CI Linux test step; three machines on system link with
debug.network_test_chat (new), every machine showing the lines to all in
one order and a team's line only on its team's machines; and a host drawn
on Xvfb with lines typed on its keyboard through xdotool (sent on Enter,
not on Escape, the player still while typing).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>