HDMV Navigation Command Language

HDMV mode uses the HDMV Navigation Command Language (or Navi Commands) for it's HDMV interactive applications. It is used primarily for scripting menu navigation and button actions, its typing discipline is relatively straightforward. It is also used to program the menu's interactive graphics and animations.

HDMV Navigation Command Language
Blu-ray Disc.svg
Type Command language
Paradigm Stack-based, label-driven
Designed by ?
Developer Blu-ray Disc Association
First Release 2006
Latest Release 2016
Typing discipline Static Typing w/ Implicit Handling
Open Format? Yes
Free Format? ?
Filename extensions MovieObject.bdmv
Magic Number MOBJ0100 MOBJ0200 (BD) MOBJ0300 (UHD)
These commands are stored in the Movie Object file. The language is standardized but has added a few additions for Blu-ray 3D (2010) and Ultra HD Blu-ray (2016).

The programming commands are opcodes (abbreviated from operation code) and operands. Opcode is the portion of a machine language instruction that specifies the basic operation to be performed. An Operand is any object capable of being manipulated. All Operation codes and Operands are binary codes (ones and zeros)

An Opcode is a single instruction that can be executed by the CPU. In machine language, a binary or hexadecimal value is loaded into the instruction register. 

There are two Operand Registers: 

  • General Purpose Register (The player has 4096 GPRs total). 
  • Player Status Register (The player has 128 PSRs in total) represents the Player’s playback status, configuration, and preferences. 

 
To look and edit these Navigation Commands, you'll need either Scenarist BD or BDEdit.
 
Here's an example from Made in Abyss; this is the code that powers the HDMV application using Scenarist's syntax:
 
Move [ 4075 ] { Title ( 4 ) }
Move [ 2599 ] 4075
Move [ 4075 ] 2599
Move [ 4076 ] 65535 /*0xffff*/
If [ 4075 ] != 4076
GoTo 7
GoTo 9
GoTo 2005 /*0x7d5*/
Move [ 4075 ] 0
Move [ 2552 ] 4075

Here's another portion for the menu page interactivity:

Move [ 4075 ] [ 3553 ]
And [ 4076 ] 10 /*0xa*/
If [ 4075 ] == [ 4076 ]
GoTo Label1_0
GoTo Label1_1
Label_0:
Move [ 4075 ] 0
Move [ 4075 ] 1
SetButtonPage Button: [ 2577 ] Page ( Effect: On ) : [ 4076 ]
GoTo Label_34
Label_1:
Move [ 4075 ] [ 3553 ]
Move [ 4076 ] 11 /*0xb*/
If [ 4075 ] == [ 4076 ]
GoTo Label1_2
GoTo Label1_3
Label_2:
Move [ 4075 ] 1
Move [ 4076 ] 1
SetButtonPage Button: [ 2575 ] Page ( Effect: On ) : [ 4076 ]
GoTo Label_34


When you open the MovieObject file in BDEdit, it makes the commands a little easier to read. Here's the same MovieObject code from Made in Abyss:

[50000001,00000FEB ,80000004]  Move GPR4075, PSR4 ;PSR4: Title Number (b15-b0) {1-999,$ffff}
[50000001,00000A27 ,00000FEB] Move GPR2599, GPR4075
[50000001,00000FEB ,00000A27] Move GPR4075, GPR2599
[50400001,00000FEC ,0000FFFF] Move GPR4076, 65535
[48000300,00000FEB ,00000FEC] NE GPR4075, GPR4076
[20810000,00000007 ,00000000] GoTo 7
[20810000,00000009 ,00000000] GoTo 9
[20810000,000007D5 ,00000000] GoTo 2005
[20810000,00000009 ,00000000] GoTo 9
[50400001,00000FEB ,00000000] Move GPR4075, 0
[50000001,000009F8 ,00000FEB] Move GPR2552, GPR4075

On the left, the blue numbers represent the Opcode's hexadecimal value (machine code) and the right represents the Operand GPR/PSR commands. Think of GPRs as controlling the software (the disc) and PSRs as controlling the hardware (the player). 

 

When you open a Movie Object file in a hex editor, you will see the file's magic number, 4D 4F 42 4A 30 32 30 30, which translates to MOB0100 or MOB0200, letting the player and developer know that this is a Movie Object file.

00000000 4D 4F 42 4A 30 32 30 30 00 00 00 00 00 00 00 00
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000020 00 00 00 00 00 00 00 00 00 01 38 BA 00 00 00 00
00000030 00 18 80 00 08 63 50 00 00 01 00 00 0F EB 80 00
00000040 00 04 50 00 00 01 00 00 0A 27 00 00 0F EB 50 00
00000050 00 01 00 00 0F EB 00 00 0A 27 50 40 00 01 00 00
00000060 0F EC 00 00 FF FF 48 00 03 00 00 00 0F EB 00 00
00000070 0F EC 20 81 00 00 00 00 00 07 00 00 00 00 20 81
00000080 00 00 00 00 00 09 00 00 00 00 20 81 00 00 00 00
00000090 07 D5 00 00 00 00 20 81 00 00 00 00 00 09 00 00
000000A0 00 00 50 40 00 01 00 00 0F EB 00 00 00 00 50 00

