Message-ID: From: Shawn Hargreaves To: djgpp AT delorie DOT com Subject: Re: ALLEGRO: Fast Palette Changing Date: Tue, 18 Jan 2000 17:17:39 -0000 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2650.21) Content-Type: text/plain; charset="iso-8859-1" Reply-To: djgpp AT delorie DOT com Night Walker writes: > I must switch between palette tables quite fast: i must draw 8bpp > RLE_SPRITE on a truecolor screen, and each sprite has different > palette. No can do, sorry: RLE sprites don't support mixing of color depths. See the "converting between color formats" section of the Allegro docs for details of which runtime conversions are supported. Short version: blit() and draw_sprite() are the only routines which support 8 bpp -> truecolor. > I messed around with Allegro SRC but I found set_pallete() quite > confusing. It's a complicated system, but here's a quick rundown: set_palette() is in fact just a wrapper for set_palette_range(), which lives in src/gfx.c. This does several things: - copies your new color values into _current_palette. - if running in a truecolor mode, fills the palette_color array with the new palette colors, after converting them into whatever pixel format is being used by the current screen mode. - sets the _current_palette_changed bitmask flags to indicate that all color depths other than the currently selected one are now dirty. - if the graphics driver wants to know about such things (ie. you are running in a 256 color mode), tells it to update the video hardware with the new colors. When you come to convert images from a 256 color format onto a truecolor destination, Allegro uses a table of preconverted color values, to avoid having to repeat this conversion for every pixel. If your truecolor destination is the same color depth as the current display mode, it can use the existing table that was created by set_palette_range() (in the palette_color array, which is in fact just a pointer to palette_color15, palette_color16, or whatever else you are currently using). If you try to draw onto some other format destination, though, no table will yet exist: this is detected by noticing that the _current_palette_changed bitmask flag for that depth is clear, after which a suitable table is created (this is handled by the palette_expansion_table() function in gfx.c). In other words, changing palettes is quite expensive, involving multiple copying of the data and conversion into at least one different pixel format. It is well optimised for expanding 256 color graphics onto truecolor destinations, but not so well for rapid changing of the palette. This may not be too bad in practice, though: there are only 256 colors to be changed, after all, so run some profiles and see how much time this takes up. Depending how many sprites you are drawing, you might well not notice the palette changing overhead at all... > Passing entire arrays (the PALLETE type) by value as function > parameters is not slow/unefficent? or are they automatically > passed by reference? PALETTE is defined to be an array of 256 RGB structures, and C always passes arrays by reference. > There is a way to simply redirect a pointer to a PALLETE table, > thus changing palette with only an assignement "="? Not directly in Allegro, because the drawing code doesn't use the PALETTE contents directly, but rather a preconverted version of it. But you could roll your own version of this if you do turn out to need it: create your own tables of preconverted colors to go in palette_color15[], palette_color16[], etc, and then just memcpy() these directly into the appropriate table when you want to change what colors are used in the conversion. Some copying is still required because these are static tables rather than pointers, but it's only 1k of data to move. > This will let me use blender maps/funx for transparency? Blender maps are a whole different issue to palette expansions, and work entirely differently in 8 bit vs. truecolor modes. The extrans and exblend example programs show how to do this. Shawn Hargreaves.