Paul Hontz 444877f06d Linux: Steam's on-screen keyboard comes up for the menus' text fields
The menus' text fields (Server Setup's name and password, the password a
listed game asks for) take only a keyboard's keys: on a Steam Deck in Game
Mode, with no keyboard, there was no way to type into them but to bring up
Steam's keyboard by hand (Steam + X). The game's own on-screen keyboard
(profile and gametype names) works with the controller and is unchanged.

While a field is typed into, the platform layer now runs SDL's text input
where the system has an on-screen keyboard that text input brings up:
Steam's, which Steam asks for with SDL_ENABLE_STEAM_SCREEN_KEYBOARD in Big
Picture and Game Mode (SDL 3.4 opens steam://open/keyboard, and
steam://close/keyboard when the field ends), or a Wayland touch screen with
no keyboard. The field is single-line: Enter on Steam's keyboard ends it, as
a keyboard's Enter does, and closes it. A password's field asks for a
hidden password's keyboard (SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_HIDDEN; Steam's
is the same). Elsewhere text input stays off, so that no input method takes
the keys the field reads. SDL is called from the window's thread (the event
pump), whichever thread the menus run on.

Steam does not say when its keyboard goes (its Enter, or closed by hand),
so SDL holds it to be up while text input runs. Each field begun brings it
up again, even when the last field ended in the same frame, as the password
screen's does after a wrong password (its field ends and begins again): text
input still running is stopped, which closes Steam's keyboard, and started
half a second later, which opens it (Steam takes each as a URL, each
through a process of its own, which could otherwise arrive the other way
round). A keyboard closed by hand comes back when the field is begun again.

On a Steam Deck (SteamOS 3.8.16, Game Mode, the game started from Steam),
the password screen (debug.menu_open) brings Steam's keyboard up at the
bottom of the screen, below the field; keys pressed on it type into the
field, and its Enter ends the field (the game tries to join) and the
keyboard goes (Steam's log: open/keyboard ... Mode=0, then close/keyboard).
2026-10-08 23:21:35 -04:00
2026-09-27 16:40:58 +13:00
2026-10-09 14:20:57 +13:00
2025-11-27 02:27:27 +00:00
2026-10-01 22:33:25 +13:00
2026-06-29 11:34:11 +01:00

Halo: Combat Evolved for Linux, Windows and Android

Join our Discord

This project is a port of the Halo: Combat Evolved decompilation to Linux, Windows and Android. The decompilation is of the Xbox build 2342 (cachebeta.exe, SHA-256 4cc87b45f721270392a96f1674ed2b5cd4a7bb4355faeab4531d1cf1884d9520).

The game on Linux

The port starts from the decompilation of bnunu/halo-1. That project is a fork of punpckhdq/halo.

Download

GitHub Actions builds the game for each commit. These links download the builds of the latest release:

Platform Release Debug
Linux halo-linux-release.zip halo-linux-debug.zip
Windows halo-windows-release.zip halo-windows-debug.zip
Android halo-android-release.zip halo-android-debug.zip

Use the release build to play. The debug build stops at the first failed assertion and writes it to the log. Use the debug build to find and report problems.

The game updates itself. At start-up it looks for a newer release, and asks if you want to install it. Refer to "Updates" in port/linux/README.md.

Each build of the main branch that passes on all three platforms is a new release. The Releases page keeps the last five releases. If the latest build has a problem, get an older build from that page.

Game data

The port does not include the game data. Download an Xbox disc image (.xiso or .iso) of Halo: Combat Evolved. All versions of the game operate. The maps of the European (PAL) version were made for a slower console. The port changes them to play as the North American (NTSC) maps do, so players of the two versions can play together.

  1. Start the game.
  2. At the first start, the game asks for the disc image. Select it.
  3. The game extracts the maps/ folder. Then the game starts.

On Linux and Windows, the game puts maps/ next to the executable. On Android, copy the disc image to the phone first. The app puts maps/ in its data folder. Refer to port/android/README.md.

Platforms

Each platform has its own instructions:

Platform Instructions
Linux (32-bit x86 executable, OpenGL 4.5, SDL3) port/linux/README.md
Windows (32-bit x86 executable, OpenGL 4.5, SDL3) port/windows/README.md
Android (arm64 app, OpenGL ES 3, SDL3) port/android/README.md

The Linux README also gives the controls, the settings and the multiplayer functions. These are almost the same on all platforms.

Multiplayer

The game can play system link games on a local network and on the internet:

  • A system link game can have up to 128 players on up to 128 machines.
  • Linux, Windows and Android machines can play in the same game.
  • An invite link lets a machine join a game on the internet. No server of this project is necessary.
  • The netcode is new. Each machine moves its own player at once, and the host makes the decisions for the game. Refer to port/linux/NETCODE.md.

Build the game

You do not need the Xbox SDK. The port supplies the SDK declarations that the game uses. Refer to port/include/xdk.

To build the game:

  1. Install Python and ninja.
  2. Install the tools for your platform. Refer to the README for the platform.
  3. In the root folder of the repository, enter python configure.py.
  4. Enter ninja with the target for the platform:
Target Result
ninja linux build/linux/halo
ninja windows (on Windows) build/windows/halo.exe and SDL3.dll
ninja android_apk port/android/app/build/outputs/apk/debug/app-debug.apk

If you enter ninja without a target, ninja builds the game for the computer that you use.

tools/ci_build.py makes the same builds as GitHub Actions. For example, enter python tools/ci_build.py linux release.

Build options

Give these options to configure.py:

Option Result
(none) A debug build. A failed assertion stops the game.
--release A release build. The game does not examine assertions, as in the retail game.
--portable The Linux and Windows builds operate on all x86-64 processors. The Linux build also operates on older distributions and on SteamOS: refer to "Portable build" in port/linux/README.md. Use this option for builds that you give to other persons.
--lto=thin, --lto=off Less link-time optimization. The link is faster.
--pgo=off No profile-guided optimization.
--pgo=train Records a new optimization profile. Refer to "Optimization profiles".

Without --portable, the Linux and Windows builds use all the instructions of the processor that builds them (-march=native). Such a build does not always start on a different computer.

Optimization profiles

The builds use profiles of the game to optimize the code:

  • pgo/halo_linux.profdata for Linux and Android.
  • pgo/halo_windows.profdata for Windows.

The profiles need clang 22 or later. With an older clang, the builds do not use the profiles.

To record a new profile:

  1. Delete the profile.
  2. Enter python configure.py --pgo=train.
  3. Enter ninja linux or ninja windows.

The build then plays the main menu and the first minute of each campaign level. This procedure continues for approximately 15 minutes. The game data must be in assets/.

2026-10-27 19:00:41 +01:00
Languages
C 90.1%
Python 6.7%
JavaScript 1.3%
Java 0.6%
C++ 0.2%
Other 0.8%