Then you'll see the list of commands in it's hexadecimal values (colored).

[50000001,00000FEB ,80000004]  Move GPR4075PSR4 ;PSR4: Title Number (b15-b0) {1-999,$ffff}
[50000001,00000A27 ,00000FEB]  Move GPR2599GPR4075
[50000001,00000FEB ,00000A27]  Move GPR4075GPR2599
[50400001,00000FEC ,0000FFFF]  Move GPR407665535
[48000300,00000FEB ,00000FEC]  NE GPR4075GPR4076
[20810000,00000007 ,00000000]  GoTo 7
[20810000,00000009 ,00000000]  GoTo 9
[20810000,000007D5 ,00000000]  GoTo 2005
[20810000,00000009 ,00000000]  GoTo 9
[50400001,00000FEB ,00000000]  Move GPR40750
[50000001,000009F8 ,00000FEB]  Move GPR2552GPR4075

 It is possible to edit the Movie Object file directly using a hex editor like ImHex or Hexed.it. But it's recommended to use Blu-ray editing software like BDedit or Scenarist. Unless, your a chad and knows each hexadecimal commands by heart.

 

General Purpose Registers (GPRs)

    Main Article: List of GPRs

A GPR stores a fixed length variable. The variable is stored as a 32-bit unsigned integer. There are 4096 GPRs available. Navigation commands are used to change the values contained in General Purpose Registers. GPRs are used to store temporary data during the execution of HDMV navigation commands in MovieObject.bdmv. They hold variables for menu states, user selections, or intermediate calculations. For example, a GPR might store a value indicating which menu button is highlighted or a counter for navigation logic. It has a small memory of 16 KB.

The HDMV VM has 4,096 GPRs, each 32 bits (4 bytes). They are manipulated by commands like Set or Compare to control menu navigation or playback decisions (e.g., Set GPR[0] = 1 to track a menu choice).

Developers use GPRs to implement menu logic, such as tracking user inputs or branching to different playlists. Their flexibility allows custom navigation within the constraints of HDMV’s fixed instruction set.

In Scenarist, GPRs are written in the program as a number value in square brackets. For example: [ 5 ]. In BDedit they are written like this:  GPR5.


Player Status Registers (PSRs)

    Main Article: List of PSRs 

A PSR stores a fixed length variable. The variable is stored as a 32-bit unsigned integer. There are 128 PSRs including reserved ones in total. Navigation commands can not change the values contained in PSRs. 

PSRs store the Blu-ray player’s current playback state and configuration, providing read-only or read-write access to disc and player information. They track details like the current title, chapter, playlist, audio stream, subtitle stream, or player settings (e.g., language preferences).

There are 128 PSRs, each 32 bits (4 bytes). Examples include PSR3 (current playlist), PSR5 (current chapter), or PSR20 (player language). Some PSRs are read-only (e.g., hardware settings), while others can be modified by navigation commands (see vm.c in libbluray).

Developers query PSRs to make navigation decisions (e.g.,If PSR20 = "en", play English audio) or update playback states (e.g., setting the current chapter).

In Scenarist, PSRs are written in the program in three equivalent forms:

  1. Number in the curly brackets: { 4 };
  2. Name in the curly brackets: { Title };
  3. Name with a number in the round brackets in the curly brackets: { Title ( 4 ) }
In BDedit, they are written like this: PSR4 ;PSR4: Title Number (b15-b0) {1-999,$ffff}


GPRs and PSRs are virtual registers, not physical hardware registers like those in a CPU (e.g., x86 registers). They are defined by the Blu-ray specification and implemented in software by the HDMV VM, as seen in libbluray’s vm.c (e.g.,vm_get_gpr()vm_set_psr() ). They exist in the player’s memory as data structures, typically stored in RAM, to manage navigation and playback state.

The HDMV VM is a software abstraction running on the Blu-ray player’s hardware, not a dedicated processor. GPRs and PSRs are emulated within the VM’s memory space. Physical registers are fixed in hardware (e.g., CPU’s AL, BL), whereas GPRs/PSRs are dynamically allocated in software, ensuring portability across different Blu-ray player architectures.

Developers interact with GPRs and PSRs via HDMV commands, not low-level hardware instructions. The fixed count (4,096 GPRs, 128 PSRs) limits storage, requiring careful optimization for complex menus.


Navigation Commands

    Main Article: List of Navigation Commands

Navigation Commands is divided into four groups, Branch Command Group, Compare Command Group, Set Command Group, and Setsystem Command Group. These commands let the developer control the GPRs and PSRs.


If a developer wishes to develop complex applications such as video games it is recommended to use BD-J mode which uses the object-orientated language, Java.

 

See Also

 

Author(s) : Æ Firestone

on Saturday, August 24, 2024 | , | A comment?
0 responses to “HDMV Navigation Command Language”

Leave a Reply

Popular Pages