Handling Display

Author:
Alberto Covarrubias

Programming
Concepts
Using Chars
Using Maps
Using Worlds


Example
Cursor
The Virtual Boy is a console that presents a different kind of display programming. First, programming isn't just have an image and blitting it at a certain coordinate, implies knowledge of the depth for this image in a 3D World. Second, many structures in this console are references to a semi-static section, for optimizing the display process. But, before continue with programming aspects, let's know some fundamental terms.

Concepts

Byte: The 8bit size forever :)

Hword: The 16bit size (2 bytes).

Word: The 32bit size (4 bytes).

Char: The primary structure in image construction. A fixed tile with 8x8 pixel dimension. Uses a uncompressed format of 2 bits per pixel. The char memory space can handle 2048 chars.

Background Map: A secondary structure. Every map represents an image composed of 64x64 chars. To store a BGMap the VB uses a predefined struct that allows a direct reference with the needed chars for this map. This structure handles a 2-bit palette. The console can handle 14 different Maps simultaneously.

Object: Another secondary structure. An object is used to handle complex animations in a game. Composed of a variable size of chars. Storing also needs a predefined struct with information about the char used and it's position and depth in the object. Uses an special 2-bit palette defined for objects. The console can handle 4 objects simultaneously.

World: A complex structure. Represents a logical plane of a map or object. This structure is the base of all the displaying stuff in the VB. Described in a predefined struct that stores position, depth, special FX for blitting, and other params. The console handles 32 planes or worlds.

After reviewing this concepts, I'll continue with the basic stuff on display programming. We need an objective, so... imagine you need to display a stereoscopic box.

Using Chars

As explained above, the char is fundamental to create a image. If we need to display a box, the first thing we need to do is create a compatible 2 bit-per-pixel(bpp) bitmap for that box. The question is... What can i do that? and... the answer is... see below :)

  • Calculate the size: If a char is composed of 8x8 pixels and we are currently using a 2bpp format the required bits of a single char are 128 bits. Now, if storing is in bytes (8 bits), the required bytes are 16, or 8 hwords, or 4 words.
  • Define the on/off bits: Depending on the char, you need to define the 1 values and 0 values. For example, the top-left corner of our box will be:
Rows HWord (8pxs) Hex Value
1 0000000000000000b 0000h
2 0000000000000000b 0000h
3 0000111111111111b 0FFFh
4 0000111111111111b 0FFFh
5 0000111111111111b 0FFFh
6 0000111111111111b 0FFFh
7 0000111111111111b 0FFFh
8 0000111111111111b 0FFFh

After defining your single char data, we need to store it in the char memory. The char memory is composed of 4 segments and is mirrored 4 times? yes, 4. The primary segments are:

Starts Ends Chars Stored
00006000h 00007FFFh 0 - 511
0000E000h 0000FFFFh 512 - 1023
00016000h 00017FFFh 1024 - 1535
0001E000h 0001FFFFh 1536 - 2047

To store our box corner in the CHAR0, we can do in assembler the following (suposse that $1 = 6000h, $2 = 0FFFh):

st.h $0, 0[$1]        ;Row 1
st.h $0, 2[$1]        ;Row 2
st.h $2, 4[$1]        ;Row 3
st.h $2, 6[$1]        ;Row 4
st.h $2, 8[$1]        ;Row 5
st.h $2, 10[$1]        ;Row 6
st.h $2, 12[$1]        ;Row 7
st.h $2, 14[$1]        ;Row 8

After you store every needed char to display a box, you'll have a tile based box like this.

prog000.gif (14476 bytes)

Using Maps

We defined the corners in a box. The next step is to construct a box image. To do this, let's check the definition of the BGMap struct.

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Palett Hflip Vflip 0 BChar

Assuming a standard palett "0" (the palett will be explained in a future reference), and there are no flips (also 0). The only field we missing is BChar and it'll have the value according of the char we need to display. The BGMap is composed of 64x64 chars. We need 64x64 structs like this. If a struct uses 2 bytes (1 hword) then we need 8192 bytes to represent a BGMap.

As defined, the VB uses 14 BGMaps, and the BGMaps are mapped in the following memory segment:

00020000h - 0003C000h  - 14 BGMaps

Storing our box in BGMAP0 can be done using the folowing asm code (assuming $1 = 20000h and $2 = 0h):

st.h $2, 0[$1]        ;Char 1
add 1, $2              ;$2 = 1h

st.h $2, 2[$1]        ;Char 2
add 1, $2              ;$2 = 2h

st.h $2, 128[$1]      ;Char 3
add 1, $2              ;$2 = 3h

st.h $2, 130[$1]      ;Char 4

With this, we have a box image in the BGMAP0, the only missing thing is displaying this map on the VB LEDs.

prog001.gif (26290 bytes)

Using Worlds

