Appendix C: Library file formats

The palette data format

The palette parameter used by DQBsetPal, DQBgetPal, DQBfadeIn, DQBloadLayer

and DQBsaveLayer must be a string of 768 character. This string holds the
hues data for each of the 256 colors: three bytes per color, representing
the red, green and blue intensities ranging 0-63. So if you want to know the
green intesity of color 45 of given palette stored into the Pal string, here's
the simple code:

green = ASC(MID$(Pal, ((45 * 3) + 2), 1))
                        |         |
                        |          \ Change this with 1,2 or 3 to know the
                        |            red, green and blue hues
                         \ This is the color number; let's multiply it by 3
The mouse cursor data format

When calling DQBsetMouseShape, you must pass a string of 64 characters as the

third parameter; this represents the cursor shape data.
Each cursor shape is a 16x16 pixels bitmap, composed of two masks of bits: the
so called "screen mask" and "cursor mask". The data is stored so that the
first 32 bytes of our string are the screen mask, and the other 32 are the
cursor mask. Two bytes (16 bits) make a cursor line, so we have 64 bytes
to define the two 16x16 pixels masks.
The screen mask specifies what part of the cursor is to be the shape and what
part is to be the background: a 0 means the background, a 1 means the shape.
The cursor mask tells what color to use into the mask. By combining these two
masks, the cursor is drawn onto the screen. Here are the combinations, with
their results on the screen:

Bit on screen mask            Bit on cursor mask          Pixel drawn
0                             0                           Black
0                             1                           White
1                             0                           Transparent
1                             1                           Inverted

I know it's hard, but it's even harder to explain... I'll try to make an
example. Let's look at the data below: this represents the default DirectQB
mouse cursor (the arrow).

&HFF,&H3F,&HFF,&H1F,&HFF,&H0F,&HFF,&H07     \
&HFF,&H03,&HFF,&H01,&HFF,&H00,&H7F,&H00      |
&H3F,&H00,&H7F,&H00,&HFF,&H0F,&HFF,&HBF      |--- Screen mask
&HFF,&HFF,&HFF,&HFF,&HFF,&HFF,&HFF,&HFF     /
&H00,&H00,&H00,&H40,&H00,&H60,&H00,&H70     \
&H00,&H78,&H00,&H7C,&H00,&H7E,&H00,&H7F      |
&H80,&H7F,&H00,&H70,&H00,&H40,&H00,&H00      |--- Cursor mask
&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00     /

Let's examine the bytes of our masks: just remember that of the two bytes that
make a cursor line, the first represents the last 8 pixels, and the second the
first 8.

Screen mask                             Cursor mask

&HFF,&H3F =   0011111111111111          &H00,&H00 =   0000000000000000
&HFF,&H1F =   0001111111111111          &H00,&H40 =   0100000000000000
&HFF,&H0F =   0000111111111111          &H00,&H60 =   0110000000000000
&HFF,&H07 =   0000011111111111          &H00,&H70 =   0111000000000000
&HFF,&H03 =   0000001111111111          &H00,&H78 =   0111100000000000
&HFF,&H01 =   0000000111111111          &H00,&H7C =   0111110000000000
&HFF,&H00 =   0000000011111111          &H00,&H7E =   0111111000000000
&H7F,&H00 =   0000000001111111          &H00,&H7F =   0111111100000000
&H3F,&H00 =   0000000000111111          &H80,&H7F =   0111111110000000
&H7F,&H00 =   0000000001111111          &H00,&H70 =   0111000000000000
&HFF,&H0F =   0000111111111111          &H00,&H40 =   0100000000000000
&HFF,&HBF =   1011111111111111          &H00,&H00 =   0000000000000000
&HFF,&HFF =   1111111111111111          &H00,&H00 =   0000000000000000
&HFF,&HFF =   1111111111111111          &H00,&H00 =   0000000000000000
&HFF,&HFF =   1111111111111111          &H00,&H00 =   0000000000000000
&HFF,&HFF =   1111111111111111          &H00,&H00 =   0000000000000000

