Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions port/assets/menus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ A settings screen (Controls Setup, Gamepads, Mouse, Audio, Video or Network
Setup) is changed in `tools/port_settings.py`, not in its XML, and written
with the command above.

To regenerate only one port settings screen without the external tag assets:

```sh
python tools/port_settings.py gamepad_setup
```

## Elements

A file holds one `<menus>` element (`root` names the main menu's widget, in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
</widget>
<widget name="main_menu/settings_select/player_setup/player_profile_edit/gamepad_setup/button_preset_label" type="text" controller="1" width="300" height="22" string_list="main_menu/settings_select/player_setup/player_profile_edit/gamepad_setup/labels" string_index="4" font="ui\large_ui" color="#FF2896FF" text_x="13" text_y="4">
</widget>
<widget name="main_menu/settings_select/player_setup/player_profile_edit/gamepad_setup/button_preset_spinner" type="spinner" left="3" top="2" width="147" height="20" flags="pass_unhandled_to_focused_child left_right_tabs_items" strings="DEFAULT|SWAP TRIGGERS|SWAP A, L TRIGGER|SWAP B, L TRIGGER|SWAP B, R STICK" setting="profile.button_preset" values="0|1|2|3|4" font="ui\large_ui" color="#FF2896FF" align="center" text_y="1" header_bitmap="bitmaps/arrow_sm_left" footer_bitmap="bitmaps/arrow_sm_right" header_bounds="7 -6 19 0" footer_bounds="7 150 19 156">
<widget name="main_menu/settings_select/player_setup/player_profile_edit/gamepad_setup/button_preset_spinner" type="spinner" left="3" top="2" width="147" height="20" flags="pass_unhandled_to_focused_child left_right_tabs_items" strings="DEFAULT|SWAP TRIGGERS|SWAP A, L TRIGGER|BOXER|GREEN THUMB|BUMPER JUMPER|RECON|WALKIE TALKIE|FISHSTICK|HELLJUMPER" setting="profile.button_preset" values="0|1|2|3|4|5|6|7|8|9" font="ui\large_ui" color="#FF2896FF" align="center" text_y="1" header_bitmap="bitmaps/arrow_sm_left" footer_bitmap="bitmaps/arrow_sm_right" header_bounds="7 -6 19 0" footer_bounds="7 150 19 156">
<on event="created" run="port setting load"/>
</widget>
<widget name="main_menu/settings_select/player_setup/player_profile_edit/gamepad_setup/op_joystick_preset" width="512" height="28" flags="pass_unhandled_to_focused_child" bitmap="bitmaps/option_bkds" color="#FF2896FF">
Expand Down Expand Up @@ -126,7 +126,7 @@
<string text="Pushing the right stick up looks down."/>
<string text="Flying vehicles pitch as aircraft do: pushing up\nflies down."/>
<string text="Level the view while walking."/>
<string text="Which of the controller's buttons does what (not\nthe keyboard's: Controls Setup sets those)."/>
<string text="Controller layouts adapted to Halo CE. Fishstick\nand Helljumper use LT toggle zoom. Menus keep A/B."/>
<string text="Which stick moves and which looks."/>
<string text="Rumble the controller."/>
<string text="Show the game's hints about its controls."/>
Expand Down
41 changes: 41 additions & 0 deletions port/linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,47 @@ controller 1. The gamepad changes controller only when none of its buttons
is held. The profile's button layout (Settings > Gamepads) is the
gamepads' only.

Settings > Gamepads > Button Layout offers BUMPER JUMPER, based on Halo 3.
It is saved in the player profile. Menus keep A to accept and B to go back.

| Button | Bumper Jumper action |
| --- | --- |
| LB | Jump |
| RB | Melee |
| LT | Throw grenade |
| RT | Fire |
| A | Switch grenades |
| B | Reload / use (hold to swap weapons) |
| X | Flashlight (Halo CE has no equipment) |
| Y | Switch weapons |
| Left stick click | Crouch |
| Right stick click | Zoom |
| Start / Back | Pause / scores |

Other layouts include classic BOXER (LT melee, B grenade) and GREEN THUMB
(right stick click melee, B zoom), named versions of the existing swaps.
The later-game layouts below are adapted to CE's actions. They keep RT fire,
Y switch weapons, Start pause and Back scores. Stick layout is independent.

| Action | Recon | Walkie Talkie | Fishstick | Helljumper |
| --- | --- | --- | --- | --- |
| Jump | A | A | A | LB |
| Melee | B | RB | Right stick click | Right stick click |
| Reload / use | RB | B | X | B |
| Throw grenade | LT | LT | RB | RB |
| Switch grenades | LB | X | LB | A |
| Flashlight | X | LB | Left stick click | X |
| Crouch | Left stick click | Left stick click | B | Left stick click |
| Zoom | Right stick click | Right stick click | LT | LT |

Recon follows Halo 3's default layout, with X flashlight instead of equipment.
Walkie Talkie's LB operates the flashlight; it does not bind voice chat.
Fishstick and Helljumper use CE's toggle/cycle zoom, not hold-to-aim. CE has
no sprint, equipment or Spartan abilities; the remaining buttons serve its
flashlight and grenade selection. Layout references:
[Halo 3](https://www.halopedia.org/H3:Control_schemes) and
[Halo 5](https://www.halopedia.org/H5G:Control_schemes).

| Action | Keys and buttons (default) |
| --- | --- |
| move | W, A, S, D |
Expand Down
14 changes: 9 additions & 5 deletions port/linux/game/menu_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -1626,6 +1626,7 @@ BITMAP_FRAMES): Gamepad Setup's row's, as the list numbers its rows
the PC version's nine the Xbox's five of the button settings */
#define PROFILE_GAMEPAD_FRAME 2
#define PROFILE_FIRST_LAYOUT_FRAME 9
#define PROFILE_LAYOUT_PICTURES 5

/* "port gamepad layout preview" (the picture's own): on Gamepad Setup's
row, the edited profile's button settings */
Expand All @@ -1635,11 +1636,14 @@ static void profile_gamepad_layout(struct widget_instance *picture)
short frame = picture->animation.current_frame_index;

if (frame == PROFILE_GAMEPAD_FRAME ||
(frame >= PROFILE_FIRST_LAYOUT_FRAME && frame < PROFILE_FIRST_LAYOUT_FRAME + NUMBER_OF_BUTTON_PRESETS))
{
picture->animation.current_frame_index = (short)(PROFILE_FIRST_LAYOUT_FRAME +
(profile && profile->controller_settings.button_preset < NUMBER_OF_BUTTON_PRESETS ?
profile->controller_settings.button_preset : _button_preset_standard));
(frame >= PROFILE_FIRST_LAYOUT_FRAME && frame < PROFILE_FIRST_LAYOUT_FRAME + PROFILE_LAYOUT_PICTURES))
{
/* The Xbox bitmap has only the original five layouts. New layouts
use the PC gamepad picture rather than an absent bitmap frame. */
picture->animation.current_frame_index = profile &&
profile->controller_settings.button_preset >= PROFILE_LAYOUT_PICTURES ?
PROFILE_GAMEPAD_FRAME : (short)(PROFILE_FIRST_LAYOUT_FRAME +
(profile ? profile->controller_settings.button_preset : _button_preset_standard));
}
}

Expand Down
78 changes: 78 additions & 0 deletions source/interface/player_ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,84 @@ static void set_local_player_controls_from_player_profile(
preferences.game_control_to_xbox_buttons[10] = _gamepad_binary_button_left_thumb;
preferences.game_control_to_xbox_buttons[11] = _gamepad_analog_button_b;
break;
/* port: Halo 3 Bumper Jumper; white/black are SDL's LB/RB.
CE has no equipment, so X operates the flashlight. */
case _button_preset_bumper_jumper:
preferences.game_control_to_xbox_buttons[0] = _gamepad_analog_button_white;
preferences.game_control_to_xbox_buttons[1] = _gamepad_analog_button_a;
preferences.game_control_to_xbox_buttons[2] = _gamepad_analog_button_b;
preferences.game_control_to_xbox_buttons[3] = _gamepad_analog_button_y;
preferences.game_control_to_xbox_buttons[4] = _gamepad_analog_button_black;
preferences.game_control_to_xbox_buttons[5] = _gamepad_analog_button_x;
preferences.game_control_to_xbox_buttons[6] = _gamepad_analog_button_left_trigger;
preferences.game_control_to_xbox_buttons[7] = _gamepad_analog_button_right_trigger;
preferences.game_control_to_xbox_buttons[8] = _gamepad_binary_button_start;
preferences.game_control_to_xbox_buttons[9] = _gamepad_binary_button_back;
preferences.game_control_to_xbox_buttons[10] = _gamepad_binary_button_left_thumb;
preferences.game_control_to_xbox_buttons[11] = _gamepad_binary_button_right_thumb;
break;
/* port: Halo 3's default (later named Recon), with X flashlight. */
case _button_preset_recon:
preferences.game_control_to_xbox_buttons[0] = _gamepad_analog_button_a;
preferences.game_control_to_xbox_buttons[1] = _gamepad_analog_button_white;
preferences.game_control_to_xbox_buttons[2] = _gamepad_analog_button_black;
preferences.game_control_to_xbox_buttons[3] = _gamepad_analog_button_y;
preferences.game_control_to_xbox_buttons[4] = _gamepad_analog_button_b;
preferences.game_control_to_xbox_buttons[5] = _gamepad_analog_button_x;
preferences.game_control_to_xbox_buttons[6] = _gamepad_analog_button_left_trigger;
preferences.game_control_to_xbox_buttons[7] = _gamepad_analog_button_right_trigger;
preferences.game_control_to_xbox_buttons[8] = _gamepad_binary_button_start;
preferences.game_control_to_xbox_buttons[9] = _gamepad_binary_button_back;
preferences.game_control_to_xbox_buttons[10] = _gamepad_binary_button_left_thumb;
preferences.game_control_to_xbox_buttons[11] = _gamepad_binary_button_right_thumb;
break;
/* port: Walkie Talkie's flashlight binding; voice chat stays separate. */
case _button_preset_walkie_talkie:
preferences.game_control_to_xbox_buttons[0] = _gamepad_analog_button_a;
preferences.game_control_to_xbox_buttons[1] = _gamepad_analog_button_x;
preferences.game_control_to_xbox_buttons[2] = _gamepad_analog_button_b;
preferences.game_control_to_xbox_buttons[3] = _gamepad_analog_button_y;
preferences.game_control_to_xbox_buttons[4] = _gamepad_analog_button_black;
preferences.game_control_to_xbox_buttons[5] = _gamepad_analog_button_white;
preferences.game_control_to_xbox_buttons[6] = _gamepad_analog_button_left_trigger;
preferences.game_control_to_xbox_buttons[7] = _gamepad_analog_button_right_trigger;
preferences.game_control_to_xbox_buttons[8] = _gamepad_binary_button_start;
preferences.game_control_to_xbox_buttons[9] = _gamepad_binary_button_back;
preferences.game_control_to_xbox_buttons[10] = _gamepad_binary_button_left_thumb;
preferences.game_control_to_xbox_buttons[11] = _gamepad_binary_button_right_thumb;
break;
/* port: Fishstick's LT zoom/RB grenade/RS melee; CE has no sprint,
so LS operates the flashlight and LB switches grenades. */
case _button_preset_fishstick:
preferences.game_control_to_xbox_buttons[0] = _gamepad_analog_button_a;
preferences.game_control_to_xbox_buttons[1] = _gamepad_analog_button_white;
preferences.game_control_to_xbox_buttons[2] = _gamepad_analog_button_x;
preferences.game_control_to_xbox_buttons[3] = _gamepad_analog_button_y;
preferences.game_control_to_xbox_buttons[4] = _gamepad_binary_button_right_thumb;
preferences.game_control_to_xbox_buttons[5] = _gamepad_binary_button_left_thumb;
preferences.game_control_to_xbox_buttons[6] = _gamepad_analog_button_black;
preferences.game_control_to_xbox_buttons[7] = _gamepad_analog_button_right_trigger;
preferences.game_control_to_xbox_buttons[8] = _gamepad_binary_button_start;
preferences.game_control_to_xbox_buttons[9] = _gamepad_binary_button_back;
preferences.game_control_to_xbox_buttons[10] = _gamepad_analog_button_b;
preferences.game_control_to_xbox_buttons[11] = _gamepad_analog_button_left_trigger;
break;
/* port: Helljumper's LB jump/LT zoom/RS melee/RB grenade, with
A switching grenades and X operating the flashlight. */
case _button_preset_helljumper:
preferences.game_control_to_xbox_buttons[0] = _gamepad_analog_button_white;
preferences.game_control_to_xbox_buttons[1] = _gamepad_analog_button_a;
preferences.game_control_to_xbox_buttons[2] = _gamepad_analog_button_b;
preferences.game_control_to_xbox_buttons[3] = _gamepad_analog_button_y;
preferences.game_control_to_xbox_buttons[4] = _gamepad_binary_button_right_thumb;
preferences.game_control_to_xbox_buttons[5] = _gamepad_analog_button_x;
preferences.game_control_to_xbox_buttons[6] = _gamepad_analog_button_black;
preferences.game_control_to_xbox_buttons[7] = _gamepad_analog_button_right_trigger;
preferences.game_control_to_xbox_buttons[8] = _gamepad_binary_button_start;
preferences.game_control_to_xbox_buttons[9] = _gamepad_binary_button_back;
preferences.game_control_to_xbox_buttons[10] = _gamepad_binary_button_left_thumb;
preferences.game_control_to_xbox_buttons[11] = _gamepad_analog_button_left_trigger;
break;
}

preferences.invert_look = controls->invert_look;
Expand Down
24 changes: 22 additions & 2 deletions source/interface/ui_widget_game_data_input_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -3908,7 +3908,17 @@ static void player_profile_1wide_list_update(
profile->controller_settings.joystick_preset);
wchar_t const *button_description = unicode_string_list_get_string(
button_descriptions_tag_index,
profile->controller_settings.button_preset);
profile->controller_settings.button_preset >= _button_preset_bumper_jumper ?
_button_preset_standard : profile->controller_settings.button_preset);
/* port: the Xbox string list has only the original presets. */
switch (profile->controller_settings.button_preset)
{
case _button_preset_bumper_jumper: button_description = L"Bumper Jumper"; break;
case _button_preset_recon: button_description = L"Recon"; break;
case _button_preset_walkie_talkie: button_description = L"Walkie Talkie"; break;
case _button_preset_fishstick: button_description = L"Fishstick"; break;
case _button_preset_helljumper: button_description = L"Helljumper"; break;
}

