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'.
RLE_SPRITE *rle; BITMAP *bmp; ... /* Create RLE sprite from an existent bitmap. */ rle = get_rle_sprite(bmp); if (!rle) abort_on_error("Couldn't create RLE sprite!"); /* We don't need the bitmap any more.*/ destroy_bitmap(bmp); /* Use the RLE sprite. */ ... /* Destroy it when we don't need it any more. */ destroy_rle_sprite(rle);
Return value: Returns a pointer to the created RLE sprite, or NULL if the RLE sprite could not be created. Remember to free this RLE sprite later to avoid memory leaks.
See also: draw_rle_sprite, destroy_rle_sprite.
See also: get_rle_sprite.
RLE_SPRITE *rle_sprite; ... draw_rle_sprite(screen, rle_sprite, 100, 100);
See also: get_rle_sprite, draw_sprite, draw_compiled_sprite, draw_trans_rle_sprite, draw_lit_rle_sprite, bitmap_mask_color.
/* 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);
See also: draw_rle_sprite, draw_lit_rle_sprite, draw_trans_sprite, color_map, set_trans_blender, set_alpha_blender, bitmap_mask_color.
/* 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, 64);
See also: draw_rle_sprite, draw_trans_rle_sprite, draw_lit_sprite, color_map, set_trans_blender, bitmap_mask_color.