Talk:DDiCI Graphics format

From ModdingWiki
Jump to navigation Jump to search

xGAPICS Format

File Header (first 48 Bytes):

Off Bytes Description

 0    2   Blank
 2    4   Font start
 6    4   Tile start
10    4   Image start
14    4   Sprite start
18    4   Image Entries start
22    4   Sprite Entries start
26    4   Blue Plane start
30    4   Green Plane start
34    4   Red Plane start
38    2   Intensity Plane start
40    2   Font Count
42    2   Tile Count
44    2   Image Count
46    2   Sprite Count

Notes:


All the "start" values need to be multiplied by 16 to get the "real" location.

The header structure is the same for EGA and CGA, but you can ignore all the "Plane start" values read from the CGA file, since CGA doesn't use planes.

Image Entries (16 Bytes each):

Off Bytes Description
 0    2   Width
 2    2   Height
 4    4   Offset
 8    8   Name (0-padded string)

Notes:

The Width value is NOT in Pixels, but rather in Bytes-per-line. So Width * Height gives you the number of bytes that need to be read. In CGA, this is the total amount of bytes for this image. In EGA, this is the number of bytes to be read FROM EACH EGA PLANE, so the actual size of the image (in bytes) is four times that size. The real width of the image (in Pixels) is Width * 8 for EGA or Width * 4 for CGA graphics.

The Offset value doesn't need to be multilpied by 16!


How to convert the RAW data to RGB values for each pixel

First, you need to know some values:

  • Width (Bytes-per-line) and Height (Pixels) of the Image
  • Image Offset
  • "start" location (Font start, Tile start, Image start or Sprite start)
  • for EGA only: Plane distance

Note on Plane distance:

All four EGA planes should have the same size. The distance can be calculated (GreenPlaneStart - BluePlaneStart), for example. The following pseudocode expects the color planes to be ordered from first to last: B-G-R-I.


Converting EGA data

First, you need to create a buffer of (Width * Height * 8) Byte values (one Byte per pixel).

Start by reading the values from the Blue Plane, so scan to position (StartLocation+ImageOffset). The StartLocation is always in the Blue Plane.

FOR i = 0 TO (Width*Height)-1

	read a Byte value (b) from the file //(and proceed to the next Byte if your programming language doesn't do that automatically)

	write ((b / 128) mod 2) to buffer at position (i*8)
	write ((b /  64) mod 2) to buffer at position (i*8 + 1)
	write ((b /  32) mod 2) to buffer at position (i*8 + 2)
	write ((b /  16) mod 2) to buffer at position (i*8 + 3)
	write ((b /   8) mod 2) to buffer at position (i*8 + 4)
	write ((b /   4) mod 2) to buffer at position (i*8 + 5)
	write ((b /   2) mod 2) to buffer at position (i*8 + 6)
	write ((b /   1) mod 2) to buffer at position (i*8 + 7)

NEXT

Now scan to position (StartLocation + PlaneDistance + ImageOffset) to read the Green Plane.

FOR i = 0 TO (Width*Height)-1

	read a Byte value (b) from the file //(and proceed to the next Byte if your programming language doesn't do that automatically)

	add (((b / 128) mod 2) * 2) to buffer at position (i*8)
	add (((b /  64) mod 2) * 2) to buffer at position (i*8 + 1)
	add (((b /  32) mod 2) * 2) to buffer at position (i*8 + 2)
	add (((b /  16) mod 2) * 2) to buffer at position (i*8 + 3)
	add (((b /   8) mod 2) * 2) to buffer at position (i*8 + 4)
	add (((b /   4) mod 2) * 2) to buffer at position (i*8 + 5)
	add (((b /   2) mod 2) * 2) to buffer at position (i*8 + 6)
	add (((b /   1) mod 2) * 2) to buffer at position (i*8 + 7)

NEXT

Now scan to position (StartLocation + 2*PlaneDistance + ImageOffset) to read the Red Plane.

