============================ Palette reduction tutorial ============================ :Author: Grzegorz Adam Hankiewicz :Contact: gradha@argon.sabren.com :Date: $Date: 2003/10/19 18:27:04 $ :Version: $Revision: 1.6 $ :Web site: http://gradha.sdf-eu.org/palopt/ :Copyright: This document has been placed in the public domain. .. contents:: .. _Allegro: http://alleg.sourceforge.net/ .. _Smacker: http://www.smacker.com/ .. _Fixpal: http://www.step.sk/marian/fixpal.htm Introduction ============ The first version of this document was written the 18th of November of 1998. At that point in time, I had recently written my second big (and unluckily to date, last) Allegro_ game Wotan, which used a hell lot of rendered graphics. I wanted to share my gained experience with palette reduction with the Allegro_ community, and thus wrote that document. This explains why the proposed method is DOS oriented, which is basically what I had. Since that version I have received a few emails either with corrections or questions about the process. However, I never found the time to update the document. Now, five years later it all looks like prehistory to me. Of course the method is still valid if you have a DOS machine with all the mentioned tools. Today there are more cross platform tools which can help you to get the wanted result. But is it really necessary? The gaming industry has clearly shifted to truecolor three-dimensional games, where palette reduction is practically irrelevant and the final screen the user gets is a result of several layers of filters and special effects. When palette reduction is done, it is done per texture rather than per game level, and this means that even crappy program can reduce the graphic to 8 bit without noticeable degradation. Even two dimensional games tend to favor truecolor graphics, because with today's CPU power they aren't that slow to move around in high resolution animations. In short, color palette reduction is an art which has entered **history**. I can't, however, fail to acknowledge the people who have contacted me. Instead of writing an updated version, I will keep the original nearly intact and mention here the changes I have been suggested by Anthony Alvarade and Ivan Zilotti Alencar. Both Anthony and Ivan state that the command ``ls`` is not necessary to generate the ``smack.lst`` file as I propose. Anthony's solution is:: dir *.pcx /b > smack.lst ...where the ``/b`` parameter tells dir to use bare format. Ivan's solution is very similar, though I don't know what the ``/aa`` switch does:: dir /aa /b *.pcx > smack.lst Finally, Anthony was confused with the use of the Smacker_ tool, for the simple reason that the current Smacker_ website offers by default the Bink tool, which is a next generation truecolor video codec and has Smacker_ integrated, but possibly with a different command line interface which doesn't work with this tutorial. Ignore Bink (for the matter of this tutorial, that is) and find a place where you can download the *old Smacker_ tools*, which produce only 8 bit palettes or videos. If you would like to improve this document, please do so, you don't even need to contact me, this is public domain. Things which would be worth doing are updating the Fixpal_ instructions to the newer versions (as of writing this 2.9 compared to 2.1 described in my original text) and update the example build system to work cross platform, much like Allegro_ does. It would be nice if the Smacker_ guys were to release the algorithm they use for palette reduction. As far as I can see, they won't loose anything doing that, because you can already use their program for free. It would mean, however, that this part of their tool could be ported to machines other than Windows. Finally, this version of the text uses reStructuredText (that's what the weird markup in the text version is for). See http://docutils.sourceforge.net/ The original introduction ========================= Draft 2. August 2003. Welcome. This little tutorial should show you how to make your 24-bit wonderful graphics still look wonderful in a palleted PC game using Allegro_. I assume you already know how to use Allegro_ and it's palettes and bitmaps. This tutorial is aimed at newbies and was written quite in a hurry. If you don't understand something, or you can't get my method to work, please email me, I may have forgotten to write some explanation. The problem =========== As you have probably experienced, 8 bit resolutions allow you the *great* variety of 256 simultaneous colors. That's quite enough, in my opinion, but when you want to mix your rendered ship with photo-realistic graphics, colors go and have a party while you slam your head against a wall asking why. Scanned pictures are truecolor images, and they don't get very well with 8 bit games, because you have to reduce their color to 8 bits. This usually means trading off quality. Thanks to color reduction programs, this doesn't have to be the case for a single image, but it's a true pain to do for a set of hundreds of files. As Shawn Hargreaves pointed on the Allegro_ mailing list: "*Good color reduction is more of an art form than just a technical algorithm*", and I absolutely agree. My first advice is that although my method has worked excellently with my graphics, it may mess yours, so don't take this tutorial as the only possible solution. You should experience yourself, try other programs, etc... You may also share your knowledge with us :-) But enough talk, let's get to the point. I will be using two freeware programs to reduce the colors: Fixpal_ and Smacker_. Fixpal_ is a handy tool, it can do the color reduction very quickly, and can be used with batch files to convert so many pictures as you want. At the moment of writing this I have version 2.1, which I got from http://www.step.sk/marian/fixpal.htm. However Fixpal_ is not so good when it comes to reduce the palette of more than hundreds, even thousands of graphic files, and that's why I help myself with Smacker_. Smacker_ is originally a movie compressor software, which can reduce AVI and FLC files to compression ratios like mpg files. It also has other features, and one of them is that it can create an optimized palette for a bunch of graphic files. Get this program from http://www.smacker.com/. You will notice that you have to pay, but only if you want to use the ``.smk`` generated movies, so I guess we are OK using it for free palette reduction. Fixpal ====== First we will learn how to do the basic stuff with one program to later mix it with Smacker_. Fixpal_ comes with a simple documentation file which is worth reading, but it's so easy to use that typing Fixpal_ at the prompt will give you a help screen about the switches it can use. You use Fixpal_ **on** several files. It can find the best palette for them, save it to a file, or apply it on those files. Notice that the last step simply destroys the original palette of the file, so you may want to have the original somewhere safe, and a little but sometimes ugly *feature* is that it cannot read truecolor images, just 8-bit files. Fixpal_'s syntax is: ``fixpal.exe infile [infile [infile]...] [options]`` Of course we can use wildcards (``*.bmp``, ``*.tga``, etc) as ``infile``. Let's explain a little bit those switches: ``-pfilename`` This reads the named files and saves an optimized palette in a separate file. ``-mcol`` This sets the maximum number of colors we want Fixpal_ to use for the optimized palette. It can be useful if we want to do color cycling inside our game and we want the last 10 colors not used by any graphic. ``-tr,g,b`` This allows you to specify the RGB components of your transparent color in case you didn't use black. So if you are using bright pink (maximum red and blue, zero green) you should use ``-t63,0,63``. ``-Tc`` Like ``-t``, but instead of specifying the RGB components of the transparent color, you choose directly the palette color telling it's index. You can't use this switch with ``-t`` at the same time. Example: ``-t23``. ``-ntr,g,b`` In case you need the new files to have a different transparent color, you can specify it's RGB components. Haven't used this in my life, but well, it's there :-) See example of ``-t``. ``-sc`` This is the important switch. It tells Fixpal_ how big is the color tolerance when creating the optimized palette. Usually when the optimized graphics have bad colors, this is the switch we will have to tweak. I like to use ``-s2``, with ``-s3`` graphics start looking *blocky*, or *hand painted*. ``-ifilename`` Instead of allowing Fixpal_ to create the optimized palette, we tell him to use a palette we already have. This is useful when we want to use external palette optimizers, like Smacker_. All in all, a typical command line to reduce the images of a directory would be:: fixpal *.pcx -s2 This will read and modify all PCX files in the actual directory to use an optimized palette with a color tolerance of two. Knowing all this, we will work with a simple directory structure and several batch files to create an automatic update process for our game's graphics. Let's imagine we have the following structure on our hard disk:: projects\ourgame\ projects\ourgame\src projects\ourgame\obj projects\ourgame\dat\ projects\ourgame\graph\ projects\ourgame\graph\level1\ projects\ourgame\graph\level1\original projects\ourgame\graph\level2\ projects\ourgame\graph\level2\original ... projects\ourgame\graph\levelx\ projects\ourgame\graph\levelx\original So you have your game sources in the ``src`` directory, the object files in the ``obj`` directory, your binary is created in the base dir ``ourgame``, your datafiles are in the ``dat`` directory, and the original graphics which are included in the datafiles are inside the ``graph`` subdirectories. You may want to also have ``levelx`` subdirectories inside the ``dat`` directory in case you need several datafiles for each level and you want to use the same name for them. We will start with the first level graphics of our game. The others are left for the reader as an exercise (I always wanted to write that! :-). Put your original graphic files inside ``graph\level1\original``. These files **have** to be 8-bit graphics, and as a convention to ease our process they will have the extension ``.pcx``. Now we create the ``update.bat`` file in ``graph\level1\``:: copy original\*.pcx /Y fixpal *.pcx -s2 -ppalette.bmp fixpal *.pcx -ipalette.bmp To create the datafile containing all these graphics and the palette, go to ``ourgame\`` and type:: dat -a dat\data.dat graph\level1\*.pcx -c2 -type BMP dat -a dat\data.dat graph\level1\palette.bmp -type PAL This will create the file ``data.dat``, with all the graphics found inside ``graph\level1`` and compress them with global compression. Later it will add ``palette.bmp`` as a palette object rather than a bitmap object. Here you may find useful to name all your enemy graphics ``enemyxxx.pcx``, so you can easily include them in a separate datafile. Later, if you run the ``update.bat`` file again, you can run ``dat -u data.dat`` inside ``ourgame\dat``, and the dat tool will update all the graphics and the optimized palette. If you want to add new files to the datafile, you will have to use again that ``dat -a ... line``. Only the first line. This process will not create a header file for the datafile. This is OK if you like accessing the objects of the datafiles by name (it's also more flexible, I recommend it), but if you want a header file for easy programming, you will also want to have specific names like GOOD_PLAYER_SHIP rather than SHIP02_PCX, so load the datafile with the grabber, change the names with Ctrl+N and save the datafile after specifying a header file. **Note**: the update command will still work with this datafile, and if I recall correctly you still can add files with ``-a`` and the wildcard. The files which already exists should just get updated, but I don't remember if their object name will change. Try and see. Smacker ======= So after you are used to this, you start doing it for your +1000 graphic directory, and you find that your player ship starts using the background palette colors rather than its own colors, simply because Fixpal_ creates the optimized palette according to the most used colors. Smacker_ fixes this in a better way, and I may say that as for now it's the best color reduction program I've seen. No more your player will be *masked* with background colors. After getting Smacker_, you also need to get the DJGPP's ``filxxx.zip`` fileutils package. Why? It includes a better ``dir`` command which we will use to create file lists: ``ls``. Copy ``smackc.exe`` to your path, go to DOS and run it from any directory. It will tell you it needs some .DLL files. OK, so go on and copy these to the ``windows\system`` directory. Repeat this until Smacker_ doesn't complain for missing .DLLs. Smacker_ has a way big variety of switches, and it has an extensive documentation and help system (like Allegro_), so you are on your own to find what each command does. I will explain only the ones we are going to use. This will be our command line: smackc infile.pcx palette.bmp /E1 /P1 /O /&smack.lst /# ``infile.pcx`` is just one file from all those in the directory. ``palette.bmp`` is the same output graphic with the optimized palette. ``/E1`` Specifies the ending frame. Do you remember this was a movie generator? Well, so we are cheating it, we are telling it to read the list of files and generate a movie of one frame (one image). ``/P1`` Create a best-case palette. ``/O`` Automatically overwrite the output file. ``/&smack.lst`` Specifies a file list with all the graphic files which should be processed when creating the new palette. ``smack.lst`` is an editable text file, with a graphic file per line. ``/#`` Exit from the program once it's done with the palette reduction. This a mere switch to prevent the program from waiting until we press the ``Done`` button after the conversion. It's useful for batch processing. OK. So now we create a ``smack.bat`` file in the directory ``graph\level1\original``:: ls *.pcx > smack.lst smackc infile.pcx palette.bmp /E1 /P1 /O /&smack.lst /# exit We first use ``ls` to list all PCX file`s and redirect the screen output to the ``smack.lst`` file. We could not have used dir, since it adds those date and other text strings Smacker_ would cough at (see note about this in `Introduction`_). ``infile.pcx`` can be any graphic we have there, I recommend you choosing a small one. The last exit command is there because I usually run the ``smack.bat`` file from Windows and use the multitask to write emails or whatever. This happens because Smacker_ is waaaaaaaay slow creating the palette, but you can bet for sure that it will do a great job. If you like, instead of exit, you can make this:: cd .. call update.bat But take care, we first have to update the ``update.bat`` file to keep Fixpal_ from overwriting our *smacked* palette. The new ``update.bat`` file would be:: copy original\*.pcx /Y copy original\*.bmp /Y Fixpal_ *.pcx *.bmp -ioriginal/palette.bmp From here on, the process of creating/updating the datafile stays the same. Now, hopefully your graphics will look right. Do you need to re-create the palette each time? =============================================== When adding new files to the original directory, it may happen that they can be optimized with the old palette, so you won't have to go through the slow process of creating a best-case palette again. To try this, copy your new files both to ``levelx\`` and ``levelx\original\``, and manually run the command ``fixpal whatever -s2 -ioriginal/palette.bmp``. If the final files are good to your taste, use them, if not, you will have to re-run the ``smack.bat`` file. The end ======= And that's the whole *magic*. If you have problems, something is unclear or wrong (which is worse), drop me an email. I've put a practical example at http://gradha.sdf-eu.org/palopt/palopt.zip, which has six different images in it and some batch files which convert them to one palette. The zip file is about 167 Kb. Enjoy!