Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!sun-barr!newstop!texsun!letni!sneaky!merch!spudge!johnm From: johnm@spudge.UUCP (John Munsch) Newsgroups: comp.sys.amiga Subject: Re: 4096 colors in HIRES Summary: Similarity to Atari ST Spectrum Message-ID: <1786@spudge.UUCP> Date: 6 Jul 89 19:47:15 GMT References: <20069@cup.portal.com> <409@xdos.UUCP> <20112@cup.portal.com> Reply-To: johnm@spudge.UUCP (John Munsch) Distribution: usa Organization: Friends of Guru Bob Lines: 242 I knew those months when I owned an ST would come in handy for something :-) Basically, it sounds to me like you are trying to rebuild the system that the ST uses to display pictures with more than 16 colors. It appeared first in the program Spectrum 512 and a description of its format and the nature of graphics on the ST follows this... Basically what I think we could get out of it are two things: 1) A simple method for compressing the extra information we need for a graphics screen. For example, if we do things similarly to Spectrum then we will have a line of data and then a set of colors that refer to that line. The number of colors will depend on how rapidly we can perform the color register switching during the course of the line being written to the screen. We keep down the amount of space devoted to each lines color table by using a bit map to indicate which colors changed in the table from the previous line to this line. Due to the locality of color that most pictures exhibit this should help tremendously to keep the extra color information within reason. 2) The other thing we can get from Spectrum is a sensible way of describing the new screen format. If you change the color registers in order, first register one, then two, etc. you will have a set of regions that each color covers. For instance, let's say that you can change the color in each register exactly three times while a scan line is being drawn. Then the number of colors on a given scan line is 48. Each color also has a certain area of the scan line it covers, like so... 012345678901234567890123456789012345678901234567 Scan line pixel # 000000000011111111112222222222333333333344444444 Reg 1 = Color 1 xxxxxxxx Reg 2 = Color 2 xxxxxxxxxxxxxxx . . . Reg 1 = Color 17 xxxxxxxxxxxxxxx Reg 2 = Color 18 xxxxxxxxxxxxxxxx . . . Where the x's represent the pixels where that color is available. By doing things this way we also don't have to give up using intuition altogether. If all the colors for a given register are set to the same color all the way down the screen (i.e. Colors 1, 17, 33 are set to black on every line) and that is done for the first four registers then you will have sacrificed some colors on every line but you will still be able to draw windows, menus, etc. and have them look normal. /* End of my $.02 */ Note: All of the above assumes that the copper will let you change the R,G,B of a given register all in one swoop rather than one component at a time like HAM mode. If that isn't possible and we are stuck with fringing around the places where colors switch then I have to say, don't waste your time. The fringing in HAM mode makes it a bitch to use and the few people who seem to have come up with good algorithms for working around it (like Digi-tek) don't seem inclined to share them with the rest of us. John Munsch =============================ST Graphics/Spectrum============================= The following is a description that I wrote (a long time ago) of the ST's graphics and the Spectrum format documentaion that Antic software distributes. The part with the >'s is mine. >Color: Color on the ST is handled in the same way as on a lot of micros >currently. They lack the memory necessary to show all the colors available >because you would need to store a large number of bits for each pixel in order >to keep track of its color. For example, the Atari has 512 colors available, >if these were to all be available simultaneously then you would need > 320 * 200 * 9 bits (screen resolution * number of bits needed) > (to store numbers from 0-511) > = 72K for a graphics screen! >Instead, the ST (and others) use color registers, 16 of them in the Atari's >case. Each register is given a color value from the 512 available and then >each pixel need only store four bits to refer to the color register that >contains the color for that pixel. Even though this can be a real hinderance >(16 colors on a screen isn't much) it does allow for tricks like color >cycling (changing the colors in the registers so that parts of the picture >change color instantly). > >The colors that are available on the ST are stored in the color registers >(and also in most files) as follows: > A two byte word: 0000 0 111 0 111 0 111 > ^^^ ^^^ ^^^ Three bits specifying a blue > | | intensity from 0-7 > | --- Three bits specifying a green intensity > | from 0-7 > --- Three bits specifying a red intensity from 0-7 > The 0 bits are just wasted bits... > 8 levels of red * 8 of green * 8 of blue = 512 colors > >Resolution: There are 3 resolutions on the Atari ST (not counting European PAL >mode). They are: > 320 x 200 (with all 16 palette registers used) <- The most common > 640 x 200 (with the first 4 palette registers used) > 640 x 400 (monochrome) >You'll note that what they have done is cut down the number of bits needed to >specify colors per pixel as the resolution increased. The effect of this was >to keep the amount of memory used by the screen buffer constant across all >resolutions. > >Pixel organization: Once you know the above then all you need to know is >exactly how pixels are stored in the 32K devoted to the screen on a ST. >I'll tackle the easiest first, monochrome. Because each pixel needs only 1 >bit to store its color, the pixels are just stored in order reading from left >to right, one line at a time. The first bit in the first byte corresponds to >the pixel in the upper left corner, the next bit to the pixel just to the >right of it, etc. > >Unfortunately, the storage in the color modes is not so simple. In fact, I >have seen conflicting information on exactly how pixels ARE stored in the >color modes. What I'm about to give you is the version that I have seen most >often and believe to be correct (I have never written directly to video >memory myself so I can't say for sure). Rather than storing the 4 bits per >pixel contiguously in the color modes (i.e. 11112222 33334444 = the first four >pixels color info as on an IBM) the ST stores pixels in separate "planes" for >high speed access by the video chips. The way this works is like this: > Two byte words: 12345678 9ABCDEFG 12345678 9ABCDEFG > 12345678 9ABCDEFG 12345678 9ABCDEFG Low resolution > > or 12345678 9ABCDEFG 12345678 9ABCDEFG Med resolution >The first byte contains the leftmost bit for pixels 1 through 8, the next >byte the for pixels 9 through 16. Thus, to get the colors for sixteen pixels >in low resolution mode you would need to read in 4 two byte words, the color >for the first pixels would be in the marked bit positions: > 12345678 9ABCDEFG 12345678 9ABCDEFG 12345678 9ABCDEFG 12345678 9ABCDEFG > ^ ^ ^ ^ > | | | | > ------------------------------------------------------ > These bits when combined together give the color register to use > for pixel one. The ones next to them for pixel two, etc. > >For medium resolution the setup is identical except that you only need to deal >with two bits per pixel so you only need to read in 2 two byte words at a time >in order to get the info for 16 pixels. SPECTRUM 512 Picture File Format There're two kinds of Spectrum files: uncompressed (.SPU) and compressed (.SPC). The .SPU file is always 51104 bytes long and consists of two parts: first the bit map (32000 bytes) and then the color map (19104 bytes). Because SPECTRUM 512 cannot display the topmost raster line, you have 199 lines instead of 200. For that reason, the top line in the bit map (the first 160 bytes of the file) contains no useful information and you should simply ignore it (SPECTRUM 512 fills it with zeros). Otherwise the bit map has the usual meaning -- low res, 4 planes, 160 bytes per raster line, giving each pixel a certain color number from 0 to 15. When you want to determine the color of any particular pixel in the .SPU file, you should first find it's color number (using Get Pixel $A002 from A-line, for example; or your own routine). To find the actual color of the pixel, look at the color map portion of the file. It consists of 199 blocks, one 96-byte block per raster line (no dummy top line here!). Each block contains 48 word color values in the usual ST format (00000rrr0ggg0bbb, r=red, g=green, b=blue). You will find the block you need for your particular pixel at the address (Y-1)*96 from the start of the color map, where Y is the Y coordinate of your pixel, 1<=Y<=199. Finding which of the 48 colors in the block is the color of your pixel is a little trickier. To do that you'll need the color number that you found from the bit map and the X coordinate of your pixel. First, multiply the color number by 10. If the color number is even, add 1 to the result; if it's odd, subtract 5. Let's call the resulting number X1. Now, if X is less then X1, leave the color number as it is; if X is more or equal X1 but less then X1+160, add 16 to the color number; and if X is more or equal X1+160, then add 32 to the color number. This adjusted color number (it could be anything from 0 to 47) is the solution to our problem! It shows which of the 48 color values in the block corresponds to your particular pixel. An example: X=139 and the color number is 3. Multiply by 10: 3*10=30. Subtract 5 (because 3 is odd): X1=30-5=25. Okay, 139 is more than 25, but less than 185 (25+160). So, we add 16 to the color number and the result is 19. That pixel's color will be found in the word number 19 of the block (word count starts at 0). .SPC files consist of 3 parts: 12-byte header, compressed bit map and compressed color map. Here's the header layout: word $5350 ("SP") word 0 for future enhancements <>0 means there're additional records in the file, following the compressed color map long length of the bit map long length of the color map Bit map compression is a slightly modified RLE. Each record consists of a header byte followed by one or more data bytes. A positive header ( 0<=n<=127 ) means copy the next n+1 bytes literally, a negative ( -128<=n<=-1 ) - copy the next byte -n+2 times (minimum 3; the encoder does not compress if there're just 2 equal bytes in a row). First goes bit plane #0, all scan lines from 1 (not 0!) to 199, without breaks at the ends of scan lines (only at the end of the last line), then bit planes #1,2 and 3. Terminate decompression when the number of bytes extracted reaches 31840 (4 bit planes x 199 lines x 40 bytes per line). The length of the compressed bit map is always even, so there might be one filler byte at the end of it. If you convert an .SPC file to .SPU to display it on the 512-color screen, fill scan line #0 with zeros (first 160 bytes of the .SPU file) to give it the same color as the top screen margin. In the color map each short 16-word block is compressed separately (there're 3 of them in each scan line, 597 altogether). The compressed record for each short block starts with the bit vector (1 word) indicating which of the 16 color slots are used, followed by the color values themselves (each is a word). For instance, $000A,$0707, $0777 should be expanded into 0,$0707,0,$0777, twelve zeros ($000A = %0000000000001010, meaning only colors #1 and 3 are used). Unused color slots should always be filled with zeros. Color #15 is never used in a finished Spectrum picture, so bit #15 of the bit vector must always be 0. Color #0 is always used (as a background) and it's always black. Since it makes no sense to have this extra 0 in every compressed record, bit #0 of the bit vector is always cleared, indicating to the decoder to fill slot #0 with 0. The number of color values following the bit vector in the compressed record is equal to the number of 1's in the bit vector. If the above compression rules are observed the length of the compressed bit map will never be greater than 32092 bytes, and the length of the compressed color map will never be greater than 17910 bytes. Spectrum rejects SPC files that exceed these size limits.