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? |
|
2019-01-02 06:51:30 +00:00
|
|
|
| `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.
|
2019-01-02 06:51:30 +00:00
|
|
|
|
2020-04-13 21:03:54 +01:00
|
|
|
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`
|
|
|
|
|
2020-04-14 03:14:49 +01:00
|
|
|
Here's the full list of values for `MENUTYPE`:
|
2020-04-13 21:03:54 +01:00
|
|
|
|
2020-04-14 03:14:49 +01:00
|
|
|
| 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.
|
2020-04-13 21:03:54 +01:00
|
|
|
|
2020-04-14 03:14:49 +01:00
|
|
|
## `SUBMENUTYPE`
|
2019-01-02 06:51:30 +00:00
|
|
|
|
|
|
|
The types seem to refer to different types of UI widget. Here's a list of unique
|
|
|
|
values:
|
|
|
|
|
|
|
|
|
|
|
|
| Value | Meaning |
|
|
|
|
|-------|---------|
|
2020-04-14 03:14:49 +01:00
|
|
|
| 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.
|
2020-03-21 00:56:35 +00:00
|
|
|
|
|
|
|
## 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:
|
|
|
|
|
|
|
|

|
|
|
|
|
2020-04-14 03:14:49 +01:00
|
|
|
However, it's *not* sufficient to put all the items for `MainGame.mnu` in the
|
|
|
|
right place.
|
|
|
|
|
2020-03-21 00:56:35 +00:00
|
|
|
## 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.
|