Compare commits

..
Author SHA1 Message Date
Stefan MaierandClaude Opus 5.5 867855d388 Bot drivers see walls and rocks ahead, back off when stuck, go round teammates
Driving a jeep or a scout, a bot looks ahead (farther the faster) along the
way it turns: a wall or a rock there (not ground it can drive up) is passed
on the most open side nearest its way, slower, and boxed in it backs off.
Stuck is now making no way along its heading for a second and a half, which
spinning wheels no longer hide. A teammate in the way is gone round slowly
on the other side instead of waited for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 13:25:15 +02:00
Stefan MaierandClaude Opus 5.5 9e7fd75f57 Bots: a vehicle left stuck is left alone a while; every third bot follows a person
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 11:41:40 +02:00
Stefan MaierandClaude Opus 5.5 aedf5ff9bc Bot drivers wait for those coming to get in, and brake for teammates
Just in, a bot driver waits up to six seconds while a bot goes for its
vehicle or a person of its team stands near it with a gun's seat free; it
brakes (backing, if fast) for a teammate on foot in its way. A bot takes a
vehicle only when the nearest enemy (or the objective) is a long way off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 11:39:24 +02:00
Stefan MaierandClaude Opus 5.5 fe160e9dbe Bots man turrets while an enemy is about
A turret near a bot (15 world units) is manned while an enemy is within 35
of it, and left once there has been no one to shoot for ten seconds; at it
the bot aims and fires as at a vehicle's gun. The map's vehicles are named
in the log once a game.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 11:23:49 +02:00
Stefan MaierandClaude Opus 5.5 12c97ffa85 Bots take vehicles: drive, man the gun, ride along; and race
A bot whose way is long takes an empty vehicle it can drive near it (a
Warthog, a Ghost, a Scorpion), walking to the driver's door and standing
there until the game offers the seat. Driving, it follows a vehicle's path
(from the vehicle's surface, wider, its steps further apart), turning a
Warthog or a Ghost by facing where it goes and pushing a Scorpion there from
where its gun faces; it runs an enemy down, circles one with a gunner
aboard, fires a Ghost's and a Scorpion's guns, backs off what it is stuck
on, roams between the map's spawn points, and gets out at the objective,
overturned, stuck again and again, or with an enemy close while it stands.
In a game of teams a bot mans the gun of a teammate's vehicle, a person's
first (or rides along with a person), aims and fires it, and gets out once
no one drives. Overturned vehicles near it are turned upright.

In a race a bot heads for the flag it is to touch next
(game_engine_race_next_flag), in a vehicle if it can have one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 16:48:59 +02:00
7 changed files with 1194 additions and 521 deletions

No files matched your search

+1103 -10
View File
File diff suppressed because it is too large. Load diff
+8 -19
View File
@@ -132,7 +132,6 @@ static struct
unsigned long long last_frame_ms;
/* settings (config.toml, [vr]) */
unsigned long settings_read_at; /* config_changes() when the live ones were read */
int smooth_turn;
float snap_turn_degrees;
float smooth_turn_degrees_per_second;
@@ -419,33 +418,22 @@ static void world_to_local(const float world[3], float local[3])
/* ---------- platform side */
/* the settings the VR options (ui_widget.c) change while the game runs:
read at the start, and again whenever one changes */
static void vr_read_live_settings(void)
{
vr.settings_read_at = config_changes();
vr.smooth_turn = config_boolean("vr.smooth_turn");
vr.snap_turn_degrees = (float)config_real("vr.snap_turn_degrees");
vr.smooth_turn_degrees_per_second = (float)config_real("vr.smooth_turn_speed");
vr.motion_tracker_on_wrist = config_boolean("vr.motion_tracker_on_wrist");
vr.crosshair = config_boolean("vr.crosshair");
vr.laser = config_boolean("vr.laser");
vr.vehicle_wheel = config_boolean("vr.vehicle_wheel");
vr.comfort_vignette = (float)config_real("vr.comfort_vignette");
}
void halo_vr_initialize(void)
{
if (vr.active || !getenv("HALO_VR"))
return;
vr_read_live_settings();
vr.smooth_turn = config_boolean("vr.smooth_turn");
vr.snap_turn_degrees = (float)config_real("vr.snap_turn_degrees");
vr.smooth_turn_degrees_per_second = (float)config_real("vr.smooth_turn_speed");
vr.cinematics_3d = config_boolean("vr.cinematics_in_3d");
vr.hud_distance = (float)config_real("vr.hud_distance");
vr.hud_width = 2.0f * vr.hud_distance * tanf((float)config_real("vr.hud_field_of_view") * PI / 360.0f);
vr.screen_distance = (float)config_real("vr.screen_distance");
vr.screen_width = (float)config_real("vr.screen_width");
vr.positional_tracking = config_boolean("vr.positional_tracking");
vr.motion_tracker_on_wrist = config_boolean("vr.motion_tracker_on_wrist");
vr.scope_size = (float)config_real("vr.scope_size");
vr.crosshair = config_boolean("vr.crosshair");
vr.motion_tracker_size = (float)config_real("vr.motion_tracker_size");
vr.motion_tracker_turn = (float)config_real("vr.motion_tracker_turn");
vr.motion_tracker_right = (float)config_real("vr.motion_tracker_right");
@@ -455,6 +443,7 @@ void halo_vr_initialize(void)
vr.rise_limit = 0.25f;
vr.log_performance = config_boolean("vr.log_performance");
vr.aim_with_controller = strcmp(config_string("vr.aim_with"), "head") != 0;
vr.laser = config_boolean("vr.laser");
vr.weapon_offset[0] = (float)config_real("vr.weapon_forward");
vr.weapon_offset[1] = (float)config_real("vr.weapon_right");
vr.weapon_offset[2] = (float)config_real("vr.weapon_down");
@@ -476,11 +465,13 @@ void halo_vr_initialize(void)
vr.vehicle_steer_angle = (float)config_real("vr.vehicle_steer_degrees") * PI / 180.0f;
vr.vehicle_gun_steer_angle = (float)config_real("vr.vehicle_gun_steer_degrees") * PI / 180.0f;
vr.vehicle_pitch_angle = (float)config_real("vr.vehicle_pitch_degrees") * PI / 180.0f;
vr.vehicle_wheel = config_boolean("vr.vehicle_wheel");
vr.vehicle_wheel_angle = (float)config_real("vr.vehicle_wheel_degrees") * PI / 180.0f;
if (vr.vehicle_wheel_angle < 10.0f * PI / 180.0f)
vr.vehicle_wheel_angle = 10.0f * PI / 180.0f;
vr.vehicle_steer_curve = (float)config_real("vr.vehicle_steer_curve");
vr.vehicle_steer_smoothing = (float)config_real("vr.vehicle_steer_smoothing");
vr.comfort_vignette = (float)config_real("vr.comfort_vignette");
vr.grenade_scale = (float)config_real("vr.grenade_scale");
vr.grenade_offset[0] = (float)config_real("vr.grenade_right");
vr.grenade_offset[1] = 0.0f;
@@ -1200,8 +1191,6 @@ void halo_vr_frame_begin(void)
vr.recentre_frames--;
vr_recentre();
}
if (vr.settings_read_at != config_changes())
vr_read_live_settings();
turn_update();
wheel_update();
vignette_update();
+37
View File
@@ -1670,3 +1670,40 @@ boolean game_engine_race_read_network_state(
csmemcpy(race_events.best_laps, state.best_laps, sizeof(race_events.best_laps));
return TRUE;
}
boolean game_engine_race_next_flag(
long player_index,
real_point3d const *from,
real_point3d *position)
{
struct scenario *scenario = global_scenario_get();
real best_distance = REAL_MAX;
boolean found = FALSE;
long itr;
if (!scenario || DATUM_INDEX_TO_ABSOLUTE_INDEX(player_index) >= MULTIPLAYER_MAXIMUM_PLAYERS)
return FALSE;
for (itr = 0; itr < scenario->netgame_flags.count; itr++)
{
struct scenario_netgame_flag *flag = TAG_BLOCK_GET_ELEMENT(
&scenario->netgame_flags,
itr,
struct scenario_netgame_flag);
real distance;
if (flag->type != _netgame_flag_race_track ||
!TEST_FLAG(race_globals.lap_completed_value, flag->team_index) ||
!can_touch_team(player_index, flag->team_index))
{
continue;
}
distance = distance3d(from, &flag->position);
if (distance < best_distance)
{
best_distance = distance;
*position = flag->position;
found = TRUE;
}
}
return found;
}
+7
View File
@@ -18,6 +18,13 @@ struct race_globals;
void race_flags_make_unique(
void);
/* port: the race flag a player is to touch next, the one of those it may
touch nearest the point (the VR port's bots, port/linux/game/bots.c);
FALSE: none */
boolean game_engine_race_next_flag(
long player_index,
real_point3d const *from,
real_point3d *position);
/* ---------- globals */
+2 -492
View File
@@ -5835,7 +5835,6 @@ the public games and a way to type a code in, either of which then joins as
an invite link does (the game shows up in the list once its host is
reached). */
void platform_log(char const *format, ...);
int p2p_join_code(char *text, int size);
int p2p_join_with_code(char const *typed);
int p2p_join_code_status(void);
@@ -6175,18 +6174,6 @@ static boolean ui_join_code_take_pointer(
static void ui_join_code_update(
void)
{
{
/* (each screen's name in the log, as it comes up) */
static char const *logged;
char const *name = widget_globals.active_widgets[0] ? widget_globals.active_widgets[0]->name : NULL;
if (name != logged)
{
logged = name;
if (name)
platform_log("menus: screen %s", name);
}
}
char text[sizeof(ui_join_code_globals.typed) / sizeof(wchar_t)];
short index;
@@ -6420,482 +6407,6 @@ static void ui_join_code_render(
}
}
/* ---------- VR options (the VR port's)
In VR, Y on the main menu or the pause menu opens a panel of the VR
settings one may want to change while playing (vr.c reads them again as
they change), and from it a page of what the controllers' buttons do. */
int config_boolean(char const *name);
double config_real(char const *name);
int config_write(char const *name, char const *value);
int config_write_boolean(char const *name, int value);
enum
{
_vr_option_turning,
_vr_option_snap_angle,
_vr_option_smooth_speed,
_vr_option_vignette,
_vr_option_wheel,
_vr_option_laser,
_vr_option_crosshair,
_vr_option_motion_tracker,
_vr_option_controls,
NUMBER_OF_VR_OPTIONS,
VR_OPTIONS_TOP = 102,
VR_OPTIONS_ROW_HEIGHT = 28,
VR_OPTIONS_FOOTER = 362,
_vr_controls_on_foot = 0,
_vr_controls_vehicles,
_vr_controls_menus,
NUMBER_OF_VR_CONTROLS_PAGES,
};
static struct
{
boolean open;
boolean controls;
short selection;
short page;
} ui_vr_options_globals;
static real const vr_snap_angles[] = { 30.0f, 45.0f, 60.0f, 90.0f };
static real const vr_smooth_speeds[] = { 60.0f, 90.0f, 120.0f, 150.0f, 180.0f };
static real const vr_vignettes[] = { 0.0f, 0.35f, 0.7f, 1.0f };
static char const *const vr_vignette_names[] = { "Off", "Light", "Medium", "Strong" };
static boolean ui_vr_options_screen(
void)
{
struct widget_instance *screen = widget_globals.active_widgets[0];
return halo_vr_active() && screen && screen->name &&
(main_menu_screen_is_active() || strstr(screen->name, "pause_game") != NULL);
}
/* which of the choices a setting is nearest */
static short ui_vr_options_nearest(
real value,
real const *choices,
short count)
{
short index;
short nearest = 0;
for (index = 1; index < count; index++)
{
if (fabs(choices[index] - value) < fabs(choices[nearest] - value))
nearest = index;
}
return nearest;
}
static void ui_vr_options_step(
char const *name,
real const *choices,
short count,
short change)
{
char text[16];
short index = ui_vr_options_nearest((real)config_real(name), choices, count);
index = (short)((index + change + count) % count);
snprintf(text, sizeof(text), "%g", choices[index]);
config_write(name, text);
}
/* a row's setting changed: forward or back, going round */
static void ui_vr_options_change(
short change)
{
switch (ui_vr_options_globals.selection)
{
case _vr_option_turning: config_write_boolean("vr.smooth_turn", !config_boolean("vr.smooth_turn")); break;
case _vr_option_snap_angle:
ui_vr_options_step("vr.snap_turn_degrees", vr_snap_angles, NUMBEROF(vr_snap_angles), change);
break;
case _vr_option_smooth_speed:
ui_vr_options_step("vr.smooth_turn_speed", vr_smooth_speeds, NUMBEROF(vr_smooth_speeds), change);
break;
case _vr_option_vignette:
ui_vr_options_step("vr.comfort_vignette", vr_vignettes, NUMBEROF(vr_vignettes), change);
break;
case _vr_option_wheel: config_write_boolean("vr.vehicle_wheel", !config_boolean("vr.vehicle_wheel")); break;
case _vr_option_laser: config_write_boolean("vr.laser", !config_boolean("vr.laser")); break;
case _vr_option_crosshair: config_write_boolean("vr.crosshair", !config_boolean("vr.crosshair")); break;
case _vr_option_motion_tracker:
config_write_boolean("vr.motion_tracker_on_wrist", !config_boolean("vr.motion_tracker_on_wrist"));
break;
case _vr_option_controls:
ui_vr_options_globals.controls = TRUE;
ui_vr_options_globals.page = _vr_controls_on_foot;
break;
}
ui_play_audio_feedback_sound(_ui_audio_feedback_forward);
}
static void ui_vr_options_close(
void)
{
ui_vr_options_globals.open = FALSE;
ui_vr_options_globals.controls = FALSE;
}
/* the panel's input: up and down choose a row, left and right (or A)
change it, B or Y closes it (the controls page: left and right turn its
pages, B goes back) */
static boolean ui_vr_options_take_event(
struct widget_instance *widget,
struct event_record const *event)
{
short move = 0;
short change = 0;
boolean accept = FALSE;
boolean back = FALSE;
if (widget != widget_globals.active_widgets[0])
return FALSE;
if (ui_vr_options_globals.open && !ui_vr_options_screen())
ui_vr_options_close();
if (!ui_vr_options_globals.open)
{
if (event->type == _event_type_button && event->data.button.value == 1 &&
event->data.button.index == _gamepad_analog_button_y && ui_vr_options_screen())
{
ui_vr_options_globals.open = TRUE;
ui_vr_options_globals.controls = FALSE;
ui_vr_options_globals.selection = 0;
ui_play_audio_feedback_sound(_ui_audio_feedback_forward);
return TRUE;
}
return FALSE;
}
if (event->type == _event_type_left_stick)
{
if (event->data.stick.y == SHORT_MAX)
move = -1;
else if (event->data.stick.y == SHORT_MIN)
move = 1;
else if (event->data.stick.x == SHORT_MAX)
change = 1;
else if (event->data.stick.x == SHORT_MIN)
change = -1;
}
else if (event->type == _event_type_button && event->data.button.value == 1)
{
switch (event->data.button.index)
{
case _gamepad_binary_button_dpad_up: move = -1; break;
case _gamepad_binary_button_dpad_down: move = 1; break;
case _gamepad_binary_button_dpad_right: change = 1; break;
case _gamepad_binary_button_dpad_left: change = -1; break;
case _gamepad_analog_button_a:
case _gamepad_binary_button_start:
accept = TRUE;
break;
case _gamepad_analog_button_b:
case _gamepad_analog_button_y:
case _gamepad_binary_button_back:
back = TRUE;
break;
}
}
if (ui_vr_options_globals.controls)
{
if (back)
{
ui_vr_options_globals.controls = FALSE;
ui_play_audio_feedback_sound(_ui_audio_feedback_back);
}
else if (change || accept)
{
ui_vr_options_globals.page = (short)((ui_vr_options_globals.page + (change ? change : 1) +
NUMBER_OF_VR_CONTROLS_PAGES) % NUMBER_OF_VR_CONTROLS_PAGES);
ui_play_audio_feedback_sound(_ui_audio_feedback_cursor);
}
return TRUE;
}
if (back)
{
ui_vr_options_close();
ui_play_audio_feedback_sound(_ui_audio_feedback_back);
}
else if (move)
{
ui_vr_options_globals.selection = (short)PIN(ui_vr_options_globals.selection + move, 0, NUMBER_OF_VR_OPTIONS - 1);
ui_play_audio_feedback_sound(_ui_audio_feedback_cursor);
}
else if (accept)
{
ui_vr_options_change(1);
}
else if (change && ui_vr_options_globals.selection != _vr_option_controls)
{
ui_vr_options_change(change);
}
return TRUE;
}
/* the pointer over the panel: the row under it chosen, a click on it as A;
on the controls page the tabs, and the footer's Back (TRUE: the panel is
open and took it) */
static boolean ui_vr_options_take_pointer(
struct halo_ui_pointer const *pointer)
{
short x = pointer->left_clicks ? pointer->click_x : pointer->x;
short y = pointer->left_clicks ? pointer->click_y : pointer->y;
if (!ui_vr_options_globals.open)
{
/* (its hint clicked: open) */
if (pointer->left_clicks && x >= 256 && x < 400 && y >= 434 && y < 464 && ui_vr_options_screen())
{
ui_vr_options_globals.open = TRUE;
ui_vr_options_globals.controls = FALSE;
ui_vr_options_globals.selection = 0;
ui_play_audio_feedback_sound(_ui_audio_feedback_forward);
return TRUE;
}
return FALSE;
}
if (!ui_vr_options_screen())
{
ui_vr_options_close();
return FALSE;
}
if (ui_vr_options_globals.controls)
{
if (!pointer->left_clicks)
return TRUE;
if (y >= 50 && y < 74 && x >= 40 && x < 600)
{
ui_vr_options_globals.page = (short)PIN((x - 40) / 186, 0, NUMBER_OF_VR_CONTROLS_PAGES - 1);
ui_play_audio_feedback_sound(_ui_audio_feedback_cursor);
}
else if (y >= 410 && y < 434)
{
ui_vr_options_globals.controls = FALSE;
ui_play_audio_feedback_sound(_ui_audio_feedback_back);
}
return TRUE;
}
if (x >= 118 && x < 522 && y >= VR_OPTIONS_TOP - 4 &&
y < VR_OPTIONS_TOP - 4 + NUMBER_OF_VR_OPTIONS * VR_OPTIONS_ROW_HEIGHT)
{
ui_vr_options_globals.selection = (short)((y - (VR_OPTIONS_TOP - 4)) / VR_OPTIONS_ROW_HEIGHT);
if (pointer->left_clicks)
ui_vr_options_change(1);
}
else if (pointer->left_clicks && x >= 118 && x < 522 && y >= VR_OPTIONS_FOOTER + 4 && y < VR_OPTIONS_FOOTER + 30)
{
ui_vr_options_close();
ui_play_audio_feedback_sound(_ui_audio_feedback_back);
}
return TRUE;
}
/* a line of the controls page: what is pressed, dim, and what it does */
static void ui_vr_controls_line(
short x,
short y,
char const *control,
char const *action)
{
real_argb_color control_color = { 1.0f, 0.55f, 0.75f, 1.0f };
real_argb_color action_color = { 1.0f, 0.88f, 0.88f, 0.88f };
ui_join_code_draw_text(x, (short)(x + 92), y, control, FALSE, 0, &control_color);
ui_join_code_draw_text((short)(x + 92), (short)(x + 280), y, action, FALSE, 0, &action_color);
}
static void ui_vr_controls_note(
short y,
char const *text)
{
real_argb_color color = { 1.0f, 0.88f, 0.88f, 0.88f };
ui_join_code_draw_text(44, 596, y, text, FALSE, 0, &color);
}
static void ui_vr_controls_render(
void)
{
static char const *const tabs[] = { "ON FOOT", "VEHICLES", "MENUS" };
real_argb_color title_color = { 1.0f, 0.55f, 0.75f, 1.0f };
real_argb_color tab_color = { 1.0f, 0.6f, 0.6f, 0.6f };
real_argb_color selected_color = { 1.0f, 1.0f, 1.0f, 1.0f };
short tab;
short left = 44;
short right = 328;
short y = 112;
ui_join_code_draw_quad(24, 40, 616, 440, 0xFF050A18);
ui_join_code_draw_quad(24, 40, 616, 42, 0xFF3A6EA5);
ui_join_code_draw_quad(24, 438, 616, 440, 0xFF3A6EA5);
for (tab = 0; tab < NUMBER_OF_VR_CONTROLS_PAGES; tab++)
{
short x0 = (short)(40 + tab * 186);
if (tab == ui_vr_options_globals.page)
ui_join_code_draw_quad(x0, 50, (short)(x0 + 180), 74, 0x803A6EA5);
ui_join_code_draw_text(x0, (short)(x0 + 180), 52, tabs[tab], FALSE, 2,
tab == ui_vr_options_globals.page ? &selected_color : &tab_color);
}
ui_join_code_draw_text(left, (short)(left + 270), 86, "LEFT CONTROLLER", FALSE, 0, &title_color);
ui_join_code_draw_text(right, (short)(right + 270), 86, "RIGHT CONTROLLER", FALSE, 0, &title_color);
ui_join_code_draw_quad(320, 86, 321, 300, 0xFF3A6EA5);
switch (ui_vr_options_globals.page)
{
case _vr_controls_on_foot:
ui_vr_controls_line(left, y, "Stick", "Move");
ui_vr_controls_line(left, y + 22, "Stick click", "Crouch");
ui_vr_controls_line(left, y + 44, "Trigger", "Grenade: hold it,");
ui_vr_controls_line(left, y + 62, "", "let go as you throw");
ui_vr_controls_line(left, y + 84, "Grip", "Weapon in both hands");
ui_vr_controls_line(left, y + 106, "X", "Action, reload");
ui_vr_controls_line(left, y + 128, "Y", "Switch weapon");
ui_vr_controls_line(left, y + 150, "Menu", "Pause");
ui_vr_controls_line(right, y, "Stick", "Turn");
ui_vr_controls_line(right, y + 22, "Stick click", "Zoom");
ui_vr_controls_line(right, y + 44, "Trigger", "Fire");
ui_vr_controls_line(right, y + 66, "Grip", "Melee (or punch");
ui_vr_controls_line(right, y + 84, "", "forward)");
ui_vr_controls_line(right, y + 106, "A", "Jump");
ui_vr_controls_line(right, y + 128, "B", "Flashlight");
ui_vr_controls_line(right, y + 150, "B held", "Switch grenades");
ui_vr_controls_note(320, "Motion tracker: turn the back of your left wrist towards you.");
ui_vr_controls_note(340, "Scope: zoom, and look through the disc above the weapon.");
ui_vr_controls_note(360, "Hold the Meta button to recentre the view.");
break;
case _vr_controls_vehicles:
ui_vr_controls_line(left, y, "Stick", "Drive");
ui_vr_controls_line(left, y + 22, "Trigger", "Second weapon");
ui_vr_controls_line(left, y + 40, "", "(Banshee, tank)");
ui_vr_controls_line(left, y + 62, "X", "Get in, get out");
ui_vr_controls_line(right, y, "Stick", "Steer; up and down:");
ui_vr_controls_line(right, y + 18, "", "climb, dive");
ui_vr_controls_line(right, y + 40, "Trigger", "Fire");
ui_vr_controls_line(right, y + 62, "B", "Flashlight");
ui_vr_controls_note(300, "Warthog: grip the wheel with one hand or both and turn it.");
ui_vr_controls_note(320, "Holding it, the right trigger accelerates, the left one brakes");
ui_vr_controls_note(338, "and reverses. Let go, and the right stick steers.");
ui_vr_controls_note(360, "At a gun or as a passenger: aim with the right controller.");
break;
default:
ui_vr_controls_line(left, y, "Stick", "Choose");
ui_vr_controls_line(left, y + 22, "X, Y", "As the screen shows");
ui_vr_controls_line(left, y + 44, "Trigger", "Click where it points");
ui_vr_controls_line(right, y, "Stick", "Choose, scroll");
ui_vr_controls_line(right, y + 22, "A", "Accept");
ui_vr_controls_line(right, y + 44, "B", "Back");
ui_vr_controls_line(right, y + 66, "Trigger", "Click where it points");
ui_vr_controls_note(300, "Point at the menus with either controller; its trigger clicks.");
ui_vr_controls_note(320, "On the keyboard, BACK and ENTER under it can be clicked too.");
ui_vr_controls_note(340, "Y on the main menu or the pause menu: these VR options.");
break;
}
ui_join_code_draw_text(44, 596, 412, "%b-button Back Left, right: the other pages", TRUE, 0, &tab_color);
}
static void ui_vr_options_render(
void)
{
real_argb_color title_color = { 1.0f, 0.55f, 0.75f, 1.0f };
real_argb_color text_color = { 1.0f, 0.88f, 0.88f, 0.88f };
real_argb_color dim_color = { 1.0f, 0.5f, 0.5f, 0.5f };
real_argb_color hint_color = { 1.0f, 0.85f, 0.85f, 0.85f };
char value[48];
short row;
boolean smooth = config_boolean("vr.smooth_turn") != 0;
if (!ui_vr_options_screen())
{
ui_vr_options_close();
return;
}
if (!ui_vr_options_globals.open)
{
/* (under the menu; centred by hand, as icons are drawn from the
left) */
ui_join_code_draw_text(266, 400, 440, "%y-button VR options", TRUE, 0, &hint_color);
return;
}
if (ui_vr_options_globals.controls)
{
ui_vr_controls_render();
return;
}
ui_join_code_draw_quad(110, 62, 530, 396, 0xFF050A18);
ui_join_code_draw_quad(110, 62, 530, 64, 0xFF3A6EA5);
ui_join_code_draw_quad(110, 394, 530, 396, 0xFF3A6EA5);
ui_join_code_draw_text(126, 514, 72, "VR OPTIONS", FALSE, 0, &title_color);
for (row = 0; row < NUMBER_OF_VR_OPTIONS; row++)
{
short y = (short)(VR_OPTIONS_TOP + row * VR_OPTIONS_ROW_HEIGHT);
char const *label = "";
boolean unused = FALSE;
value[0] = 0;
switch (row)
{
case _vr_option_turning:
label = "Turning";
snprintf(value, sizeof(value), "%s", smooth ? "Smooth" : "Snap");
break;
case _vr_option_snap_angle:
label = "Snap turn";
snprintf(value, sizeof(value), "%.0f degrees", vr_snap_angles[ui_vr_options_nearest(
(real)config_real("vr.snap_turn_degrees"), vr_snap_angles, NUMBEROF(vr_snap_angles))]);
unused = smooth;
break;
case _vr_option_smooth_speed:
label = "Smooth turn speed";
snprintf(value, sizeof(value), "%.0f degrees/s", vr_smooth_speeds[ui_vr_options_nearest(
(real)config_real("vr.smooth_turn_speed"), vr_smooth_speeds, NUMBEROF(vr_smooth_speeds))]);
unused = !smooth;
break;
case _vr_option_vignette:
label = "Vehicle comfort vignette";
snprintf(value, sizeof(value), "%s", vr_vignette_names[ui_vr_options_nearest(
(real)config_real("vr.comfort_vignette"), vr_vignettes, NUMBEROF(vr_vignettes))]);
break;
case _vr_option_wheel:
label = "Warthog steering wheel";
snprintf(value, sizeof(value), "%s", config_boolean("vr.vehicle_wheel") ? "On" : "Off (stick)");
break;
case _vr_option_laser:
label = "Weapon laser";
snprintf(value, sizeof(value), "%s", config_boolean("vr.laser") ? "On" : "Off");
break;
case _vr_option_crosshair:
label = "Crosshair";
snprintf(value, sizeof(value), "%s", config_boolean("vr.crosshair") ? "On" : "Off");
break;
case _vr_option_motion_tracker:
label = "Motion tracker";
snprintf(value, sizeof(value), "%s", config_boolean("vr.motion_tracker_on_wrist") ? "On the wrist" : "In the HUD");
break;
case _vr_option_controls:
label = "Controller buttons...";
break;
}
if (row == ui_vr_options_globals.selection)
ui_join_code_draw_quad(118, (short)(y - 4), 522, (short)(y + VR_OPTIONS_ROW_HEIGHT - 6), 0x803A6EA5);
ui_join_code_draw_text(128, 330, y, label, FALSE, 0, unused ? &dim_color : &text_color);
if (value[0])
{
char shown[56];
snprintf(shown, sizeof(shown), "< %s >", value);
ui_join_code_draw_text(330, 512, y, shown, FALSE, 1, unused ? &dim_color : &text_color);
}
}
ui_join_code_draw_text(126, 514, VR_OPTIONS_FOOTER + 8, "%a-button Change %b-button Done", TRUE, 0, &text_color);
}
/* whether a menu is up (VR shows it on a screen in the room: render.c) */
boolean ui_widgets_menus_active(
void)
@@ -6934,7 +6445,7 @@ static void ui_widgets_process_mouse(
{
#ifdef HALO_ANDROID
/* (the VR port's panels over the menus take the pointer themselves) */
if (ui_vr_options_take_pointer(&pointer) || ui_join_code_take_pointer(&pointer))
if (ui_join_code_take_pointer(&pointer))
return;
#endif
if (pointer.moved)
@@ -7408,7 +6919,6 @@ void render_ui_widgets(
}
#ifdef HALO_ANDROID
ui_join_code_render();
ui_vr_options_render();
#endif
if (widget_globals.fade_to_black >= 0.0f &&
widget_globals.fade_to_black <= 1.0f)
@@ -8463,7 +7973,7 @@ void process_ui_widgets(
do
{
#ifdef HALO_ANDROID
if (ui_vr_options_take_event(widget, &event) || ui_join_code_take_event(widget, &event))
if (ui_join_code_take_event(widget, &event))
continue;
#endif
if (!pause_pressed)
+21
View File
@@ -853,6 +853,27 @@ done:
return !no_vehicles_moving;
}
short vehicle_bot_drive_kind(
long vehicle_index)
{
struct vehicle_datum *vehicle = vehicle_datum_get(vehicle_index);
struct vehicle_definition *definition = vehicle_specific_definition_get(
vehicle->definition_index);
switch (definition->vehicle_type)
{
case _vehicle_type_human_jeep:
case _vehicle_type_alien_scout:
return _vehicle_bot_drive_facing;
case _vehicle_type_human_tank:
return _vehicle_bot_drive_relative;
case _vehicle_type_turret:
return _vehicle_bot_drive_turret;
default:
return _vehicle_bot_drive_none;
}
}
#ifdef HALO_ANDROID
boolean vehicle_vr_steered_by_facing(
long vehicle_index)
+16
View File
@@ -81,6 +81,22 @@ void vehicle_render_debug(
/* ---------- public code */
/* port: how the VR port's bots (port/linux/game/bots.c) drive a vehicle:
turned to where its driver faces (a jeep, a scout), moved where he pushes
from where he faces (a tank), manned where it stands (a turret), or not
at all (the rest) */
enum
{
_vehicle_bot_drive_none = 0,
_vehicle_bot_drive_facing,
_vehicle_bot_drive_relative,
_vehicle_bot_drive_turret,
};
short vehicle_bot_drive_kind(
long vehicle_index);
boolean vehicle_is_flipped(
long vehicle_index);
#ifdef HALO_ANDROID
/* VR: whether the vehicle's driver steers it by where he faces (the jeep,
boat, plane, scout and fighter: the right stick steers them), as opposed to