| 1 |
/********************************************************************* |
| 2 |
|
| 3 |
drawgfx.h |
| 4 |
|
| 5 |
Generic graphic functions. |
| 6 |
|
| 7 |
*********************************************************************/ |
| 8 |
|
| 9 |
#ifndef DRAWGFX_H |
| 10 |
#define DRAWGFX_H |
| 11 |
|
| 12 |
#ifdef __cplusplus |
| 13 |
extern "C" { |
| 14 |
#endif |
| 15 |
|
| 16 |
#include "palette.h" |
| 17 |
|
| 18 |
#define MAX_GFX_PLANES 8 |
| 19 |
#define MAX_GFX_SIZE 64 |
| 20 |
|
| 21 |
#define RGN_FRAC(num,den) (0x80000000 | (((num) & 0x0f) << 27) | (((den) & 0x0f) << 23)) |
| 22 |
#define IS_FRAC(offset) ((offset) & 0x80000000) |
| 23 |
#define FRAC_NUM(offset) (((offset) >> 27) & 0x0f) |
| 24 |
#define FRAC_DEN(offset) (((offset) >> 23) & 0x0f) |
| 25 |
#define FRAC_OFFSET(offset) ((offset) & 0x007fffff) |
| 26 |
|
| 27 |
#define STEP4(START,STEP) (START),(START)+1*(STEP),(START)+2*(STEP),(START)+3*(STEP) |
| 28 |
#define STEP8(START,STEP) STEP4(START,STEP),STEP4((START)+4*(STEP),STEP) |
| 29 |
#define STEP16(START,STEP) STEP8(START,STEP),STEP8((START)+8*(STEP),STEP) |
| 30 |
|
| 31 |
|
| 32 |
struct GfxLayout |
| 33 |
{ |
| 34 |
UINT16 width,height; /* width and height (in pixels) of chars/sprites */ |
| 35 |
UINT32 total; /* total numer of chars/sprites in the rom */ |
| 36 |
UINT16 planes; /* number of bitplanes */ |
| 37 |
UINT32 planeoffset[MAX_GFX_PLANES]; /* start of every bitplane (in bits) */ |
| 38 |
UINT32 xoffset[MAX_GFX_SIZE]; /* position of the bit corresponding to the pixel */ |
| 39 |
UINT32 yoffset[MAX_GFX_SIZE]; /* of the given coordinates */ |
| 40 |
UINT16 charincrement; /* distance between two consecutive characters/sprites (in bits) */ |
| 41 |
}; |
| 42 |
|
| 43 |
#define GFX_RAW 0x12345678 |
| 44 |
/* When planeoffset[0] is set to GFX_RAW, the gfx data is left as-is, with no conversion. |
| 45 |
No buffer is allocated for the decoded data, and gfxdata is set to point to the source |
| 46 |
data; therefore, you must not use ROMREGION_DISPOSE. |
| 47 |
xoffset[0] is an optional displacement (*8) from the beginning of the source data, while |
| 48 |
yoffset[0] is the line modulo (*8) and charincrement the char modulo (*8). They are *8 |
| 49 |
for consistency with the usual behaviour, but the bottom 3 bits are not used. |
| 50 |
GFX_PACKED is automatically set if planes is <= 4. |
| 51 |
|
| 52 |
This special mode can be used to save memory in games that require several different |
| 53 |
handlings of the same ROM data (e.g. metro.c can use both 4bpp and 8bpp tiles, and both |
| 54 |
8x8 and 16x16; cps.c has 8x8, 16x16 and 32x32 tiles all fetched from the same ROMs). |
| 55 |
Note, however, that performance will suffer in rotated games, since the gfx data will |
| 56 |
not be prerotated and will rely on GFX_SWAPXY. |
| 57 |
*/ |
| 58 |
|
| 59 |
struct GfxElement |
| 60 |
{ |
| 61 |
int width,height; |
| 62 |
|
| 63 |
unsigned int total_elements; /* total number of characters/sprites */ |
| 64 |
int color_granularity; /* number of colors for each color code */ |
| 65 |
/* (for example, 4 for 2 bitplanes gfx) */ |
| 66 |
pen_t *colortable; /* map color codes to screen pens */ |
| 67 |
int total_colors; |
| 68 |
UINT32 *pen_usage; /* an array of total_elements entries. */ |
| 69 |
/* It is a table of the pens each character uses */ |
| 70 |
/* (bit 0 = pen 0, and so on). This is used by */ |
| 71 |
/* drawgfgx() to do optimizations like skipping */ |
| 72 |
/* drawing of a totally transparent character */ |
| 73 |
UINT8 *gfxdata; /* pixel data */ |
| 74 |
int line_modulo; /* amount to add to get to the next line (usually = width) */ |
| 75 |
int char_modulo; /* = line_modulo * height */ |
| 76 |
int flags; |
| 77 |
}; |
| 78 |
|
| 79 |
#define GFX_PACKED 1 /* two 4bpp pixels are packed in one byte of gfxdata */ |
| 80 |
#define GFX_SWAPXY 2 /* characters are mirrored along the top-left/bottom-right diagonal */ |
| 81 |
#define GFX_DONT_FREE_GFXDATA 4 /* gfxdata was not malloc()ed, so don't free it on exit */ |
| 82 |
|
| 83 |
|
| 84 |
struct GfxDecodeInfo |
| 85 |
{ |
| 86 |
int memory_region; /* memory region where the data resides (usually 1) */ |
| 87 |
/* -1 marks the end of the array */ |
| 88 |
int start; /* beginning of data to decode */ |
| 89 |
struct GfxLayout *gfxlayout; |
| 90 |
int color_codes_start; /* offset in the color lookup table where color codes start */ |
| 91 |
int total_color_codes; /* total number of color codes */ |
| 92 |
}; |
| 93 |
|
| 94 |
|
| 95 |
struct rectangle |
| 96 |
{ |
| 97 |
int min_x,max_x; |
| 98 |
int min_y,max_y; |
| 99 |
}; |
| 100 |
|
| 101 |
struct _alpha_cache { |
| 102 |
const UINT8 *alphas; |
| 103 |
const UINT8 *alphad; |
| 104 |
UINT8 alpha[0x101][0x100]; |
| 105 |
}; |
| 106 |
|
| 107 |
extern struct _alpha_cache alpha_cache; |
| 108 |
|
| 109 |
enum |
| 110 |
{ |
| 111 |
TRANSPARENCY_NONE, /* opaque with remapping */ |
| 112 |
TRANSPARENCY_NONE_RAW, /* opaque with no remapping */ |
| 113 |
TRANSPARENCY_PEN, /* single pen transparency with remapping */ |
| 114 |
TRANSPARENCY_PEN_RAW, /* single pen transparency with no remapping */ |
| 115 |
TRANSPARENCY_PENS, /* multiple pen transparency with remapping */ |
| 116 |
TRANSPARENCY_PENS_RAW, /* multiple pen transparency with no remapping */ |
| 117 |
TRANSPARENCY_COLOR, /* single remapped pen transparency with remapping */ |
| 118 |
TRANSPARENCY_PEN_TABLE, /* special pen remapping modes (see DRAWMODE_xxx below) with remapping */ |
| 119 |
TRANSPARENCY_PEN_TABLE_RAW, /* special pen remapping modes (see DRAWMODE_xxx below) with no remapping */ |
| 120 |
TRANSPARENCY_BLEND, /* blend two bitmaps, shifting the source and ORing to the dest with remapping */ |
| 121 |
TRANSPARENCY_BLEND_RAW, /* blend two bitmaps, shifting the source and ORing to the dest with no remapping */ |
| 122 |
TRANSPARENCY_ALPHAONE, /* single pen transparency, single pen alpha */ |
| 123 |
TRANSPARENCY_ALPHA, /* single pen transparency, other pens alpha */ |
| 124 |
#ifdef MAME32JP |
| 125 |
TRANSPARENCY_FONT, |
| 126 |
#endif |
| 127 |
|
| 128 |
TRANSPARENCY_MODES /* total number of modes; must be last */ |
| 129 |
}; |
| 130 |
|
| 131 |
/* drawing mode case TRANSPARENCY_PEN_TABLE */ |
| 132 |
extern UINT8 gfx_drawmode_table[256]; |
| 133 |
enum |
| 134 |
{ |
| 135 |
DRAWMODE_NONE, |
| 136 |
DRAWMODE_SOURCE, |
| 137 |
DRAWMODE_SHADOW |
| 138 |
}; |
| 139 |
|
| 140 |
/* By default, when drawing sprites with pdrawgfx, shadows affect the sprites below them. */ |
| 141 |
/* Set this flag to 1 to make shadows only affect the background, leaving sprites at full brightness. */ |
| 142 |
extern int pdrawgfx_shadow_lowpri; |
| 143 |
|
| 144 |
|
| 145 |
typedef void (*mark_dirty_proc)(int sx,int sy,int ex,int ey); |
| 146 |
extern mark_dirty_proc mark_dirty; |
| 147 |
|
| 148 |
|
| 149 |
/* pointers to pixel functions. They're set based on orientation, depthness and whether |
| 150 |
dirty rectangle handling is enabled */ |
| 151 |
#define plot_pixel(bm,x,y,p) (*(bm)->plot)(bm,x,y,p) |
| 152 |
#define read_pixel(bm,x,y) (*(bm)->read)(bm,x,y) |
| 153 |
#define plot_box(bm,x,y,w,h,p) (*(bm)->plot_box)(bm,x,y,w,h,p) |
| 154 |
#ifdef MAME32JP |
| 155 |
#define plot_box_trans(bm,x,y,w,h) (*(bm)->plot_box_ts)(bm,x,y,w,h) |
| 156 |
#endif |
| 157 |
|
| 158 |
void decodechar(struct GfxElement *gfx,int num,const unsigned char *src,const struct GfxLayout *gl); |
| 159 |
struct GfxElement *decodegfx(const unsigned char *src,const struct GfxLayout *gl); |
| 160 |
void set_pixel_functions(struct mame_bitmap *bitmap); |
| 161 |
void freegfx(struct GfxElement *gfx); |
| 162 |
void drawgfx(struct mame_bitmap *dest,const struct GfxElement *gfx, |
| 163 |
unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy, |
| 164 |
const struct rectangle *clip,int transparency,int transparent_color); |
| 165 |
void pdrawgfx(struct mame_bitmap *dest,const struct GfxElement *gfx, |
| 166 |
unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy, |
| 167 |
const struct rectangle *clip,int transparency,int transparent_color, |
| 168 |
UINT32 priority_mask); |
| 169 |
void mdrawgfx(struct mame_bitmap *dest,const struct GfxElement *gfx, |
| 170 |
unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy, |
| 171 |
const struct rectangle *clip,int transparency,int transparent_color, |
| 172 |
UINT32 priority_mask); |
| 173 |
void copybitmap(struct mame_bitmap *dest,struct mame_bitmap *src,int flipx,int flipy,int sx,int sy, |
| 174 |
const struct rectangle *clip,int transparency,int transparent_color); |
| 175 |
void copybitmap_remap(struct mame_bitmap *dest,struct mame_bitmap *src,int flipx,int flipy,int sx,int sy, |
| 176 |
const struct rectangle *clip,int transparency,int transparent_color); |
| 177 |
void copyscrollbitmap(struct mame_bitmap *dest,struct mame_bitmap *src, |
| 178 |
int rows,const int *rowscroll,int cols,const int *colscroll, |
| 179 |
const struct rectangle *clip,int transparency,int transparent_color); |
| 180 |
void copyscrollbitmap_remap(struct mame_bitmap *dest,struct mame_bitmap *src, |
| 181 |
int rows,const int *rowscroll,int cols,const int *colscroll, |
| 182 |
const struct rectangle *clip,int transparency,int transparent_color); |
| 183 |
void draw_scanline8(struct mame_bitmap *bitmap,int x,int y,int length,const UINT8 *src,pen_t *pens,int transparent_pen); |
| 184 |
void draw_scanline16(struct mame_bitmap *bitmap,int x,int y,int length,const UINT16 *src,pen_t *pens,int transparent_pen); |
| 185 |
void pdraw_scanline8(struct mame_bitmap *bitmap,int x,int y,int length,const UINT8 *src,pen_t *pens,int transparent_pen,UINT32 orient,int pri); |
| 186 |
void pdraw_scanline16(struct mame_bitmap *bitmap,int x,int y,int length,const UINT16 *src,pen_t *pens,int transparent_pen,UINT32 orient,int pri); |
| 187 |
void extract_scanline8(struct mame_bitmap *bitmap,int x,int y,int length,UINT8 *dst); |
| 188 |
void extract_scanline16(struct mame_bitmap *bitmap,int x,int y,int length,UINT16 *dst); |
| 189 |
|
| 190 |
|
| 191 |
/* Alpha blending functions */ |
| 192 |
extern int alpha_active; |
| 193 |
void alpha_init(void); |
| 194 |
INLINE void alpha_set_level(int level) { |
| 195 |
if(level == 0) |
| 196 |
level = -1; |
| 197 |
alpha_cache.alphas = alpha_cache.alpha[level+1]; |
| 198 |
alpha_cache.alphad = alpha_cache.alpha[255-level]; |
| 199 |
} |
| 200 |
|
| 201 |
INLINE UINT32 alpha_blend16( UINT32 d, UINT32 s ) |
| 202 |
{ |
| 203 |
const UINT8 *alphas = alpha_cache.alphas; |
| 204 |
const UINT8 *alphad = alpha_cache.alphad; |
| 205 |
return (alphas[s & 0x1f] | (alphas[(s>>5) & 0x1f] << 5) | (alphas[(s>>10) & 0x1f] << 10)) |
| 206 |
+ (alphad[d & 0x1f] | (alphad[(d>>5) & 0x1f] << 5) | (alphad[(d>>10) & 0x1f] << 10)); |
| 207 |
} |
| 208 |
|
| 209 |
|
| 210 |
INLINE UINT32 alpha_blend32( UINT32 d, UINT32 s ) |
| 211 |
{ |
| 212 |
const UINT8 *alphas = alpha_cache.alphas; |
| 213 |
const UINT8 *alphad = alpha_cache.alphad; |
| 214 |
return (alphas[s & 0xff] | (alphas[(s>>8) & 0xff] << 8) | (alphas[(s>>16) & 0xff] << 16)) |
| 215 |
+ (alphad[d & 0xff] | (alphad[(d>>8) & 0xff] << 8) | (alphad[(d>>16) & 0xff] << 16)); |
| 216 |
} |
| 217 |
|
| 218 |
|
| 219 |
/* |
| 220 |
Copy a bitmap applying rotation, zooming, and arbitrary distortion. |
| 221 |
This function works in a way that mimics some real hardware like the Konami |
| 222 |
051316, so it requires little or no further processing on the caller side. |
| 223 |
|
| 224 |
Two 16.16 fixed point counters are used to keep track of the position on |
| 225 |
the source bitmap. startx and starty are the initial values of those counters, |
| 226 |
indicating the source pixel that will be drawn at coordinates (0,0) in the |
| 227 |
destination bitmap. The destination bitmap is scanned left to right, top to |
| 228 |
bottom; every time the cursor moves one pixel to the right, incxx is added |
| 229 |
to startx and incxy is added to starty. Every time the cursor moves to the |
| 230 |
next line, incyx is added to startx and incyy is added to startyy. |
| 231 |
|
| 232 |
What this means is that if incxy and incyx are both 0, the bitmap will be |
| 233 |
copied with only zoom and no rotation. If e.g. incxx and incyy are both 0x8000, |
| 234 |
the source bitmap will be doubled. |
| 235 |
|
| 236 |
Rotation is performed this way: |
| 237 |
incxx = 0x10000 * cos(theta) |
| 238 |
incxy = 0x10000 * -sin(theta) |
| 239 |
incyx = 0x10000 * sin(theta) |
| 240 |
incyy = 0x10000 * cos(theta) |
| 241 |
this will perform a rotation around (0,0), you'll have to adjust startx and |
| 242 |
starty to move the center of rotation elsewhere. |
| 243 |
|
| 244 |
Optionally the bitmap can be tiled across the screen instead of doing a single |
| 245 |
copy. This is obtained by setting the wraparound parameter to true. |
| 246 |
*/ |
| 247 |
void copyrozbitmap(struct mame_bitmap *dest,struct mame_bitmap *src, |
| 248 |
UINT32 startx,UINT32 starty,int incxx,int incxy,int incyx,int incyy,int wraparound, |
| 249 |
const struct rectangle *clip,int transparency,int transparent_color,UINT32 priority); |
| 250 |
|
| 251 |
void fillbitmap(struct mame_bitmap *dest,pen_t pen,const struct rectangle *clip); |
| 252 |
void plot_pixel2(struct mame_bitmap *bitmap1,struct mame_bitmap *bitmap2,int x,int y,pen_t pen); |
| 253 |
void drawgfxzoom( struct mame_bitmap *dest_bmp,const struct GfxElement *gfx, |
| 254 |
unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy, |
| 255 |
const struct rectangle *clip,int transparency,int transparent_color,int scalex,int scaley); |
| 256 |
void pdrawgfxzoom( struct mame_bitmap *dest_bmp,const struct GfxElement *gfx, |
| 257 |
unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy, |
| 258 |
const struct rectangle *clip,int transparency,int transparent_color,int scalex,int scaley, |
| 259 |
UINT32 priority_mask); |
| 260 |
void mdrawgfxzoom( struct mame_bitmap *dest_bmp,const struct GfxElement *gfx, |
| 261 |
unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy, |
| 262 |
const struct rectangle *clip,int transparency,int transparent_color,int scalex,int scaley, |
| 263 |
UINT32 priority_mask); |
| 264 |
|
| 265 |
void draw_crosshair(struct mame_bitmap *bitmap,int x,int y,const struct rectangle *clip); |
| 266 |
|
| 267 |
INLINE void sect_rect(struct rectangle *dst, const struct rectangle *src) |
| 268 |
{ |
| 269 |
if (src->min_x > dst->min_x) dst->min_x = src->min_x; |
| 270 |
if (src->max_x < dst->max_x) dst->max_x = src->max_x; |
| 271 |
if (src->min_y > dst->min_y) dst->min_y = src->min_y; |
| 272 |
if (src->max_y < dst->max_y) dst->max_y = src->max_y; |
| 273 |
} |
| 274 |
|
| 275 |
|
| 276 |
#ifdef __cplusplus |
| 277 |
} |
| 278 |
#endif |
| 279 |
|
| 280 |
#endif |