FOR i = 0 TO (Width*Height)-1

	read a Byte value (b) from the file //(and proceed to the next Byte if your programming language doesn't do that automatically)

	add (((b / 128) mod 2) * 4) to buffer at position (i*8)
	add (((b /  64) mod 2) * 4) to buffer at position (i*8 + 1)
	add (((b /  32) mod 2) * 4) to buffer at position (i*8 + 2)
	add (((b /  16) mod 2) * 4) to buffer at position (i*8 + 3)
	add (((b /   8) mod 2) * 4) to buffer at position (i*8 + 4)
	add (((b /   4) mod 2) * 4) to buffer at position (i*8 + 5)
	add (((b /   2) mod 2) * 4) to buffer at position (i*8 + 6)
	add (((b /   1) mod 2) * 4) to buffer at position (i*8 + 7)

NEXT

Now scan to position (StartLocation + 3*PlaneDistance + ImageOffset) to read the Intensity Plane.

FOR i = 0 TO (Width*Height)-1

	read a Byte value (b) from the file //(and proceed to the next Byte if your programming language doesn't do that automatically)

	add (((b / 128) mod 2) * 8) to buffer at position (i*8)
	add (((b /  64) mod 2) * 8) to buffer at position (i*8 + 1)
	add (((b /  32) mod 2) * 8) to buffer at position (i*8 + 2)
	add (((b /  16) mod 2) * 8) to buffer at position (i*8 + 3)
	add (((b /   8) mod 2) * 8) to buffer at position (i*8 + 4)
	add (((b /   4) mod 2) * 8) to buffer at position (i*8 + 5)
	add (((b /   2) mod 2) * 8) to buffer at position (i*8 + 6)
	add (((b /   1) mod 2) * 8) to buffer at position (i*8 + 7)

NEXT

After this is done, you have the color index for every pixel in your buffer. To get the corresponding RGB value, just use the following color table:

Index Name        RGB value (HEX)

0     Black       000000
1     Dark Blue   0000AA
2     Dark Green  00AA00
3     Dark Cyan   00AAAA
4     Dark Red    AA0000
5     Purple      AA00AA
6     Brown       AAAA00
7     Grey        AAAAAA
8     Dark Grey   555555
9     Blue        5555FF
A     Green       55FF55
B     Cyan        55FFFF
C     Red         FF5555
D     Pink        FF55FF
E     Yellow      FFFF55
F     White       FFFFFF


For the sake of completeness here's the pseudocode to create a "Pixmap" from the buffer. We use the WritePixel(x, y, rgb) to add the color information to the "Pixmap".

CreatePixmap (w = Width*8, h = Height)

FOR i = 0 to (Width*Height)-1
	WritePixel(x = i mod w, y = i / w, rgb = ColorTable[Buffer[i]])
NEXT


Converting CGA data

For the CGA data, you don't need a buffer for the color indices. We'll write the pixels as we read the RAW data, using the following color table:

Index Name        RGB value (HEX)

0     Black       000000
1     Cyan        55FFFF
2     Pink        FF55FF
3     White       FFFFFF


CreatePixmap(w = Width*4, h = Height)

Scan to position (StartLocation + ImageOffset)

FOR i = 0 to (Width*Height)-1

	read a Byte value (b) from the file //(and proceed to the next Byte if your programming language doesn't do that automatically)
	
	WritePixel(x = (i mod w)  , y = (i / w), rgb = ColorTable[(b / 64) mod 4])
	WritePixel(x = (i mod w)+1, y = (i / w), rgb = ColorTable[(b / 16) mod 4])
	WritePixel(x = (i mod w)+2, y = (i / w), rgb = ColorTable[(b /  4) mod 4])
	WritePixel(x = (i mod w)+3, y = (i / w), rgb = ColorTable[(b /  1) mod 4])
NEXT

--K1n9 Duk3 14:46, 15 January 2011 (GMT)