# *.mnu These files appear to be the UI definitions for Chaos Gate. Some relate to system menus, other to in-game menus. Their names are hardcoded into the `WH40K.exe` binary. Each has a `.obj` file associated with it. It's an ASCII-formatted text file with a 12-line header, followed by a number of descriptor records. Here's the top of `MainGame.mnu`: ``` MainGame.obj BACKGROUND COLOR 0..255..-1 trans : 0 HYPERTEXT COLOR 0..255 : 120 FONT TYPE 0..5 : 10 wh40k_12 basfnt12 wh40k_47 wh40k_12_red wh40k_12_blue wh40k_12_green wh40k_12_yellow NULL ``` The first line of the header is a `.obj` file containing sprites we want to display on-screen. We see entries further down have a `SPRITEID`, which must reference entries in that file. In `SaveGame.mnu`, we can see multiple `.obj` files can be referenced. There are then 3 lines that seem to be fixed descriptor names with values that vary. Is this font colour, perhaps? Unsure. Next is a variable-length list of font names, referencing files in the `Fonts` directory. Finally, there's a list of records that specify the menu itself. Truncated contents of `SaveGame.mnu`: ``` #rem..........Background MENUID : 1 MENUTYPE : 0 MOVEABLE : 0 ACTIVE : 1 SPRITEID : 0 ACCELERATOR: 0 DRAW TYPE : 0 SHARE : -1 X-CORD : -1 Y-CORD : -1 DESC : * #rem..........MAIN BACKGROUND MENUID : 2 MENUTYPE : 45 MOVEABLE : 0 ACTIVE : 1 SPRITEID : 0 ACCELERATOR: 0 DRAW TYPE : 0 SHARE : -1 X-CORD : -1 Y-CORD : -1 DESC : #rem.......... MAIN BACKGROUND SUBMENUID : 1 SUBMENUTYPE: 31 FONTTYPE : 20 ACTIVE : 0 SPRITEID : -1 ACCELERATOR: 0 DRAW TYPE : 0 SHARE : 0 SOUNDTYPE : 0 DESC : * #rem..........Chat List Box Menu MENUID : 21 MENUTYPE : 1 MOVEABLE : 0 ACTIVE : 1 SPRITEID : 764 ACCELERATOR: 0 DRAW TYPE : 0 SHARE : -1 X-CORD : -1 Y-CORD : -1 DESC : [...] * ~ ``` We start processing these as soon as we see `MENUID`, I suppose. Each toplevel item is `*`-delimited, and the list is terminated with `~`. Each menu has a list of parameters: | Name | Examples | Purpose | |---------|----------|---------| | `MENUID`| `1`, `2`, `3` | Maybe linking between menus? | | `MENUTYPE` | `0`, `1`, `2`, `3`, `45`, `300` | ? | | `MOVEABLE` | `0` | Unimplemented functionality? | | `ACTIVE` | `0`, `1`, `1,0` | ? | | `SPRITEID` | `-1`, `0`, `123`, `16,-1,1` | Select from `.obj` file? | | `ACCELERATOR` | | ? | | `DRAW TYPE` | | ? | | `SHARE` | | ? | | `X-CORD` | `-1`, `0`, `200` | X coordinate to draw at | | `Y-CORD` | `-1`, `0`, `200` | Y coordinate to draw at | | `FONTTYPE` | | Choose a font from the above? | | `SOUNDTYPE` | | ? | | `DESC` | `CHARACTER SELECT`, `51005` | Text, or reference to `Data/USEng.dta` | Submenus also show a couple of unique values: | Name | Examples | Purpose | |---------------|---------------|---------------| | `SUBMENUID` | `1`, `2`, `3` | As `MENUID` | | `SUBMENUTYPE` | `0`, `1`, `2` | As `MENUTYPE` | It seems .mnu files can also include other files, which have the extension `.mni` (presumably for "Menu include"). Examples: ``` * $GenDialog.mni $GenLoad.mni ``` It looks like we just interpolate the named file into the text when we come across one of these lines. The `MENUID` in `GenDialog` and `GenLoad` is a 2-element list, like `1000,1` or `2000,2`. The second number corresponds to the offset in the list of object files. ## `MENUTYPE` Here's the full list of ## `SUBMENUTYPE` ## (Sub)menu types The types seem to refer to different types of UI widget. Here's a list of unique values: | Value | Meaning | |-------|---------| | 0 | Background | | 1 | Logical menu grouping? | | 2 | ? | | 3 | Standard button? | | 30 | Equipment? | | 31 | "Character helmet" / "Slot" | | 40 | "X Line Y" | | 41 | "X Line Y" | | 45 | ? | | 45,10,11,9 | ? | | 45,11,12,10 | ? | | 45,14,15,13 | ? | | 45,17,18,16 | ? | | 45,3,4,2 | ? | | 45,5,6,4 | ? | | 45,6,7,5 | ? | | 45,7,8,6 | ? | | 45,8,9,7 | ? | | 45,9,10,8 | ? | | 50 | ? | | 60 | Other text to display? (`UltEquip.mnu`) | | 61 | Text to display | | 70 | Hypertext to display | | 91 | ? | | 100 | ? | | 110 | ? | | 120 | ? | | 200 | Drop-down button? | | 205 | Single list box item? | | 220 | Psyker power? | | 221 | Page? | | 228 | Big buttons in `Main.mnu` | | 232 | ? | | 233 | ? | | 300 | Pop-up dialog box | | 400,0,0,{8, 16} | ? | | 400,22,22,{2, 4, 5, 6, 7, 8, 9, 9, 10, 13, 16} | ? | | 400,30,-1,5 | ? | | 405,0,0,{8, 16} | ? | | 405,22,22,{2, 4, 5, 6, 7, 8, 9, 10, 13, 16} | ? | | 405,30,-1,5 | ? | ## Positioning The X-CORD and Y-CORD values would seem to be related, to this, but they are universally set to 0 or -1. Far more important are the XOffset and YOffset values for each sprite in the associated .obj files. Taking these into account is enough to draw `Options.mnu` successfully, for instance: ![](img/Options.mnu.png) ## Animation This seems to be done by choosing a different sprite to draw every N ticks. They are laid out sequentially, but I don't yet know how to animate them. It's likely to be the same approach as used for other obj files. Looking at Main.mnu, it points at the object fail Main.obj. This has 118 sprites, which can be described as follows: | Start | Count | Desc | | ------ | ----- | ---- | | 0 | 1 | Background image | | 1 | 3 | New game button: base, pressed, disabled | | 4 | 3 | Load game button: base, pressed, disabled | | 7 | 3 | Multiplayer button: base, pressed, disabled | | 10 | 3 | Settings button: base, pressed, disabled | | 13 | 3 | Quit button: base, pressed, disabled | | 16 | 20 | New game button: 20 animation frames | | 36 | 20 | Load game button: 20 animation frames | | 56 | 20 | Multiplayer button: 20 animation frames | | 76 | 20 | Settings button: 20 animation frames | | 96 | 20 | Quit button: 20 animation frames | | 116 | 1 | Section of background ("Menu title") | | 117 | 1 | Version hotspot | So we have 5 buttons with very similar characteristics, but at different sprite offsets, and two distinct ranges per button, plus some others. Here's some attributes plucked from `Main.mnu`: | Name | (SUB)MENUTYPE | "Active" | "SPRITEID" | "DRAW TYPE" | "SHARE" | | ---------- | ------------- | -------- | ---------- | ----------- | ------- | | Background | 1 | 1 | 0 | 0 | -1 | | Start menu | 1 | 1 | -1 | 0 | -1 | | New game | 228 | 1,0 | 16,-1,1 | 20 | 1 | | Load game | 228 | 1,0 | 36,-1,4 | 20 | 4 | | MP game | 228 | 1,0 | 56,-1,7 | 20 | 7 | | Options | 228 | 1,0 | 76,-1,10 | 20 | 10 | | Quit | 228 | 1,0 | 96,-1,13 | 20 | 13 | | Menu title | 61 | 1 | -1 | 0 | 116 | | V hotspot | 61 | 1 | -1 | 0 | 117 | The buttons, menu title and version hotspot are submenus of the start menu. ### `MENUTYPE` This is the only menu where we see a type of 228. ~750 other unique values are observed, suggesting structure. For instance, we have `24`, `240`, `241` and `2410`, but not `2411` or `2409`. Sometimes we have a comma-separated list, e.g.: `400,30,-1,5`. A listing of some currently-known values: | Value | Type | | ----- | ---------------- | | 0 | Static image | | 1 | Menu | | 3 | Button | | 45 | Thumb | | 50 | Invoke? Button? | | 61 | "Overlay" | | 70 | "Hypertext" | | 91 | Checkbox | | 220 | Animation sample | | 228 | Main menu button | | 232 | Slider | Hypothesis: `MENUTYPE` and `SUBMENUTYPE` are actually distinct lists of values. So far, I've been treating them as the same thing, but, e.g., `MainGame.mnu` has a `MENUTYPE: 45` which is labelled "MAIN BACKGROUND", while `SUBMENUTYPE: 45` is tentatively labelled a "thumb" and used in text boxes. There are also a few cases where I've had to manually override the `MENUTYPE` because it coincides with `Button`. ### `ACTIVE` There are only 4 values seen across all menus: `0`, `1`, `1,0`, `102` and `1,1`. Perhaps this represents possible states? ### Sprite selection For the background (`MENUTYPE: 1`), this points simply at the sprite index in the object file. For the start menu, it's `-1` (no sprite, I assume). For the menu title and version hotspot (`MENUTYPE: 61`, it's `-1` too. For the buttons, it's a list pointing to the start of the 20 animated frames, `-1`, then the start of the 3 static frames. `DRAW TYPE` is the number of animated frames. We only use the animated frames when the button is focused. `SHARE` repeats the start of the static frames, and is the only place they're found for the menu title and version hotspot.