src/blitter/32bpp_anim.cpp
changeset 7556 7224575e68fb
parent 7555 85e72f9c20cb
child 7557 4b3f3b4c613e
equal deleted inserted replaced
7555:85e72f9c20cb 7556:7224575e68fb
     8 
     8 
     9 static FBlitter_32bppAnim iFBlitter_32bppAnim;
     9 static FBlitter_32bppAnim iFBlitter_32bppAnim;
    10 
    10 
    11 void Blitter_32bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
    11 void Blitter_32bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
    12 {
    12 {
       
    13 	if (bp->dst < _screen.dst_ptr || bp->dst > (uint32 *)_screen.dst_ptr + _screen.width * _screen.height) {
       
    14 		/* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent Draw() */
       
    15 		Blitter_32bppOptimized::Draw(bp, mode, zoom);
       
    16 		return;
       
    17 	}
    13 	const SpriteLoader::CommonPixel *src, *src_line;
    18 	const SpriteLoader::CommonPixel *src, *src_line;
    14 	uint32 *dst, *dst_line;
    19 	uint32 *dst, *dst_line;
    15 	uint8 *anim, *anim_line, *anim_end;
    20 	uint8 *anim, *anim_line;
    16 
    21 
    17 	if (_screen.width != this->anim_buf_width || _screen.height != this->anim_buf_height) {
    22 	if (_screen.width != this->anim_buf_width || _screen.height != this->anim_buf_height) {
    18 		/* The size of the screen changed; we can assume we can wipe all data from our buffer */
    23 		/* The size of the screen changed; we can assume we can wipe all data from our buffer */
    19 		free(this->anim_buf);
    24 		free(this->anim_buf);
    20 		this->anim_buf = CallocT<uint8>(_screen.width * _screen.height);
    25 		this->anim_buf = CallocT<uint8>(_screen.width * _screen.height);
    21 		this->anim_buf_width = _screen.width;
    26 		this->anim_buf_width = _screen.width;
    22 		this->anim_buf_height = _screen.height;
    27 		this->anim_buf_height = _screen.height;
    23 	}
    28 	}
    24 	anim_end = this->anim_buf + this->anim_buf_height * this->anim_buf_width - 1;
       
    25 
    29 
    26 	/* Find where to start reading in the source sprite */
    30 	/* Find where to start reading in the source sprite */
    27 	src_line = (const SpriteLoader::CommonPixel *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
    31 	src_line = (const SpriteLoader::CommonPixel *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
    28 	dst_line = (uint32 *)bp->dst + bp->top * bp->pitch + bp->left;
    32 	dst_line = (uint32 *)bp->dst + bp->top * bp->pitch + bp->left;
    29 	anim_line = this->anim_buf + ((uint32 *)bp->dst - (uint32 *)_screen.dst_ptr) + bp->top * this->anim_buf_width + bp->left;
    33 	anim_line = this->anim_buf + ((uint32 *)bp->dst - (uint32 *)_screen.dst_ptr) + bp->top * this->anim_buf_width + bp->left;
    35 		src = src_line;
    39 		src = src_line;
    36 		src_line += bp->sprite_width * ScaleByZoom(1, zoom);
    40 		src_line += bp->sprite_width * ScaleByZoom(1, zoom);
    37 
    41 
    38 		anim = anim_line;
    42 		anim = anim_line;
    39 		anim_line += this->anim_buf_width;
    43 		anim_line += this->anim_buf_width;
    40 		/* Don't allow values of 'anim' greater than 'anim_end' to avoid buffer overflows.
       
    41 		 *  This only happens when we are doing a big-screenshot, so it should be relative safe */
       
    42 		if (anim >= anim_end || anim < this->anim_buf) anim = anim_end;
       
    43 
    44 
    44 		for (int x = 0; x < bp->width; x++) {
    45 		for (int x = 0; x < bp->width; x++) {
    45 			if (src->a == 0) {
    46 			if (src->a == 0) {
    46 				/* src->r is 'misused' here to indicate how much more pixels are following with an alpha of 0 */
    47 				/* src->r is 'misused' here to indicate how much more pixels are following with an alpha of 0 */
    47 				int skip = UnScaleByZoom(src->r, zoom);
    48 				int skip = UnScaleByZoom(src->r, zoom);
    48 
    49 
    49 				dst  += skip;
    50 				dst  += skip;
    50 				/* Make sure the anim-buffer is cleared */
    51 				/* Make sure the anim-buffer is cleared */
    51 				if (anim < anim_end - skip) {
    52 				memset(anim, 0, skip);
    52 					memset(anim, 0, skip);
    53 				anim += skip;
    53 					anim += skip;
       
    54 				}
       
    55 				x    += skip - 1;
    54 				x    += skip - 1;
    56 				src  += ScaleByZoom(1, zoom) * skip;
    55 				src  += ScaleByZoom(1, zoom) * skip;
    57 				continue;
    56 				continue;
    58 			}
    57 			}
    59 
    58 
    87 					else               *dst = ComposeColourRGBA(src->r, src->g, src->b, src->a, *dst);
    86 					else               *dst = ComposeColourRGBA(src->r, src->g, src->b, src->a, *dst);
    88 					*anim = src->m;
    87 					*anim = src->m;
    89 					break;
    88 					break;
    90 			}
    89 			}
    91 			dst++;
    90 			dst++;
    92 			/* Don't increase the anim buffer anymore if we tend to run out of the buffer...
    91 			anim++;
    93 			 *  This only happens when we are doing a big-screenshot, so it should be relative safe */
       
    94 			if (anim < anim_end) anim++;
       
    95 			src += ScaleByZoom(1, zoom);
    92 			src += ScaleByZoom(1, zoom);
    96 		}
    93 		}
    97 	}
    94 	}
    98 }
    95 }
    99 
    96