The last thing we need to do is create the needed information to display our box in a 3D format. Before starting, we need to know the World predefined struct, that looks like this.

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
LON RON BGM SCX SCY OVR END 0 0 MapRef
Gx
Gp
Gy
Mx
Mp
My
Width
Height
Param Base 0 0 0 0
Overplane Character
0
0
0
0
0

As you can suppose, the most important fields are LON, RON & END because if you don't place this fields right, you will never see an image.

The World memory is mapped in memory as follows:

0003D800h - 0003DBFFh - 32 Worlds (1024 bytes).

The first displayed plane is 31 that is addressed in 0003DBE0h, and so on to finish in plane 0. If a plane has the END bit set, this world and the rest are skipped for display (usually for optimization).

There are 4 types of plane, usually defined with the BGM field:

BGM-Value Type Description
0 Normal Blits the MapRef image using as source rect Mx, My and W, H, and as destination rect Gx, Gy, W, H. The paralax fields will be explained bellow.
1 H-Bias Used for displacement effects in rows, using in the param-base an offset to a hbias table of factors. This method is not quite defined.
2 Affin Used for rotation and scale effects. This method is also no quite defined, maybe I'll write a future reference with this potentially topics.
3 Object This is an appart topic that i'll discuss in a future reference about "Using Objects".

There are 2 ways to handle the 3D display operation, one is easy and the other one is not used, but we'll also review that.

  • Paralax Display: This method is the most common way to generate a stereoscopic display in VB. As shown above, the World struct has a field called paralax that means a little displacement in pixel order. The problem of this method is that the displacement is horizontal, if we need a vertical displacement this param cannot be helpful (after all, the stereoscopic concept is just horizontal).
  • Bi-plane displacement: If you need to make an Horizontal and Vertical displacement, this method is the only way to do that. Consists in use 2 world planes, one with the LON bit set and the other with the RON bit set. The LON plane will handle the left eye displacement and the RON plane will handle the right one. This concept is just if you need a special effect like that, but I think any game use this method.

For this example, we will use the paralax method, with a 5 pixel displacement, using the previous defined box map. The only fields we need to fill (in plane 31) are LON, RON, MapRef, Gx, Gy, Gp, W and H. The plane 30 will have the END field set (to skip this and the following planes).

At least, to display this box, just write the following lines in asm (assuming $1 = 3DE00h and $5 as our variable value):

xor $5, $5                ;Var = 0
movea 0x0C00, $5, $5     ;Setting a 0xC000 means
shl 4, $5                 ;only LOn, ROn set & Map = 0
st.h $5, 0[$1]           ;Store value
xor $5, $5                ;Var = 0
movea 0x0060, $5, $5     ;GX = 0x60 (Screen)
st.h $5, 2[$1]
mov 5, $5                 ;GP = 5
st.h $5, 4[$1]           ;A Simple 3D Effect
xor $5, $5                ;Var = 0
movea 0x006F, $5, $5     ;GY = 0x6F (Screen)
st.h $5, 6[$1]
mov 16, $5                ;W = 16  
st.h $5, 14[$1]
st.h $5, 16[$1]          ;H = 16

movhi 0x3DBC, $0, $1     ;Load 30 World Address
shr 12, $1                ;Alias: 0003DBC0
xor $5, $5                ;Var = 0 , Again? :)
mov 0x40, $5              ;0x0040...End
st.h $5, 0[$1]           ;Load World Desc Part

Well, after doing all this stuff, we only need the palette values... I'll not discuss right now anything about the palettes, for now, use the following:

movhi 0x05F8, $0, $1      ;Get a pointer to the VIP Reg
shr 8, $1                 ;Address: 0005F800
mov 0x0C, $2             ;Load the Color Intensity
st.h $2, 0x24[$1]        ;BRTA
add 0x0C,$2
st.h $2, 0x26[$1]        ;BRTB
add 0x0C,$2
st.h $2, 0x28[$1]        ;BRTC
xor $2, $2
movea 0xE4, $2, $2       ;Pallette Value: 11100100b
st.h $2, 0x60[$1]        ;GPLT0
st.h $2, 0x62[$1]        ;GPLT1
st.h $2, 0x64[$1]        ;GPLT2
st.h $2, 0x66[$1]        ;GPLT3
st.h $2, 0x68[$1]        ;JPLT0
st.h $2, 0x6A[$1]        ;JPLT1
st.h $2, 0x6C[$1]        ;JPLT2
st.h $2, 0x6E[$1]        ;JPLT3
st.h $0, 0x70[$1]        ;BKCOL

If everything's all right you will see you 3D Box in the Virtual Boy.

prog002.gif (16742 bytes)

In future references we'll talk about palletes, objects, animation stuff, special fx, using pad, using interrupts and other things about programming the Virtual Boy. Thanks to David Tucker and it's page for provides me the needed documentation of this reference.

Any comment? Write us: virtuale98@yahoo.com

The Virtual Boy and Nintendo logos are trademarks of Nintendo Co. Ltd.