The OMF pilot images are 54 pixels high, and appear to be limited to 71 pixels in width. The actual width of each row of the image is variable. The width of each row, as well as its offset from the left margin is coded within the image and followed by the actual image data for that row. If the offset for any row is 0 (i.e. it starts immediately at the left margin) it may be encoded in a shorthand method. In addition, there are special coding sequences for runs of transparent pixels that may be intermixed within a row of opaque pixels The final complication is that only certain color values are appropriate for use in the pilot images, other color indexes may change or fade depending on the color of your robot and the scene you are in within the game. In general, the image contains 54 rows (unless you have runs of transparent pixels), each encoded as follows: Header, Data, repeat as necessary... The header data is as follows for normal runs: key, offset*4, width*4+1 So for a line like this (periods include transparent pixels): ....XXXXXXX... the header would be: 02 00 10 00 1D 00 ^ ^ ^ | | width - 7 times 4 is 28 plus 1 is 29, which is 1D hex | offset - 4 times 4 is 16, which is 10 hex key - starts out as 0x02 and increases by 4 The header is followed by raw pixel data for that line. The image you intend to use must conform to these limitations: 1. Does not exceed 70x54 pixels in size (The width of the image is limited to 70 here rather than 71 to simplify the example code below, see the "further exploration" section for explanation.) 2. Uses only the colors that are used by the original pilot images Maybe the easiest way to accomplish this is do a screen capture of OMF and then load it into your paint program so that you can use the same palette and figure out the valid colors - they're mainly within the last 64 palette entries. You need to be able to get this artwork into an array within your conversion program in its raw form. An appropriate storage location might be: unsigned char image[54][70]; The next portion of this discussion is presented as heavily-commented C code. This is not an optimal coding method (nor even a good method) but it is sufficiently wordy to convey these ideas. Also, this program is not capable of converting pictures that contain runs of transparent pixels (e.g. XXX XX XXXX). ConvertImage() { int x, y, i; // a plethora of index variables int offset; // blank space on left margin int width; // length of opaque pixel run int found_non_zero; // indicates start of opaque run unsigned char key=0x02; // code to indicate start of run unsigned char c; // temp variable for pixel data unsigned char linebuffer[70]; // store the opaque pixels here FILE *out; // handle for output to file out=fopen("filename.ext","wb"); // open output file binary mode for (y=0; y<54; y++) // process each row { // set up variables for this row: offset = 1; // we won't deal with offset=0 width = 0; // no pixels have been save yet found_non_zero = 0; // haven't found first opaque pixel for (x=0; x<70; x++) // process each column { c = image[y][x]; // simply read the pixel data if (c == 0) // if pixel is transparent, then... { if (!found_non_zero) // skip transparent til first opaque offset++; // move the left margin over one } else // otherwise it's opaque... { found_non_zero = 1; // indicate found opaque (overkill!) linebuffer[width]=c; // save the opaque pixel width++; // increase width of opaque run } } // done with all columns, save // 6-byte header: offset != 0 fputc(key, out); // indicates start of run fputc(0, out); // hi byte of int fputc(offset*4, out); // offset 4 times too big fputc(0, out); // hi byte of int fputc((1+4*width)&0xff, out); // width 4 times too big plus 1 fputc((1+4*width)>>8, out); // hi byte of int for (i=0; i (Hint: a while loop to do transparent, followed by another for opaque, using a pointer to access the image array) The special case of left margin = 0 is dealt with by the fact that offsets are always even, while widths are always odd. If the int following the key value is odd then that means that offset was not encoded, thus left margin=0. So, run header is reduced from 6 to 4 bytes. Add this logic to the above routine and you can do 0 left margin images. (IOW, test for offset=0, then don't write offset bytes) To include runs of transparent pixels, you must use a slightly different method. The key value is the new offset*4, the offset is width*4+1, and there is no width (everything is shifted left). Here is a diagram to illustrate. Suppose your line was this: ...XXXXXX..XX... You would use the normal method for the first 6 opaque pixels. The header for the next 2 opaque pixels is as follows: 2C 00 09 00 Followed by pixel data. The entire line would be: 02 00 0C 00 19 00 {data for 6 pixels} 2C 00 09 00 {data for 2 pixels} So, in effect, it's like having more than one line per row. If you have any questions, you can contact the author or the editor for more information (addresses at end of document). Originally by: Dave Bollinger (CIS# 72510,3623) Revised and edited by: Craig Boston (CIS# 74442,2200)