0. WHY PCX files? Because they are a widely available file format and rather simple. You may want to use them for introducing nice graphic images into your games. The official name of the PCX format is ``PC Paintbrush file Format''. 1. An example of using PCX files is the game "Space Jam". We will be using this game to illustrate what we say. --The Space Jam program is in two modules: a main module called game.asm, with graphics routines in graphics.asm. --The standard memory model used is COMPACT, which supports one code segment and multiple data segments. In this case, only two data segments are used. --Images are stored in pcx format. --However, these files are sometimes given the .dat extension. As far as I know, .dat is not a standard name. The .dat and .pcx files with the same name are apparently identical. --The game uses video mode 13h, which has resolution 320x200, and has a color palette of 256 out of 256K (=64^3) colors. --There is a ``double_buffer'' that is 64000 bytes in size. 2. You can learn a lot about pcx files by understanding the routine pcx_load (in graphics module). Basically the pcx file format has three parts: PART 1: The first 128 bytes form the header. See details below. PART 3: The last 769=1+(3x256) bytes defines the color palette. The bytes are ID,R1,G1,B1,R2,G2,B2,R3,... where ID is a special identifier byte and (Ri,Gi,Bi) is the RGB values for the $i$th palette register. See the routine update_color_register (in graphics module) for how this can be used. For some reason, each color component is right-shifted by 2 in this routine. This may have to do with the color depth of the particular .pcx images. PART 2: The main data is stored in this part. Pcx_load assumes that this part represent a 320x200 screen, but that is not true in general. NOTE it is possible for this part NOT to have any compression schemes! (Then each pixel is stored literally). But if it is compressed, then the method used is RUN-LENGTH ENCODING (RLE). Here is a description of the PCX version of RLE: The pixels are grouped as (a) a single pixel, or as (b) a consecutive group of similar valued pixels. Each byte value N that is read is treated as follows: (1) if the byte value is less than 192d (=0C0h) then it represents a single pixel with palette index N. (2) if the byte value is greater than or equal to 192d, then it is the number of pixels whose common palette index is given by the next byte. NOTE: you may want to write a slightly more general version of PCX_LOAD which does not assume the screen size is 320x200. 3. Other useful routines in the graphics module: show_double_buffer -- display the contents of the double_buffer set_palette_register -- set the color of a particular palette register get_palette_register -- get the color of a particular palette register update_color_register -- set the colors of all the palette registers 4. More details about PCX format, taken from p.403, ``Graphics File Formats'', by C. Wayne Brown and Barry J. Shepherd, Manning Pub. Co., Greenwich, CT (1995). HEADER: Byte# DATA Details ===== ==== ======= 1 signature Hex A0 2 version Version 2.5, 2.8, 3.0 and greater, etc 3 compression 1=run-length 4 bits/pixel per color plane 5-6 Xmin Upper left corner 7-8 Ymin upper left corner 9-10 Xmax Lower right corner 11-12 Ymax Lower right corner 13-14 hor.resolution 15-16 ver.resolution 17-74 palette 65 reserved 66 no.of color planes 67-68 bytes/line buffer space needed for decoding 69-70 palette type 1=grayscale, 2=color 71-128 filler(not used) Image Data: Each scan line is encoded separately (run-lengths do not cross scan line boundaries). Palette (769 bytes): Byte 1 is the signature (=0Ch) Bytes 2,3,4 = RGB for palette index 1 Bytes 5,6,7 = RGB for palette index 2 etc PCX run-length scheme: the first 2 bits of each byte is used to distinguish length values from data values. If a data value already has its first 2 bits set, then a length value must be inserted in front of the data (regardless of whether there is any repetition). ALGORITHM: REPEAT: Val = next byte in compressed data stream IF Val < 192, THEN output Val (as literal value) ELSE Count = Val-192 (this strip off the high order 2 bits) Color = next byte in stream output Color, Count number of times. UNTIL the stream is processed. 5. How to view, create and manipulate PCX files. Most graphic image viewers will support pcx formats. For example, MICROSOFT PHOTO EDITOR can used to read and view pcx formats. Another well-known program is XV (unix platform only?). In the following, I will illustrate using MS Phote Editor. If you get access to any one of these software, you can also create and manipulate PCX files. Two simple way to create PCX files are: (a) by converting from another file in some other format. E.g., you may have some .GIF files that you wish to convert to .PCX. Any of these software should be able to do this conversion (first you read the gif file, then you save it in the pcx format!) (b) by scanning in a hard copy image (which you may draw or paint yourself, for instance). To create files that the PCX_LOAD routine can decode properly, you need to make sure that the image is (a) 320x200 pixels in size (b) uses 256 color palette (c) uses run-length encoding IN MS Photo Editor, you can modify (a) by using the resize command. You should also take care to set (b), and when you save your file in the pcx format, make sure you choose the RLE encoding (default is no encoding). You can cut and paste images, do various image transformation effects, etc. 6. Exercise: rewrite pcx_load to load any pcx image into a 64000 size buffer. However, you only assume that the image has 320 pixels per row (but the number of rows may be more or less than 200). If more than 200 rows, you truncate at 200. If less than 200 rows, you fill it up with 0. You should read the header of the pcx file to verify that it has 320 pixels per row (else error). Also use the header to find out how rows of pixels it actually has.