NOTE: With the release of NorthernUIAway, this article is outdated. However, information in here may still be useful to users who wish to use NorthernUI's DLL alongside other UI overhauls, such as DarNified UI.
Bare-minimum needed changes
The instructions below describe the bare-minimum changes needed to get gamepad support working in the vanilla menu files. Instructions may differ for other UI overhauls. You will, at a minimum, need to know basic XML to make the changes needed to enable all of the gamepad functionality.
The world map and local map
NorthernUI does not add full gamepad support to the maps unless a variable is set in the menu file; this is mainly for compatibility reasons. Most menus hide the gamepad map cursor anyway, so that must be edited as well.
To start with, find the first tile inside of the root XML element. Just before it, add this code:<user21>3</user21>
<user22>1</user22>
That code enables gamepad control of the map cursor, and specifies which joystick should be used to control the cursor.
Next, you'll need to find two tiles, which in the vanilla menu are called "map_world_map_cursor" and "map_local_map_cursor". These tiles should have the following trait:<visible>&xenon;</visible>
Change it to:<visible> <copy src="NorthernUI()" trait="_xxnGamepadAvailable" /> </visible>
The "persuasion" mini-game
NorthernUI does not add full gamepad support for the persuasion mini-game unless a variable is set in the menu file; this is mainly for compatibility reasons. Find the first tile inside of the root XML element. Just before it, add this code:<user24>&true;</user24>
Lockpicking
Full gamepad support for LockPickMenu requires that we add an invisible button to the menu, and tell the game to treat A-presses in the menu as if they were clicks on that button. Find the first XML element with a name attribute, and insert this code before it:<xbuttona> <ref src="northernui_minigame_click_shim" trait="clicked" /> </xbuttona>
<rect name="northernui_minigame_click_shim">
<id>9001</id>
<target>&true;</target>
<visible>&true;</visible>
<xdefault>&true;</xdefault>
</rect>
General notes
NorthernUI adds gamepad support to the game, including its menus. However, the vanilla menus will not display Xbox button mappings even though those mappings exist in the menu code. This is because Bethesda relied on compile-time constants to determine whether Xbox-related content should display. Constants aren't sufficient for NorthernUI's use case (they don't allow for detecting the connection or disconnection of a gamepad in real-time), so the mod
relies on other means to know when to show gamepad mappings and leaves the vanilla constants unchanged.
NorthernUI writes values to some of the user-prefixed traits in some menus, in order to supply menu-side code with more information to work with; it sometimes gets the executable to read new user-prefixed traits in order to allow menu-side code to control executable-side behaviors. All of these changes should be backward-compatible with the vanilla menus. No attempt was made to ensure compatibility with other UI overhauls. Traits used are listed in another article.
Oblivion XML
Oblivion menu files are written in XML. A full, formal reference for how Oblivion uses XML can be found on the CS wiki or on the UESP wiki. The remainder of this article is simplified documentation.
Menus are made of objects called tiles, which represent not just visible elements like icons and text, but also elements used for positioning. Tiles can have traits such as a size, a position, a font style, and so on. Traits can be numbers or plain text, but numeric ones can also use operators like addition, subtraction, and copying, to compute their values on the fly.
Here is a basic tile, five pixels wide (the "width" trait is set to 5) and two pixels high (the "height" trait is set to 2):<rect name="myTile">
<width>5</width>
<height>2</height>
</rect>
What if we want to position another tile directly below that one? Well, that's where operators come in:<rect name="anotherTile">
<x>
<copy src="myTile" trait="x" />
</x>
<y>
<copy src="myTile" trait="y" />
<add src="myTile" trait="height" />
</y>
</rect>
We've used operators to define the Y-position of the anotherTile tile. It will copy the Y-position of the myTile tile, and then add the height of the myTile tile. This places anotherTile directly beneath myTile. Looking at the operators, you can see that an attribute called "src" (short for "source") is used to specify what tile we want to borrow data from, and an operator called "trait" is used to specify what trait we want to borrow from that tile.
There are some special "source" tiles that we can copy from. Here is an example of the "parent" source:<rect name="outer">
<width>500</width>
<rect name="inner">
<!-- Make this tile use the same width as whatever other tile it is inside of: -->
<width> <copy src="parent()" trait="width" /> </width>
</rect>
</rect>
NorthernUI defines a "NorthernUI()" source, which can be used to access special values:<rect name="xbox_button_icon">
<visible> <copy src="NorthernUI()" trait="_xxnGamepadAvailable" /> </visible>
</rect>
NorthernUI uses "XXN" as a prefix to mark a lot of its added data and features. Here, we are asking NorthernUI whether a gamepad is plugged in, and choosing to make a tile visible or invisible based on that information. Note that the "NorthernUI()" source only works if the "data/menus/NorthernUI/datastore.xml" file exists.
Understanding how keyboard navigation works
Now that we know the basics of traits and operators, we can talk about the specific traits and operators that make keyboard navigation work. The following traits are used for keyboard navigation:
- XButtonA
- XButtonB
- XButtonX
- XButtonY
- XButtonLB
- XButtonRT
- XButtonLT
- XButtonRT
- XLeft
- XRight
- XUp
- XDown
You may notice that all of these traits are named after Xbox buttons. Bethesda designed the game so that keyboard navigation and gamepad navigation are the same. This means that any menu that properly supports keyboard navigation will also support gamepad navigation, if NorthernUI is installed. So, what are these traits for, then?
Well, keyboard navigation traits can be used with a special operator called "ref." Let's look at an example:
<menu name="BookMenu">
<xbuttonb><ref src="button_exit" trait="clicked" /></xbuttonb>
</menu>
In that example code, if you press the B button anywhere in the menu, then the game will treat it as if you've clicked a tile named "button_exit". The "trait" attribute on a <ref/> operator can be used to fake a mouse click ("clicked"), a mouse click with the Shift key held down ("shiftclicked"), or to navigate between elements ("mouseover"). Here is an example of navigation:
<rect name="first_button">
<xdown><ref src="second_button" trait="mouseover" /></xdown>
</rect>
<rect name="second_button">
<xup><ref src="first_button" trait="mouseover" /></xup>
</rect>
Here, we have defined two buttons. If the first button has keyboard focus and you press the "down" arrow key, then focus will move to the second button. If the second button has keyboard focus and you press the "up" arrow key, then focus will move to the first button. And of course, the gamepad's joystick and D-Pad can also be used.