Repository navigation
ButtonIcons and Picture
ButtonIcons shows the controller's button pictures in the menus and on the HUD as something else. A keyboard mod uses it to show its keys ("Enter" instead of A) in the help bar and in prompts. Picture reads a PNG, resizes it, and turns it into the game's texture file, so you can ship your own button pictures as PNGs.
Thread: Enable, Refresh and Override work from any thread. Your pick functions are called on the UI thread. Picture works on any thread.
Turns Key_Enter.png (shipped in your mod's folder) into a game texture, and shows it wherever the game shows the A button.
using FH2;
using FH2ModPlatform;
public sealed class KeyIcons : Mod
{
public override ModInfo Info => new("KeyIcons", "1.0.0");
protected override void OnInit()
{
var pic = Picture.FromPng(File.ReadAllBytes(Path.Combine(ModFolder, "Key_Enter.png")));
if (pic == null) return;
SetFile("UI/textures/data_bound/KeyIcons/Key_Enter.swatchbin", pic.Resize(64, 64).ToSwatchbin());
ButtonIcons.Enable(req => req.Button == "A" ? new ButtonIcon("KeyIcons/Key_Enter") : null);
}
}Imports System.IO
Imports FH2
Imports FH2ModPlatform
Public Class KeyIcons
Inherits [Mod]
Public Overrides ReadOnly Property Info As ModInfo
Get
Return New ModInfo("KeyIcons", "1.0.0")
End Get
End Property
Protected Overrides Sub OnInit()
Dim pic = Picture.FromPng(File.ReadAllBytes(Path.Combine(ModFolder, "Key_Enter.png")))
If pic Is Nothing Then Return
SetFile("UI/textures/data_bound/KeyIcons/Key_Enter.swatchbin", pic.Resize(64, 64).ToSwatchbin())
ButtonIcons.Enable(Function(req As ButtonIconRequest) As ButtonIcon?
If req.Button = "A" Then Return New ButtonIcon("KeyIcons/Key_Enter")
Return Nothing
End Function)
End Sub
End Class| Member | What it does |
|---|---|
IsReady (property, bool) |
True once the pictures can be swapped (the game's code is as expected). |
Enable(Func<ButtonIconRequest, ButtonIcon?> pick) (method) |
From now on, pick says what each button shows. Return null for the controller's own picture. It's asked each time the game shows a button. |
Refresh() (method) |
Shows the pictures on screen again, asking your pick function anew, at the next UI frame. Call it when your answers change (the player rebinds a key). |
Override(string controlType, string resource, Func<ButtonIcon?> pick) (method) |
Swaps a picture that another control keeps as a resource of its own. For example FH2 ANNA's HUD: control "HUDAnnaControl", resource "FH2ANNA_Icon_Open". Return null for its own picture. Asked again at each Refresh. |
What the game asks for.
| Member | What it does |
|---|---|
Button (property, string) |
The button: "A", "X", "Menu", "View", "LB", "LT", "L3", "DPadUp", "DPadUpDown"... |
Large (property, bool) |
True for the large picture (the HUD's). |
Place (property, ButtonIconPlace) |
Where it's shown. |
The picture to show instead.
| Member | What it does |
|---|---|
ButtonIcon(string Texture, float Aspect = 1) (constructor) |
A texture you've written under ui/textures/data_bound, named without the extension ("MyKeys/Key_0D"), and how many times as wide as high it is. |
Texture (property, string) |
The texture's name. |
Aspect (property, float) |
Width divided by height. Only used in the help bar (up to 4). |
| Value | Meaning |
|---|---|
HelpBar |
The help bar ("(A) Select (B) Back"). The picture may be wider than high (up to 4 times). |
HudPrompt |
The HUD's prompts while driving ("(X) Enter garage"). A square. |
Page |
A picture a page names itself ("PRESS (A) TO START", the tab strips' LB/RB). A square. |
A picture in memory, in BGRA with the colour premultiplied by alpha (as the game's UI textures are).
| Member | What it does |
|---|---|
Picture(int width, int height, byte[]? bgra = null) (constructor) |
A picture of that size. Without bgra, it starts fully transparent. Throws ArgumentException if bgra isn't width * height * 4 bytes. |
Width (property, int) |
Its width in pixels. |
Height (property, int) |
Its height in pixels. |
Bgra (property, byte[]) |
The pixels, in rows from the top: blue, green, red, alpha, with the colour premultiplied by alpha. You can change them. |
FromPng(byte[] png) (static method, returns Picture?) |
Reads a PNG, or null if it can't be read. |
Resize(int width, int height) (method, returns Picture) |
A new picture at another size. Smaller: each pixel is the average of what it covers. Larger: smoothly stretched. |
ToSwatchbin() (method, returns byte[]) |
The game's texture file (.swatchbin) of it, for SetFile under ui/textures/.... In XAML it's then shown as "/ForzaUI;component/Textures/....png". |
- Write your textures with
SetFileinOnInit, so they're in place before the game reads them. Use the same name inButtonIcon, withoutui/textures/data_bound/and without the extension. - Your pick function is called often (each time the game shows a button picture). Keep it quick: look the answer up, don't load files there.
- If a pick function throws, the error goes to platform.log and the controller's own picture is shown.
-
Enablewaits for Menus to be ready (up to a minute), so you can call it fromOnInit. - VB: a pick function has to return
ButtonIcon?(a nullable). Write it as a multi-lineFunction(...) As ButtonIcon?as in the example.If(cond, New ButtonIcon(...), Nothing)gives an emptyButtonIconinstead ofNothing. -
FromPngreads PNGs with 8 bits per channel, or with a palette. It doesn't read 16-bit or interlaced PNGs (it returns null). -
ToSwatchbinthrowsInvalidOperationExceptionif a side isn't a multiple of 8.Resizefirst if needed. -
Unsupported game build: if the help bar's code isn't as expected,
ButtonIconsswitches itself off,IsReadystays false, and platform.log says "ButtonIcons off: ...". The game then shows the controller's pictures. If only the HUD prompts don't match, platform.log says "ButtonIcons: the HUD's prompts keep the controller's buttons", and the rest still works.
- Menus and UiElement
- GameInput: make the keys do what the pictures say.
- SettingsTile
- UI and Hud
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