Commit Graph
2706 Commits
Author SHA1 Message Date
MrBruh dfc6ac5f9f Merge pull request #207 from ChupathingyCE/upstream-fix/lastmpmp-buffer
lastmpmp.txt written from a buffer of the size written
2026-10-09 18:46:28 +13:00
MrBruh 3bb4866fbf Merge pull request #203 from ChupathingyCE/upstream-fix/widget-menu-functions
Widgets: a map's widgets don't run the main menu's profile or settings functions
2026-10-09 18:46:28 +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 71f7fd7664 Merge pull request #200 from ChupathingyCE/upstream-fix/tag-name-copies
Bounded copies and formats of tag names
2026-10-09 18:46:27 +13:00
MrBruh f5fc3d76ef Scoreboard speaker just right of the name 2026-10-09 18:00:38 +13:00
MrBruh e7e5777a88 Voice chat list in name tag colours
The in-game list of who talks colours each name as the names above players' heads are (hud_player_name_color, now shared): allies in the HUD's blue, enemies red, this machine's own players white; in co-op every other player is an ally.
2026-10-09 17:55:00 +13:00
MrBruh 348f8ad4f8 Speaker beside talking players' name tags
A player talking in voice chat has the speaker just left of their name above their head, centred on its capitals, at the name's scale and fade; only where the name itself is shown (display.player_names, and the gametype's motion tracker rules).
2026-10-09 17:44:55 +13:00
MrBruh b08a95b3ba Smaller voice chat list
The in-game list of who talks is drawn at 0.8 times the HUD's text, its speakers with it.
2026-10-09 17:36:47 +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
MrBruh f97b33391b Voice chat
Opus voice chat (port/third_party/opus 1.5.2, port/linux/src/voice_audio.c, port/linux/game/network_voice.c), relayed by the host, in the lobby too. The host decides in Server Setup > Teamplay Options: lobby voice (on by default), the game's mode (off, team near, anyone near, team, team and enemies near: the default), the near distance, and the quality, 8 to 64 kbps (24). Each player picks push to talk (V), open mic or off, the voices' volume, and the output and input devices in Settings > Audio, and mutes others from the scoreboard's menu. A speaker icon marks who talks in the lobby, on the scoreboard and in a list in game. The host takes a machine's frames only with the key it gave it over its stream, within the quality's size, 50 a second and 8 talkers at once, and sends voices only to machines that asked for them, so the network version stays.
2026-10-09 14:20:57 +13:00
MrBruh 3b20ef879a Votes to kick
Any player of a network game can start a vote to kick another, on any team, by picking their name on the scoreboard (right-click while it is open frees the mouse) or with the console's votekick; the host's own scoreboard also has Kick and Ban (Ban picked twice). The host alone counts (port/linux/game/network_votekick.c): votes only from each voter's stream, one per real address and again per hardware id (which only removes votes), time played on the host before starting (network.votekick_minutes) and voting, more than half of everyone with the target counted and at least two, one vote at a time with cooldowns for a failed vote's starter and target, and a passed vote keeps the player out for network.votekick_ban_minutes. Builds without it drop the new messages, so the network version stays.
2026-10-09 10:07:51 +13: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 ea79111994 Bounded copies and formats of tag names
The scenario's tag name was copied with strcpy into the game state
header's 256-byte map_name, a tag's name was formatted with sprintf into
the out of objects message's 512 bytes, and csprintf bounded its output
at MAXIMUM_STRING_SIZE even when it formats into temporary, which is 256
bytes and where most callers put tag names. All three are bounded by
their buffers' sizes now.
2026-10-08 08:35:50 -04:00
Milenko 6f0f2992cb Widgets: a game map's run none of the main menu's profile functions
A widget's event handlers name their function by its index in the table,
which nothing checked, so a game map's widget could run the main menu's
profile functions (deleting and saving player and playlist profiles, the
demos) and the port's own menu functions (writing config.toml, quitting,
connecting), on its created event too. The shipped maps' widgets run none
of these. Now only the port's own menu tags run the port's functions, and
only the main menu runs its profile functions; a refusal is logged once.
2026-10-08 08:33:20 -04:00
Milenko 22bb651e68 Write the last multiplayer map's name from a buffer of the size written
saved_game_file_remember_last_used_multiplayer_map wrote 256 bytes from
the caller's name, which the menus' map list keeps in 64, so whatever
followed it in memory went into lastmpmp.txt. The name is now copied into
a zeroed buffer of the written size first.
2026-10-08 08:31:13 -04:00
MrBruh 73dc01d09a Stereo sounds in the world fade as mono ones do
#191's inverse-distance gain replaces the linear fade for a positioned stereo sound rather than adding to it, so it is as loud as a mono sound at the same distance (both curves together left it some 7 dB quieter at 40 units and 15 at 60), and it is the fade the reverb send takes back out, so the reverb follows the 3D room rolloff as a mono sound's does. A 3D sound is not cut off at the tag's maximum distance either: none starts past it.
2026-10-08 23:35:08 +13:00
meowsandstuff 0e220b8831 Fix positional stereo audio distance attenuation 2026-10-08 21:19:46 +11:00
MrBruh 2d2348cd7d Reverberate and muffle stereo sounds in the world
A stereo channel's positioned sound is now given what a 3D channel's is: the same occlusion, obstruction and underwater listener (as the 3D call passes them) and its class's wet gain make its I3DL2 source, so the mixer muffles its direct path and sends it to the reverb as it does a 3D voice. The room send rolls off with distance as a 3D voice's does, the game's own fade of the stereo voice's volume taken back out of it. Unpositioned stereo stays unpanned and dry.
2026-10-08 22:21:13 +13:00
MrBruh a14401ac7d Pan stereo sounds towards where they are
A sound with a position plays on a 3D channel, but those are mono: a stereo one (a Custom Edition map's gunfire, a bullet's impact) fell back to a stereo channel, which the Xbox never panned, so it was only faded with distance and came from nowhere. update_channels now gives a stereo channel's sound in the world a pan towards it, as the mixer pans a 3D voice; the mixer pans the channels' middle and keeps their difference as wide as the far ear's gain. Unpositioned stereo plays as before, and no channel pools change.
2026-10-08 21:35:40 +13:00
MrBruh 71bf206bd0 Sound tags from files over a map's, and a 16 MB sound cache
Our version of #147. With audio.loose_sounds (off by default), each of a map's sounds that has a Halo PC sound tag file of its name in the data root's tags folder plays from it (port/linux/game/loose_sounds.c); loose_sounds_reload and loose_sounds at the console read them again or give the map's back. The files' samples are made the Xbox ADPCM this build plays through the Custom Edition converter, so no channel pools change and stock maps play as before. The override is written into the map's definition in place, keeping the counters the game updates; a change stops every sound and flushes the sound cache first, and old samples are freed once no cache block holds them. A split sound's length is its chain's.

