From 7a1cf793961f090c7c507a987bfd08324e632849 Mon Sep 17 00:00:00 2001 From: Stefan Maier <145186748+Cesarus85@users.noreply.github.com> Date: Sun, 4 Oct 2026 12:00:41 +0200 Subject: [PATCH 1/2] VR: teammates' triangles over their heads, a click joins on the profile screen The triangle the game draws over each teammate goes into the name's slot over the head (shown in the world there, not on the HUD before the eyes, where it hung distorted), under the name, or alone when names are off. On the screen where controllers join by pressing A, a click is the pad's A. On the screen of games to join, the online games' hint goes into the key bar's free left and the join status under it, clear of the map's picture. Co-Authored-By: Claude Opus 5.5 --- port/linux/src/xinput_sdl.c | 12 ++++++++++- source/interface/hud.c | 41 ++++++++++++++++++++++++++++++++---- source/interface/ui_widget.c | 15 +++++++++++-- 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/port/linux/src/xinput_sdl.c b/port/linux/src/xinput_sdl.c index af25b68f..d2dc4050 100644 --- a/port/linux/src/xinput_sdl.c +++ b/port/linux/src/xinput_sdl.c @@ -813,6 +813,15 @@ In the menus the buttons are the Xbox's by position: A accepts, B goes back. */ int halo_vr_controllers(struct halo_xr_hand hands[HALO_XR_HAND_COUNT], int *menus); int halo_vr_wheel_held(void); +/* a click that stands for the pad's A (ui_widget.c: the screen where +controllers join by pressing it), held a moment */ +static Uint64 vr_pad_a_until; + +void halo_vr_pulse_pad_a(void) +{ + vr_pad_a_until = SDL_GetTicks() + 120; +} + static SHORT vr_stick(float value) { if (value > 1.0f) @@ -859,7 +868,8 @@ static void vr_gamepad_state(XINPUT_GAMEPAD *pad) if (abs(value) > abs(pad->sThumbRX)) pad->sThumbRX = value; value = vr_stick(right->thumbstick[1]); if (abs(value) > abs(pad->sThumbRY)) pad->sThumbRY = value; - merge_button(pad, XINPUT_GAMEPAD_A, (right->buttons & HALO_XR_BUTTON_A) != 0); + merge_button(pad, XINPUT_GAMEPAD_A, (right->buttons & HALO_XR_BUTTON_A) != 0 || + SDL_GetTicks() < vr_pad_a_until); merge_button(pad, XINPUT_GAMEPAD_B, (right->buttons & HALO_XR_BUTTON_B) != 0); merge_button(pad, XINPUT_GAMEPAD_X, (left->buttons & HALO_XR_BUTTON_A) != 0); merge_button(pad, XINPUT_GAMEPAD_Y, (left->buttons & HALO_XR_BUTTON_B) != 0); diff --git a/source/interface/hud.c b/source/interface/hud.c index 50bd928a..7f386096 100644 --- a/source/interface/hud.c +++ b/source/interface/hud.c @@ -961,6 +961,11 @@ static void hud_draw_players( long player_index = local_player_get_player_index(render.local_player_index); long team_index = player_get(player_index)->team_index; +#ifdef HALO_ANDROID + /* (VR: over the heads, with the names: hud_draw_player_name) */ + if (halo_vr_names_apart()) + return; +#endif if (player_index != NONE) { /* the native builds' sessions hold more than 16 players */ @@ -1135,6 +1140,7 @@ static void hud_draw_player_name( long player_index, boolean ally, boolean indicator, + boolean name_shown, real enemy_range, boolean vr_apart) { @@ -1176,7 +1182,7 @@ static void hud_draw_player_name( point[0] = head_position.x; point[1] = head_position.y; - point[2] = head_position.z + (indicator ? 0.15f : 0.0f); + point[2] = head_position.z + (indicator ? 0.06f : 0.0f); slot = halo_vr_add_name(point); if (slot < 0) return; @@ -1185,7 +1191,31 @@ static void hud_draw_player_name( y = (short)(slot_bounds[3] - 4); /* (an ally's whole at any distance it is drawn at) */ view_position.z = -1.0f; + if (indicator) + { + /* (a teammate's triangle at the slot's foot, the name over it: + the game's, drawn on the HUD, would hang before the eyes) */ + struct bitmap_data *bitmap = bitmap_group_get_bitmap_from_sequence( + interface_get_tag_index(_interface_bitmap_multiplayer_hud), 0, 0); + + if (bitmap && _texture_cache_bitmap_get_hardware_format(bitmap, FALSE, TRUE)) + { + point2d tip; + real_rectangle2d whole; + + tip.x = x; + tip.y = (short)(slot_bounds[3] - 2); + whole.x0 = 0.0f; + whole.x1 = 1.0f; + whole.y0 = 0.0f; + whole.y1 = 1.0f; + interface_draw_bitmap(bitmap, &tip, &whole, 0.6f, 0.0f, 1.0f); + y = (short)(tip.y - bitmap->registration_point.y * 0.6f); + } + } indicator = FALSE; + if (!name_shown) + return; } else #endif @@ -1271,7 +1301,8 @@ static void hud_draw_player_names_now( long team_index; real enemy_range; - if (setting == _player_names_none || player_index == NONE) + /* (VR: the triangles over teammates go with the names, shown or not) */ + if ((setting == _player_names_none && !vr_apart) || player_index == NONE) return; team_index = player_get(player_index)->team_index; indicators = game_engine_display_team_indicators(); @@ -1281,12 +1312,14 @@ static void hud_draw_player_names_now( { /* (allies as the game's triangles tell them: the same team) */ boolean ally = player->team_index == team_index; + boolean shown = !(setting == _player_names_none || (ally && setting == _player_names_enemies) || + (!ally && setting == _player_names_allies)); if (iterator.datum_index == player_index || player->unit_index == NONE) continue; - if ((ally && setting == _player_names_enemies) || (!ally && setting == _player_names_allies)) + if (!shown && !(vr_apart && ally && indicators)) continue; - hud_draw_player_name(iterator.datum_index, ally, ally && indicators, enemy_range, vr_apart); + hud_draw_player_name(iterator.datum_index, ally, ally && indicators, shown, enemy_range, vr_apart); } return; diff --git a/source/interface/ui_widget.c b/source/interface/ui_widget.c index 60e3ee09..727bb4b5 100644 --- a/source/interface/ui_widget.c +++ b/source/interface/ui_widget.c @@ -5836,6 +5836,7 @@ an invite link does (the game shows up in the list once its host is reached). */ int p2p_join_code(char *text, int size); +void halo_vr_pulse_pad_a(void); int p2p_join_with_code(char const *typed); int p2p_join_code_status(void); void p2p_join_code_clear_status(void); @@ -6143,6 +6144,13 @@ static boolean ui_join_code_take_pointer( press.type = _event_type_button; press.data.button.index = _gamepad_analog_button_a; press.data.button.value = 1; + /* (the screen where controllers join by their A: a click is the + pad's A, there, not a menu's) */ + if (pointer->left_clicks && y < 400 && ui_join_code_screen_active("4way_start2join_screen")) + { + halo_vr_pulse_pad_a(); + return TRUE; + } if (ui_join_code_globals.panel_open) { if (x >= 48 && x < 592 && y >= 128 && y < 128 + ONLINE_PANEL_ROWS * 22) @@ -6315,13 +6323,16 @@ static void ui_join_code_render( if (ui_join_code_screen_active("server_list_screen")) { char const *status = NULL; + real_argb_color hint_color = { 1.0f, 0.85f, 0.85f, 0.85f }; if (ui_join_code_globals.panel_open) { ui_join_code_render_panel(); return; } - ui_join_code_draw_line(372, "%x-button Online games: public ones, or join by a code", TRUE, FALSE); + /* (in the key bar's free left, and under it: clear of the map's + picture) */ + ui_join_code_draw_text(40, 420, 420, "%x-button Online games, join code", TRUE, 0, &hint_color); switch (p2p_join_code_status()) { case _join_code_looking: status = "Looking for the game of that code..."; break; @@ -6344,7 +6355,7 @@ static void ui_join_code_render( } } if (status) - ui_join_code_draw_line(392, status, FALSE, FALSE); + ui_join_code_draw_line(452, status, FALSE, FALSE); } else if (ui_join_code_screen_active("connected_pregame_screen") && global_network_game_server_get()) { From 4af570bc08a1eec13c9d3db56b50888483d7f622 Mon Sep 17 00:00:00 2001 From: Stefan Maier <145186748+Cesarus85@users.noreply.github.com> Date: Sun, 4 Oct 2026 13:13:27 +0200 Subject: [PATCH 2/2] VR: the online games' hint further left and shorter, clear of Y = Create Game Co-Authored-By: Claude Opus 5.5 --- source/interface/ui_widget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/interface/ui_widget.c b/source/interface/ui_widget.c index 727bb4b5..23b644fc 100644 --- a/source/interface/ui_widget.c +++ b/source/interface/ui_widget.c @@ -6332,7 +6332,7 @@ static void ui_join_code_render( } /* (in the key bar's free left, and under it: clear of the map's picture) */ - ui_join_code_draw_text(40, 420, 420, "%x-button Online games, join code", TRUE, 0, &hint_color); + ui_join_code_draw_text(8, 200, 420, "%x-button Online / code", TRUE, 0, &hint_color); switch (p2p_join_code_status()) { case _join_code_looking: status = "Looking for the game of that code..."; break;