RLE sprite routines are implemented in <lua_rle.c>. Header file is: <lua_rle.h>.

A half of RLE sprite routines are ready: get_rle_sprite and draw_rle_sprite.

destroy_rle_sprite is implemented in LuAllegro garbage collection routine.

 

RLE sprites

Because bitmaps can be used in so many different ways, the bitmap structure is quite complicated, and it contains a lot of data. In many situations, though, you will find yourself storing images that are only ever copied to the screen, rather than being drawn onto or used as filling patterns, etc. If this is the case you may be better off storing your images in RLE_SPRITE (read chapter "Structures and types defined by Allegro" for an internal description of the RLE_SPRITE structure) or COMPILED_SPRITE (see next chapter) structures rather than regular bitmaps.

RLE sprites store the image in a simple run-length encoded format, where repeated zero pixels are replaced by a single length count, and strings of non-zero pixels are preceded by a counter giving the length of the solid run. RLE sprites are usually much smaller than normal bitmaps, both because of the run length compression, and because they avoid most of the overhead of the bitmap structure. They are often also faster than normal bitmaps, because rather than having to compare every single pixel with zero to determine whether it should be drawn, it is possible to skip over a whole run of zeros with a single add, or to copy a long run of non-zero pixels with fast string instructions.

Every silver lining has a cloud, though, and in the case of RLE sprites it is a lack of flexibility. You can't draw onto them, and you can't flip them, rotate them, or stretch them. In fact the only thing you can do with them is to blast them onto a bitmap with the draw_rle_sprite() function, which is equivalent to using draw_sprite() with a regular bitmap. You can convert bitmaps into RLE sprites at runtime, or you can create RLE sprite structures in grabber datafiles by making a new object of type 'RLE sprite'.

AL_RLE_SPRITE userdata    allegro.get_rle_sprite(AL_BITMAP userdata bitmap);

Creates an RLE sprite based on the specified bitmap (which must be a memory bitmap userdata). You don't have to remember to destroy rle sprite since Lua has a garbage collection mechanism. Example:
      -- Create RLE sprite from an existent bitmap. */
      rle = get_rle_sprite(bmp);
      
      if (rle==nil) then
         abort_on_error("Couldn't create RLE sprite!")
      end
         
      -- Use the RLE sprite. 
      ...
 
      -- RLE sprite will be destroyed automatically when we don't have any references to it.
      rle=nil;
 
      --We may explicitly call collectgarbage to ensure 
      --that rle sprite is destroyed at the very same moment
      collectgarbage();
 

Return value: Returns an userdata containing created RLE sprite, or nil if the RLE sprite could not be created. 

void destroy_rle_sprite(RLE_SPRITE *sprite);


There is no possibility to call this routine directly. And that is the way it should be. 

This function is implemented as a part of  LuAllegro userdata garbage collection routine: allegrolib__gc.

LuAllegro garbage collection routine is implemented in a separate file <lua_root.c>

This routine is capable of destroying bitmaps, zbuffers, fonts, rle sprites and compiled sprites.

I have tested it carefully to ensure that every sprite or bitmap is destroyed. It works. Here is an implementation:

 

 

//------------------------------------------------------------------------------------------
//--- Garbage collection routine for Allegro userdata --------------------------------------
//------------------------------------------------------------------------------------------
static int allegrolib__gc (lua_State *L) 
{
AUD* ad = (AUD*) lua_touserdata(L, 1);

if (ad) 
   switch(ad->DataType)
   {
   case AL_BITMAP:
      if (ad->DataPtr!=NULL)
         { destroy_bitmap( (BITMAP*) ad->DataPtr); 
           ad->DataPtr=NULL;                      }
      break;

   case AL_ZBUFFER:
      if (ad->DataPtr!=NULL)
         { destroy_zbuffer( (ZBUFFER*) ad->DataPtr); 
           ad->DataPtr=NULL;                      }
      break;

   case AL_FONT:
      if (ad->DataPtr!=NULL)
         { destroy_font( (FONT*) ad->DataPtr); 
           ad->DataPtr=NULL;                      }
      break;

   case AL_RLE_SPRITE:
      if (ad->DataPtr!=NULL)
         { destroy_rle_sprite( (RLE_SPRITE*) ad->DataPtr); 
           ad->DataPtr=NULL;                      }
      break;

   case AL_COMPILED_SPRITE:
      if (ad->DataPtr!=NULL)
         { destroy_compiled_sprite( (COMPILED_SPRITE*) ad->DataPtr); 
           ad->DataPtr=NULL;                      }
      break;
   }

return 0;
}
allegro.draw_rle_sprite(AL_BITMAP bitmap, AL_RLE_SPRITE sprite, x, y);

Draws an RLE sprite onto a bitmap at the specified position. Bitmap parameter is optional and can be nil. When you omit bitmap parameter or pass nil value then screen will be assumed as default bitmap. sprite parameter must be valid AL_RLE_SPRITE userdata. x and y are coordinates, where sprite will appear on a bitmap. 

Example:

 
allegro.draw_rle_sprite(screen, rle_sprite, 100, 100);
 
void draw_trans_rle_sprite(BITMAP *bmp, const RLE_SPRITE *sprite, int x, int y);

Not implemented yet, because I have not implemented color mapping table routines, blender functions and other related stuff.

Translucent version of draw_rle_sprite(). See the description of draw_trans_sprite(). This must only be used after you have set up the color mapping table (for 256-color modes) or blender functions (for truecolor modes). The bitmap and sprite must normally be in the same color depth, but as a special case you can draw 32-bit RGBA format sprites onto any hicolor or truecolor bitmap, as long as you call set_alpha_blender() first. Example:

      /* Some one time initialisation code. */
      COLOR_MAP global_trans_table;
      create_trans_table(&global_trans_table, my_palette,
                         128, 128, 128, NULL);
      ...
      if (get_color_depth() == 8)
         color_map = &global_trans_table;
      else
         set_trans_blender(128, 128, 128, 128);

      draw_trans_rle_sprite(buffer, rle_ghost_sprite, x, y);
 
void draw_lit_rle_sprite(BITMAP *bmp, const RLE_SPRITE *sprite, int x, y, color);

Not implemented yet, because I have not implemented color mapping table routines, blender functions and other related stuff.

Tinted version of draw_rle_sprite(). See the description of draw_lit_sprite(). This must only be used after you have set up the color mapping table (for 256-color modes) or blender functions (for truecolor modes). Example:

      /* Some one time initialisation code. */
      COLOR_MAP global_light_table;
      create_light_table(&global_trans_table, my_palette,
                         10, 10, 60, NULL);
      ...
      if (get_color_depth() == 8)
         color_map = &global_light_table;
      else
         set_trans_blender(40, 40, 255, 255);

      /* Lit the cape with a blueish light. */
      draw_lit_rle_sprite(buffer, rle_colored_cape, x, y);
 

Back to main page