The sound cache is HALO_PORT_SOUND_CACHE_SIZE: 16 MB on desktop, the Xbox's 4 MB on Android, with the debug view's buffer sized to match.
2026-10-08 20:22:16 +13:00
xshxdex98 57038d51c9 Weapon HUD: no secondary magazine drawn for a weapon without one
#180 gave a weapon without a second magazine the secondary's overlays at
rest (default and always) and states at rest (not disabled). The Xbox
never set those overlays, and an empty magazine's total ammunition state
is disabled, so the stock HUDs' secondary numbers and icons, which never
showed, drew over the campaign HUD's ammunition and grenade panels.

Such a weapon now leaves the secondary overlays unset, as the Xbox did,
and its states read the cleared, empty magazine. #180's fix stays: the
secondary's overlays no longer write over the primary's.
2026-10-07 22:27:32 -05:00
MrBruh 6d840473da sv_say: leave out '|'
The HUD's text takes '|' and the character after it as one escape (draw_string.c, parse_unicode_string), so a map's message ending in '|' had its drawing read past the terminator. sv_say leaves '|' out of what it shows.
2026-10-08 15:35:54 +13:00
MrBruh 11b937653c Merge pull request #182 from xshxdex98/upstream-script-sv-say-end-game 2026-10-08 15:34:13 +13:00
MrBruh 66541c670d Merge pull request #181 from xshxdex98/upstream-particle-missing-sequence 2026-10-08 15:34:12 +13:00
MrBruh 1588addbb1 Merge pull request #180 from xshxdex98/upstream-hud-secondary-magazine 2026-10-08 15:34:10 +13:00
MrBruh 3ef06395be Merge pull request #179 from xshxdex98/upstream-script-none-object 2026-10-08 15:34:08 +13:00
MrBruh 8fca9ef427 Mark the short camera track fallback as the port's
#152's fallback gets a port: comment and includes cseries/errors.h, as the rest of source/ does, and clamps t with PIN; a pitch not a number still samples the first point.
2026-10-08 15:04:27 +13:00
MrBruh 078901a907 Merge pull request #152 from innerhat-dev/following-camera-track 2026-10-08 15:02:13 +13:00
xshxdex98 3fc953136f Scripts: Halo PC's sv_say and sv_end_game for Custom Edition maps
Custom Edition maps' scripts call these Halo PC functions (lookout_classic
and the Halo Kart maps show players messages with sv_say), which did
nothing here. sv_say now shows the message in each player's HUD, and
sv_end_game ends the game on the host, as its time running out does.

