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 |