usnprintf(
profile_description->parameters.text_box.text,
Expand Down Expand Up @@ -3939,7 +3949,17 @@ static void player_profile_1wide_list_update(
profile->controller_settings.joystick_preset);
wchar_t const *button_description = unicode_string_list_get_string(
button_descriptions_tag_index,
profile->controller_settings.button_preset);
profile->controller_settings.button_preset >= _button_preset_bumper_jumper ?
_button_preset_standard : profile->controller_settings.button_preset);
/* port: the Xbox string list has only the original presets. */
switch (profile->controller_settings.button_preset)
{
case _button_preset_bumper_jumper: button_description = L"Bumper Jumper"; break;
case _button_preset_recon: button_description = L"Recon"; break;
case _button_preset_walkie_talkie: button_description = L"Walkie Talkie"; break;
case _button_preset_fishstick: button_description = L"Fishstick"; break;
case _button_preset_helljumper: button_description = L"Helljumper"; break;
}

usnprintf(
profile_description->parameters.text_box.text,
Expand Down
6 changes: 6 additions & 0 deletions source/saved games/player_profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ enum
_button_preset_swap_a_and_left_trigger,
_button_preset_swap_b_and_left_trigger,
_button_preset_swap_b_and_right_thumb,
_button_preset_bumper_jumper, /* port: appended to preserve saved preset values */
/* port: later-game layouts adapted to CE's actions */
_button_preset_recon,
_button_preset_walkie_talkie,
_button_preset_fishstick,
_button_preset_helljumper,
NUMBER_OF_BUTTON_PRESETS
};