They go at the end of the function table, so Xbox maps, which call
functions by their place in it, are unaffected; Custom Edition maps call
them by name (custom_edition_scripts.c).

sv_end_game adapted from ChupathingyCE (4e89e01f), by MrMilenko.
2026-10-07 20:55:11 -05:00
xshxdex98 1f7c5c9d5e Particles: a bitmap without the sequence drawn draws nothing
A particle state names its bitmap's sequence, which a Custom Edition map's
bitmap may not have, or may have with no sprites (Hornets Nest's). The
draw read past the bitmap's sequences, then took the sprite index modulo
a sprite count of zero. Such a particle is now skipped.

Found by ChupathingyCE (MrMilenko).
2026-10-07 20:52:23 -05:00
xshxdex98 f7301fcd06 Weapon HUD: the secondary magazine's overlays and warnings are its own
render_weapon_hud set the secondary magazine's overlay flags into slots 0
and 1, over the primary's, where its states and numbers use 4 and 5: a
weapon of one magazine showed its ammunition overlays as the empty second
magazine's (coldsnap's flamethrower read NO FUEL with a full tank).

A weapon of one magazine also read a second it doesn't have:
weapon_build_weapon_interface_state fills only the weapon's own, into
unset stack memory, so the HUD's secondary flash, reload and fired-empty
warnings followed whatever was there. The state is now cleared first, and
a weapon of one magazine keeps its secondary states and overlays at rest.
2026-10-07 20:51:44 -05:00
Milenko a601ad7119 Scripts: take none as an object name, as Halo PC's compiler does
coldsnap_20th_xl's scripts start an object_name global as none, which
this compiler refused ("none: this is not a valid object name."), so on
a Custom Edition map the scripts using it were dropped. none is now no
object: the object_name type's own default, which every lookup takes.

Adapted from ChupathingyCE (92342517), by MrMilenko.
2026-10-07 20:49:27 -05:00
MrBruh 65a6bb7edd Grow the powerups' render spheres in a port file
The powerup bounds of #117 move from source/models/models.c to port/linux/game/powerup_render_bounds.c, called from scenario_tags_load beside the other tags-loaded hooks, so the game's models.c no longer takes <xtl.h> and D3D buffer locks. It uses square_root and a relative margin in place of sqrtf and nextafterf, which strict gnu89 does not declare, and the objects.h scale change is marked as the port's. tools/test_powerup_bounds.py is dropped: it redeclares the engine's types by hand and CI does not run it.

