Repository navigation
GameInput
Bartholomew Ho edited this page Nov 9, 2026
·
1 revision
Feeds the game's own controls, as a controller would: the driving controls, the menus' sticks, and the controller's buttons held. It can also let the game play on with no controller at all. This is how a keyboard-and-mouse mod drives the car and works the menus.
Thread: any thread.
W and S are gas and brake, A and D steer, and E shifts up.
using FH2;
using FH2ModPlatform;
public sealed class KeyboardDriving : Mod
{
private bool _eWasDown;
public override ModInfo Info => new("KeyboardDriving", "1.0.0");
protected override void OnInit()
{
_ = Menus.IsReady; // GameInput starts with Menus
Game.Tick += () =>
{
GameInput.SetDriving(DrivingControl.Gas, GameWindow.IsKeyDown(0x57) ? 1 : 0); // W
GameInput.SetDriving(DrivingControl.Brake, GameWindow.IsKeyDown(0x53) ? 1 : 0); // S
float steer = (GameWindow.IsKeyDown(0x44) ? 1 : 0) - (GameWindow.IsKeyDown(0x41) ? 1 : 0); // D, A
GameInput.SetDriving(DrivingControl.Steer, steer);
bool e = GameWindow.IsKeyDown(0x45); // E
if (e && !_eWasDown) GameInput.PressDriving(DrivingControl.ShiftUp);
_eWasDown = e;
};
}
}Imports FH2
Imports FH2ModPlatform
Public Class KeyboardDriving
Inherits [Mod]
Private _eWasDown As Boolean
Public Overrides ReadOnly Property Info As ModInfo
Get
Return New ModInfo("KeyboardDriving", "1.0.0")
End Get
End Property
Protected Overrides Sub OnInit()
Dim ready = Menus.IsReady ' GameInput starts with Menus
AddHandler Game.Tick,
Sub()
GameInput.SetDriving(DrivingControl.Gas, If(GameWindow.IsKeyDown(&H57), 1.0F, 0.0F)) ' W
GameInput.SetDriving(DrivingControl.Brake, If(GameWindow.IsKeyDown(&H53), 1.0F, 0.0F)) ' S
Dim steer = If(GameWindow.IsKeyDown(&H44), 1.0F, 0.0F) - If(GameWindow.IsKeyDown(&H41), 1.0F, 0.0F) ' D, A
GameInput.SetDriving(DrivingControl.Steer, steer)
Dim e = GameWindow.IsKeyDown(&H45) ' E
If e AndAlso Not _eWasDown Then GameInput.PressDriving(DrivingControl.ShiftUp)
_eWasDown = e
End Sub
End Sub
End Class| Member | What it does |
|---|---|
CanDrive (property, bool) |
True once the driving controls can be fed (the game's input code is as expected). |
DrivingControlsOn (property, bool) |
True while the game takes driving input: not on a race's results, in a cutscene, in photo mode or in a menu. As of the last input frame. |
SetDriving(DrivingControl control, float value) (method) |
Adds value to a driving control for as long as you leave it set (set 0 to stop). 1 is a pedal pressed fully or a stick pushed all the way. The controller's own value is added to it, and the total is kept within -1..1. |
SetDrivingAtLeast(DrivingControl control, float value) (method) |
Keeps the control at least at value (set 0 to stop). Meant for the look controls, where a stick let go means "ahead". |
ClearDriving() (method) |
Stops feeding every driving control. |
PressDriving(DrivingControl control) (method) |
One press of a button control (shift up, rewind, map...), as the controller's. Each place in the game that asks for it within a moment sees it pressed once, unless one of them takes it for itself. |
LastAsked(DrivingControl control) (method, returns long) |
When the game last asked for the control, as Environment.TickCount64. The look controls are asked for while a driving camera looks where the stick points. |
| Member | What it does |
|---|---|
SetMenu(MenuControl control, float value) (method) |
Adds value (-1..1) to one of the menus' sticks, for as long as you leave it set. |
| Member | What it does |
|---|---|
HeldButtons (property, PadButtons, get/set) |
Controller buttons held for the game, as if on the controller, until you change it. What reads the buttons themselves (the radio's d-pad, the tile grids, FH2 ANNA) sees them held, pressed and let go. |
HeldXInputButtons (property, ushort, get/set) |
XInput button bits (0x1 d-pad up ... 0x8000 Y) held only where the controller's raw state is read, not for the game's own buttons. Extra Options and its plugins read them there. |
AnyControllerConnected (property, bool) |
True if a controller is connected to the game. |
PlayWithoutController (property, bool, get/set) |
| Member | What it does |
|---|---|
Trace (property, bool, get/set) |
Set to true before the game starts: platform.log then gets each input check that answers anything but 0 (which control, the answer, and where it was asked from), at most every 400 ms each. For finding out what a screen reads. Slows the game a little. |
InputFrame (property, uint) |
Counts the game's input updates (once a frame). 0 until GameInput has started. |
The driving controls you can feed.
| Value | Meaning |
|---|---|
Gas, Brake
|
The pedals, 0..1. |
Steer |
-1 left .. 1 right. |
Handbrake, ShiftUp, ShiftDown, Clutch
|
The other driving controls. |
LookAhead, LookBack, LookLeft, LookRight
|
The right stick, for the driving cameras: up (ahead), back, left, right. |
PhotoMode, Camera, Rewind, Map
|
Photo mode, the camera button, rewind, and the map. Button controls: use PressDriving. |
Interact |
The HUD's prompts ("Enter garage"): X with an automatic gearbox, View with a manual one. |
The menus' analog controls.
| Value | Meaning |
|---|---|
LayerRight, LayerUp
|
Design editor > Edit layer: move, size, spin or skew the layer (right +, up +). |
CameraRight, CameraUp
|
The garage's camera, turned by the right stick (right +, up +). |
The controller's buttons, as the game keeps them. Combine them with | (C#) or Or (VB).
None, DPadUp, DPadDown, DPadLeft, DPadRight, Start, View, LeftStick, RightStick, LB, RB, A, B, X, Y.
-
GameInput starts with Menus. It switches itself on the first time a mod reads
Menus.IsReadyor subscribes toMenus.Frame. If no mod does, nothing you feed reaches the game. - What you feed goes straight to the game's own controls. Driving values only count while the game takes driving input (not in photo mode or a menu). The menu sticks only count in the menus.
-
SetDrivingandSetMenustay set until you change them. Set the value back to 0 (or callClearDriving) when your key is let go. -
SetDrivingAtLeastis applied only while it's set to something other than 0, so it never pulls steering from -1 to 0. -
HeldButtonsstays held until you set it again. SetPadButtons.Noneto let go. - If your mod is a hosted mod and it's reloaded, everything it fed (driving, menu sticks, held buttons) is cleared, and the new copy feeds its own.
-
Unsupported game build: if the game's input code isn't as expected,
CanDrivestays false and platform.log says "GameInput: no driving controls". If held buttons can't be fed, platform.log says "GameInput: no held buttons". The parts for playing without a controller each switch off on their own if they don't match. -
Traceis only read when GameInput starts, so set it inOnInit, beforeMenusis first used.
- Controller: read the real controller.
- GameWindow: the mouse and the keyboard.
- Menus and UiElement: press the menus' keys and focus elements.
- MapView, PhotoCamera, GarageCamera: the map, photo mode and the garage camera.
- Threads
Playing
Getting started
Writing mods
The FH2 classes
- Game
- Player
- Vehicle
- World
- Garage, CarCatalog, Profile
- UI and Hud
- Camera
- Audio
- ANNA
- Skills
- DebugOverlay
- Controller
- GameInput
- GameWindow
- Menus and UiElement
- SettingsTile
- ButtonIcons and Picture
- MapView, PhotoCamera, GarageCamera
More