1 /*------------------------------------------------------------------------. 2 | Copyright 2000 Alexandre Duret-Lutz <duret_g@epita.fr> | 3 | | 4 | This file is part of Heroes. | 5 | | 6 | Heroes is free software; you can redistribute it and/or modify it under | 7 | the terms of the GNU General Public License version 2 as published by | 8 | the Free Software Foundation. | 9 | | 10 | Heroes is distributed in the hope that it will be useful, but WITHOUT | 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 13 | for more details. | 14 | | 15 | You should have received a copy of the GNU General Public License along | 16 | with this program; if not, write to the Free Software Foundation, Inc., | 17 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 `------------------------------------------------------------------------*/ 19 20 #ifndef HEROES__SPRITES__H 21 #define HEROES__SPRITES__H 22 23 /*-------------------------------------------------------------------. 24 | This file define an abstraction for sprites, i.e., small blocks of | 25 | pixels that can be pasted in memory (but you knew that). | 26 `-------------------------------------------------------------------*/ 27 28 #include "video.h" 29 30 /* Different kind of sprites, they are not all used yet. These values 31 should be used *internally* by the sprite handling functions. */ 32 enum sprite_kind { 33 S_OPAQUE, /* opaque (yes!) */ 34 S_RLE, /* transparant */ 35 S_RLE_SHADE, /* transparant, using one line of glenz */ 36 S_RLE_ZCOL, /* transparant, using a kind of 37 color-based z-buffer, for explosions */ 38 S_RLE_GLENZ, /* transparant, 39 using uniform glenz for the rest */ 40 S_RLE_UNIC_SHADE, /* transparant, using a UNIque opaque Color, 41 and one line of glenz */ 42 S_RLE_GLENZ_AUTO, /* transparant, using glenz for some 43 known colors (this is slow) */ 44 S_PROG, /* a list of sprites, to draw all at once */ 45 S_PROG_WAV /* like S_PROG but also wave */ 46 }; 47 48 typedef union sprite_s a_sprite; 49 50 typedef void (*sprite_draw_func) (const a_sprite *sprite, a_pixel *dest); 51 52 /*-------------------------------------------------------------------. 53 | Because the various flavor of sprites are not drawn the same way, | 54 | there exist various drawing functions. There is one drawing | 55 | function for each kind of sprite. | 56 | | 57 | Each sprite contains a pointer to its drawing function. Therefore | 58 | the DRAW_SPRITE macro below is the generic way to draw a sprite. | 59 | It is more efficient, however, to call the right drawing function | 60 | if you know it at compile time. | 61 `-------------------------------------------------------------------*/ 62 63 #define DRAW_SPRITE(s,dest) ((s)->draw ((s), (dest))) 64 65 #define SPRITE_FIRST_MEMBER \ 66 sprite_draw_func draw 67 68 69 #define SPRITE_COMMON_MEMBERS \ 70 SPRITE_FIRST_MEMBER; \ 71 enum sprite_kind kind /* kind of sprite */ 72 73 struct sprite_common_s { 74 SPRITE_COMMON_MEMBERS; 75 }; 76 77 typedef struct sprite_prog_list_s a_sprite_prog_list; /* see sprprog.c */ 78 79 struct sprite_prog_s { 80 SPRITE_COMMON_MEMBERS; 81 a_sprite_prog_list *list; 82 }; 83 84 #define SPRITE_RLE_MEMBERS \ 85 SPRITE_COMMON_MEMBERS; \ 86 \ 87 /* The code of an rle-sprite is a sequence of \ 88 1 a_u8: number m of transparent pixels to skip \ 89 1 a_u8: number n of bytes to write \ 90 n a_u8: actual bytes to write \ 91 The end of a line can be announced using m=0 and n=0, \ 92 and the code MUST terminate by m=0 and n=0. \ 93 */ \ 94 a_u8* code; \ 95 \ 96 /* a pointer the byte right after the end of code, \ 97 in order to known where to stop. */ \ 98 a_u8* end_code; \ 99 \ 100 /* the number of byte to skip to from the end of a line to the \ 101 beginning of the next one */ \ 102 unsigned int line_skip 103 104 struct sprite_rle_s { 105 SPRITE_RLE_MEMBERS; 106 }; 107 108 struct sprite_rle_shade_s { 109 /* shaded sprites reuse the member of RLE, but the code used 110 is extended. The code of a shaded sprite is a sequence of 111 1 a_u8: number m of transparent pixels to skip 112 1 a_u8: number n of bytes to write 113 n a_u8: actual bytes to write 114 1 a_u8: number s of glenz pixels to draw right after 115 The end of a line can be announced using m=0, n=0, and s=0, 116 and the code MUST terminate by m=0, n=0, and s=0. 117 */ 118 SPRITE_RLE_MEMBERS; 119 a_pixel* glenz; 120 }; 121 122 struct sprite_rle_glenz_s { 123 /* glenz sprites reuse the member of RLE, but the code used 124 is extended. The code of a shaded sprite is a sequence of 125 1 a_u8: number m of transparent pixels to skip 126 1 a_u8: number n of glenz pixels to write 127 The end of a line can be announced using m=0, and n=0, 128 and the code MUST terminate by m=0, and n=0. 129 */ 130 SPRITE_RLE_MEMBERS; 131 a_pixel* glenz; 132 }; 133 134 struct sprite_rle_unic_shade_s { 135 /* shaded sprites reuse the member of RLE, but the code used 136 is extended. The code of a shaded sprite is a sequence of 137 1 a_u8: number m of transparent pixels to skip 138 1 a_u8: number n of bytes to write 139 1 a_u8: number s of glenz pixels to draw right after 140 The end of a line can be announced using m=0, n=0, and s=0, 141 and the code MUST terminate by m=0, n=0, and s=0. 142 */ 143 SPRITE_RLE_MEMBERS; 144 a_pixel* glenz; 145 a_pixel color; /* used to draw opaque pixels */ 146 }; 147 148 struct sprite_opaque_s { 149 SPRITE_COMMON_MEMBERS; 150 a_pixel* data; /* data to write (concatenated) */ 151 a_pixel* end_data; /* pointer the pixel right after the last 152 in data */ 153 int width; /* number of data to write per line */ 154 int line_skip; /* byte to skip at the end of a line, to 155 jump to the next one. */ 156 }; 157 158 union sprite_s { 159 SPRITE_FIRST_MEMBER; 160 struct sprite_common_s all; 161 struct sprite_prog_s prog; 162 struct sprite_rle_s rle; 163 struct sprite_rle_shade_s shade; 164 struct sprite_rle_glenz_s glenz; 165 struct sprite_opaque_s opaq; 166 struct sprite_rle_unic_shade_s unish; 167 }; 168 169 /* generic sprite freeing function, this will dispatch to the right 170 freeing function */ 171 void free_sprite (a_sprite *sprite); 172 173 #define FREE_SPRITE0(x) \ 174 do { \ 175 if (x) { \ 176 free_sprite (x); \ 177 x = 0; \ 178 } \ 179 } while (0) 180 181 #endif /* HEROES__SPRITES__H */ 182