On bloodgulch the active camouflage's render radius grows from 0.1 to 0.23 and the overshield's from 0.1 to 0.21; no other equipment changes.
2026-10-08 14:15:15 +13:00
MrBruh ec23cfcf24 Merge pull request #117 from eltanschauung/fix/powerup-render-bounds 2026-10-08 14:08:53 +13:00
MrBruh f59c4c15d1 Merge pull request #120 from ChupathingyCE/pr/script-object-lists 2026-10-08 14:04:04 +13:00
MrBruh bad6534e0c Forget the object bounds cache in the game state load procs
The cache is forgotten before every game state load (beside cluster_partitions_port_forget) and at each new map, after the declarations, rather than at the top of four functions.
2026-10-08 13:46:02 +13:00
MrBruh 7e7095b046 Merge pull request #169 from addisonbair/asset-free-tests 2026-10-08 13:42:01 +13:00
MrBruh ffa4a8ad04 Merge pull request #173 from TwistedFlog/custom-edition-maps
Custom Edition Discrepancy Fixes
2026-10-08 13:18:11 +13:00
Milenko 8d4fe32c0c Merge remote-tracking branch 'upstream/main' into HEAD
# Conflicts:
#	port/linux/include/halo_port_capacity.h
2026-10-07 20:15:42 -04:00
MrBruh 9e9a1bbf89 Merge pull request #148 from meowsandstuff/error-screen-build-info
Identify native builds and show recent errors on halt screen
2026-10-08 12:46:36 +13:00
MrBruh 760bc907af Merge pull request #151 from innerhat-dev/point-physics-radius
Treat a point physics radius below zero as zero
2026-10-08 12:46:34 +13:00
TwistedFlog 6b1d81c7b1 Custom Edition Map Discrepancy Fixes
Fixed: Weapons whose trigger had flag "analog rate of fire" now read how far the trigger is pulled: fully for mouse/keyboard, the actual pressure for a controller trigger. Before they never fired.
source/input/input_abstraction.c
source/input/input_abstraction.h
source/game/player_control.c

Fixed: Weapon spawn orientation on Custom Edition maps. Multiplayer weapons and items now spawn facing the way the map places them, as in Halo PC.
source/game/game_engine.c

Added: PC vehicle set. There's a new PC option in the vehicle set list, between Gun Turrets and Custom. A team set to PC gets every vehicle the map places, as in Halo PC. On Custom Edition maps that means every placement whose spawn flags name the gametype.
port/assets/menus/ce/strings.xml
port/linux/game/menu_functions.c
source/game/game_engine.h
source/game/game_engine.c

Added: Start LAN, internet and split screen games alone. A game with one machine and one player can now start. Pressing start alone begins the countdown, others can join while the game is in progress, and the lobby no longer says it's waiting for another machine or player.
source/networking/network_server_manager.c
source/interface/ui_widget_game_data_input_functions.c
2026-10-07 17:45:15 -06:00
Addison Bair 04713926d1 Pass over far objects on a packed copy of their bounding spheres
A collision query (collision_get_features_in_sphere) reads the bounding
sphere of every collideable object in every cluster it touches, to pass
over the far ones. Every biped queries each tick, so a crowded cluster
(co-op's extra enemies, a carrier burst) costs the square of the crowd in
scattered object reads.

object_bounds_cache.c keeps the spheres packed by absolute index, written
by their only writer (object_compute_node_matrices). The loop runs the same
point_in_sphere on the copy, so the same objects are passed over and the
same features gathered, in order. game_state.c invalidates the copy when
the game state is replaced (revert, loaded core or game, new map).

Deterministic offline crowd (c20, legendary, extra enemies x8, 24 carriers
burst, seed pinned): game state identical tick for tick; collision queries
4.2 -> 3.0 us (-28%), object updates -15%.
2026-10-07 22:11:47 +00:00
MrBruh 6e015a75ad Merge pull request #168 from xshxdex98/upstream-coop-bringto
Co-op: bringto brings every player to the host
2026-10-08 10:56:51 +13:00
MrBruh bfe812fe10 Merge pull request #164 from xshxdex98/upstream-vehicle-homes
Bring back every vehicle a map places, not the first 64
2026-10-08 10:56:51 +13:00
MrBruh 1617f43fbc Merge pull request #163 from xshxdex98/upstream-client-outside-world
Leave the host's falling bipeds to the host on a client
2026-10-08 10:56:50 +13:00
MrBruh 5bf891fd80 Merge pull request #158 from xshxdex98/upstream-oddball-no-spawn
Place the oddball at a starting location on a map with no ball spawn
2026-10-08 10:56:48 +13:00
MrBruh db9b2f4a5b Merge pull request #155 from xshxdex98/upstream-ce-map-version
Refuse a Custom Edition map of another version than the host's
2026-10-08 10:56:47 +13:00
MrBruh 36411f5dea Merge pull request #153 from xshxdex98/upstream-ce-linear-pitch
Custom Edition maps: linear bitmaps of any row length drawn
2026-10-08 10:56:46 +13:00
MrBruh f41c8e977a Merge pull request #145 from addisonbair/widget-pools
Fix invisible plasma bolts in large network games
2026-10-08 10:56:45 +13:00