The hotspot is passed to DQBsetMouseShape in pixel units. A hotspot of (0,0)
represents the upper-left corner of the cursor bitmap; the hotspot coordinates
can range from (-16,-16) to (16,16).

Now I know that it's not so easy to create a mouse cursor, so I made the
CUREDIT program, which is a cursor editor. You can use it to create and save
your cursors as DATA statements as well as into a binary file as strings of
64 characters.
The font data format

A font is contained into a string of 2305 characters. Each font holds the

graphical data for 256 characters (8 bytes per each character, so we have
8*256=the first 2048 bytes), the width in pixels of each of them (next 256
bytes, 1 byte for each character), and the height of all the characters (last
byte).
Each bit of the 8 bytes of graphical data of a character represents the state
of a pixel: 1 means the pixel is on, 0 that the pixel is off.
So let's examine the data for the following character:

00010000 =  &H10
00111000 =  &H38
01101100 =  &H6C
01101100 =  &H6C
11000110 =  &HC6
11111110 =  &HFE
11000110 =  &HC6
00000000 =  &H00

This would obviously represent an 'A'...
The pixels off will be transparent if in transparent text mode, otherwise it
will be set to the current text background color set by DQBsetTextBackCol.

Old fixed-sized fonts are no longer supported by DQBsetFont.
Use DirectQB Tools to create your own fonts; old fonts can be still loaded
from this utility, so you can use it to convert them into the new format.
The blender map data format

Creating a blender map is often a slow process. For this reason, I've coded

the DQBloadBMap and DQBsaveBMap functions; here follows the file format
description:

Offset  Length  Description
0       4       Blender map file format ID string; must be "BMap"
4       1       First mapped foreground color
5       1       Last mapped foreground color
6       256*n   n blender map chunks, where n is the total number of mapped
                foreground colors

A blender map chunk is a 256 bytes chunk that contains all the 256 possible
background color combination for a foreground color.
The datafile file format

DirectQB datafiles are a little complex structures. The first 1032 bytes are

the header, here explained:

Offset  Length  Description
0       7       Datafile file format ID string: must be "DQBPaCk"
7       1       Number of used packets
8       1024    256 packet offset info chunks; each of these is a 4 bytes
                long integer, specifying the absolute address of the packet
                data into the file

Next the packets data follow. Each packet type has its own small header, and
all them are encoded and encrypted using the same algorithm: basically it's
a simple RLE-based engine, where every time a byte has to be repeated, a
255 is the marker byte, next follow the number of repetitions (up to 255), and
the byte to repeat. If a single byte 255 has to decoded, the encoded stream
would look like "255,1,255"; that's all. About encryption, here's how it
works: before RLE-decoding the data stream, the password bytes are
"subtracted" from the encoded data, and this is repeated beginning with
subtracting the first password character to the first packet byte, and then
until the end of the packet, wrapping the password. Needless to say, when
no password is specified, this process has no effect. The password is not
stored into the datafile itself, so it's up to you to remind it, otherwise
you may loose your data! I know this is also a simple algorithm, but it works
quickly and it's hard to decode.
Now, here follows an explanation of the different packets allowed into a
datafile. I refer to them as they should be once decrypted and decoded:

* FONT packet

    Offset  Length  Description
    0       4       Packet ID: must be "FNTþ"
    4       2305    Font data

* IMAGE packet

    Offset  Length  Description
    0       4       Packet ID: must be "IMGþ"
    4       2       Image width in pixels
    6       2       Image height in pixels
    8       ?       Image data

* SOUND packet

    Offset  Length  Description
    0       4       Packet ID: must be "SNDþ"
    4       4       Sound length in bytes
    8       ?       Sample data

* PALETTE packet

    Offset  Length  Description
    0       4       Packet ID: must be "PALþ"
    4       768     Palette data

* BMAP packet

    Offset  Length  Description
    0       4       Packet ID: must be "BMAþ"
    4       1       Number of mapped foreground color
    5       ?       Blender map data

* CURSOR packet

    Offset  Length  Description
    0       4       Packet ID: must be "CURþ"
    4       64      Cursor data

* USER packet

    Offset  Length  Description
    0       4       Packet ID: must be "USRþ"
    4       4       Data length
    8       ?       Any data