Files
ordoor/doc/formats/mnu.md

283 lines
9.0 KiB
Markdown
Raw Normal View History

2018-10-13 03:22:39 +01:00
# *.mnu
These files appear to be the UI definitions for Chaos Gate. Some relate to
2018-12-30 23:23:08 +00:00
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? |
2018-12-30 23:32:44 +00:00
| `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` |
2018-12-30 23:23:08 +00:00
Submenus also show a couple of unique values:
2018-12-30 23:32:44 +00:00
| Name | Examples | Purpose |
|---------------|---------------|---------------|
| `SUBMENUID` | `1`, `2`, `3` | As `MENUID` |
| `SUBMENUTYPE` | `0`, `1`, `2` | As `MENUTYPE` |
2018-10-13 03:22:39 +01:00
2018-12-31 13:38:35 +00:00
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 values for `MENUTYPE`:
| Value | Meaning |
| ----- | ------------ |
| 0 | `Background` |
| 1 | `Menu` |
| 2 | `DragMenu` |
| 3 | `RadioMenu` ??? - only seen in `LevelPly` and `LoadGame` around select-one items |
| 45 | `MainBackground` ??? - only seen in `MainGame` and `MainGameChaos` |
| 300 | `Dialogue` |
The `MENUTYPE` acts as a logical grouping of a set of objects onscreen, and
gives strong hints about how to handle their children.
## `SUBMENUTYPE`
The types seem to refer to different types of UI widget. Here's a list of unique
values:
| Value | Meaning |
|-------|---------|
| 3 | `Button` |
| 30 | `DoorHotspot1` |
| 31 | `DoorHotspot2` |
| 40 | `LineKbd` |
| 41 | `LineBriefing` |
| 45 | `Thumb` |
| 50 | `InvokeButton` |
| 60 | `DoorHotspot3` |
| 61 | `Overlay` |
| 70 | `Hypertext` |
| 91 | `Checkbox` |
| 100 | `EditBox` |
| 110 | `InventorySelect` |
| 120 | `RadioButton` |
| 200 | `DropdownButton` |
| 205 | `ComboBoxItem` |
| 220 | `AnimationSample` |
| 221 | `AnimationHover` |
| 228 | `MainButton` |
| 232 | `Slider` |
| 233 | `StatusBar` |
| 400 | `ListBoxUp` |
| 405 | `ListBoxDown` |
`400`, `405`, and `45`, can all accept 4 values for `SUBMENUTYPE` in a
comma-separated list. These records combine to form a `TListBox` control, with a
number of visible slots that act as a viewport. There is a draggable vertical
slider (the "thumb") to show where in the full list the viewport is, and up +
down buttons to move the position of the thumb by one, so it's feasible that
these values tell us about the available steps.
Here are the values in `Briefing.mnu`:
```
#rem..........List Box Menu
MENUTYPE : 1 # List Box Menu
SUBMENUTYPE: 400,22,22,13 # Scroll Up
SUBMENUTYPE: 405,22,22,13 # Scroll Down
SUBMENUTYPE: 45, 14,15,13 # Thumb
```
There are 13 elements in this listbox, which sorts out the fourth number (but
what is it used for?). The other two need more investigation.
## 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)
However, it's *not* sufficient to put all the items for `MainGame.mnu` in the
right place.
## 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.
2020-03-21 18:50:26 +00:00
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.
### `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.