Expand Down
20 changes: 17 additions & 3 deletions tools/port_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,10 @@
("AUTO-CENTER LOOK:", "profile.autocenter", YES_NO,
"Level the view while walking.", None),
("BUTTON LAYOUT:", "profile.button_preset",
[("DEFAULT", "0"), ("SWAP TRIGGERS", "1"), ("SWAP A, L TRIGGER", "2"), ("SWAP B, L TRIGGER", "3"),
("SWAP B, R STICK", "4")],
"Which of the controller's buttons does what (not\nthe keyboard's: Controls Setup sets those).", None),
[("DEFAULT", "0"), ("SWAP TRIGGERS", "1"), ("SWAP A, L TRIGGER", "2"), ("BOXER", "3"),
("GREEN THUMB", "4"), ("BUMPER JUMPER", "5"), ("RECON", "6"), ("WALKIE TALKIE", "7"),
("FISHSTICK", "8"), ("HELLJUMPER", "9")],
"Controller layouts adapted to Halo CE. Fishstick\nand Helljumper use LT toggle zoom. Menus keep A/B.", None),
("STICK LAYOUT:", "profile.joystick_preset",
[("DEFAULT", "0"), ("SOUTHPAW", "1"), ("LEGACY", "2"), ("LEGACY SOUTHPAW", "3")],
"Which stick moves and which looks.", None),
Expand Down Expand Up @@ -1460,3 +1461,16 @@ def multiplayer_files() -> dict:


REPLACED_FOLDERS = [f"{MT}/server_settings"]


if __name__ == "__main__":
import argparse
from pathlib import Path

parser = argparse.ArgumentParser(description="Regenerate one port settings screen without external tag assets.")
parser.add_argument("screen", choices=SCREENS)
args = parser.parse_args()
filename = f"{PE}/{args.screen}".replace("/", ".") + ".xml"
destination = Path(__file__).resolve().parents[1] / "port/assets/menus/ce" / filename
destination.write_text("\n".join(settings_files()[filename]), encoding="utf-8")
print(destination)
Loading