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 3The 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