1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Sprite drawing functions.
12 *
13 * By Michael Bukin.
14 *
15 * See readme.txt for copyright information.
16 */
17
18 #ifndef __bma_cspr_h
19 #define __bma_cspr_h
20
21
22 /* _linear_draw_sprite_ex:
23 * Draws a masked sprite onto a linear bitmap at the specified dx, dy position,
24 * using drawing mode specified by 'mode' and flipping mode specified by
25 * 'flip'.
26 */
FUNC_LINEAR_DRAW_SPRITE_EX(BITMAP * dst,BITMAP * src,int dx,int dy,int mode,int flip)27 void FUNC_LINEAR_DRAW_SPRITE_EX(BITMAP * dst, BITMAP * src, int dx, int dy,
28 int mode, int flip)
29 {
30 int x, y, w, h;
31 int x_dir = 1, y_dir = 1;
32 int dxbeg, dybeg;
33 int sxbeg, sybeg;
34 DLS_BLENDER lit_blender;
35 DTS_BLENDER trans_blender;
36
37 ASSERT(dst);
38 ASSERT(src);
39
40 if (flip == DRAW_SPRITE_V_FLIP) {
41 y_dir = -1;
42 }
43 if (flip == DRAW_SPRITE_H_FLIP) {
44 x_dir = -1;
45 }
46 if (flip == DRAW_SPRITE_VH_FLIP) {
47 y_dir = -1;
48 x_dir = -1;
49 }
50
51 if (dst->clip) {
52 int tmp;
53
54 tmp = dst->cl - dx;
55 sxbeg = MAX(0, tmp);
56 dxbeg = sxbeg + dx;
57
58 tmp = dst->cr - dx;
59 w = MIN(src->w, tmp) - sxbeg;
60 if (w <= 0)
61 return;
62
63 if (flip == DRAW_SPRITE_H_FLIP || flip == DRAW_SPRITE_VH_FLIP) {
64 /* use backward drawing onto dst */
65 sxbeg = src->w - (sxbeg + w);
66 dxbeg += w - 1;
67 }
68
69 tmp = dst->ct - dy;
70 sybeg = MAX(0, tmp);
71 dybeg = sybeg + dy;
72
73 tmp = dst->cb - dy;
74 h = MIN(src->h, tmp) - sybeg;
75 if (h <= 0)
76 return;
77
78 if (flip == DRAW_SPRITE_V_FLIP || flip == DRAW_SPRITE_VH_FLIP) {
79 /* use backward drawing onto dst */
80 sybeg = src->h - (sybeg + h);
81 dybeg += h - 1;
82 }
83 }
84 else {
85 w = src->w;
86 h = src->h;
87 sxbeg = 0;
88 sybeg = 0;
89 dxbeg = dx;
90 if (flip == DRAW_SPRITE_H_FLIP || flip == DRAW_SPRITE_VH_FLIP) {
91 dxbeg = dx + w - 1;
92 }
93 dybeg = dy;
94 if (flip == DRAW_SPRITE_V_FLIP || flip == DRAW_SPRITE_VH_FLIP) {
95 dybeg = dy + h - 1;
96 }
97 }
98
99 lit_blender = MAKE_DLS_BLENDER(0);
100 trans_blender = MAKE_DTS_BLENDER();
101
102 if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
103 bmp_select(dst);
104
105 for (y = 0; y < h; y++) {
106 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
107
108 /* flipped if y_dir is -1 */
109 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
110
111 /* d is incremented by x_dir, -1 if flipped */
112 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR_N(d,x_dir), x--) {
113 unsigned long c = GET_MEMORY_PIXEL(s);
114 if (!IS_SPRITE_MASK(src, c)) {
115 switch (mode) {
116 case DRAW_SPRITE_NORMAL:
117 break;
118
119 case DRAW_SPRITE_LIT:
120 c = DLSX_BLEND(lit_blender, c);
121 break;
122
123 case DRAW_SPRITE_TRANS:
124 c = DTS_BLEND(trans_blender, GET_PIXEL(d), c);
125 break;
126 }
127 PUT_PIXEL(d, c);
128 }
129 }
130 }
131
132 bmp_unwrite_line(dst);
133 }
134 else {
135 for (y = 0; y < h; y++) {
136 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
137 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
138
139 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR_N(d,x_dir), x--) {
140 unsigned long c = GET_MEMORY_PIXEL(s);
141 if (!IS_SPRITE_MASK(src, c)) {
142 switch (mode) {
143 case DRAW_SPRITE_NORMAL:
144 break;
145
146 case DRAW_SPRITE_LIT:
147 c = DLSX_BLEND(lit_blender, c);
148 break;
149
150 case DRAW_SPRITE_TRANS:
151 c = DTS_BLEND(trans_blender, GET_PIXEL(d), c);
152 break;
153 }
154 PUT_MEMORY_PIXEL(d, c);
155 }
156 }
157 }
158 }
159 }
160
161
162
163 /* _linear_draw_sprite:
164 * Draws a sprite onto a linear bitmap at the specified x, y position,
165 * using a masked drawing mode where zero pixels are not output.
166 */
FUNC_LINEAR_DRAW_SPRITE(BITMAP * dst,BITMAP * src,int dx,int dy)167 void FUNC_LINEAR_DRAW_SPRITE(BITMAP *dst, BITMAP *src, int dx, int dy)
168 {
169 int x, y, w, h;
170 int dxbeg, dybeg;
171 int sxbeg, sybeg;
172
173 ASSERT(dst);
174 ASSERT(src);
175
176 if (dst->clip) {
177 int tmp;
178
179 tmp = dst->cl - dx;
180 sxbeg = ((tmp < 0) ? 0 : tmp);
181 dxbeg = sxbeg + dx;
182
183 tmp = dst->cr - dx;
184 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
185 if (w <= 0)
186 return;
187
188 tmp = dst->ct - dy;
189 sybeg = ((tmp < 0) ? 0 : tmp);
190 dybeg = sybeg + dy;
191
192 tmp = dst->cb - dy;
193 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
194 if (h <= 0)
195 return;
196 }
197 else {
198 w = src->w;
199 h = src->h;
200 sxbeg = 0;
201 sybeg = 0;
202 dxbeg = dx;
203 dybeg = dy;
204 }
205
206 if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
207 bmp_select(dst);
208
209 for (y = 0; y < h; y++) {
210 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
211 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
212
213 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
214 unsigned long c = GET_MEMORY_PIXEL(s);
215 if (!IS_SPRITE_MASK(src, c)) {
216 PUT_PIXEL(d, c);
217 }
218 }
219 }
220
221 bmp_unwrite_line(dst);
222 }
223 else {
224 for (y = 0; y < h; y++) {
225 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
226 PIXEL_PTR d = OFFSET_PIXEL_PTR(dst->line[dybeg + y], dxbeg);
227
228 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
229 unsigned long c = GET_MEMORY_PIXEL(s);
230 if (!IS_SPRITE_MASK(src, c)) {
231 PUT_MEMORY_PIXEL(d, c);
232 }
233 }
234 }
235 }
236 }
237
FUNC_LINEAR_DRAW_SPRITE_END(void)238 void FUNC_LINEAR_DRAW_SPRITE_END(void) { }
239
240
241
242 /* _linear_draw_256_sprite:
243 * Draws a 256 coor sprite onto a linear bitmap at the specified x, y
244 * position, using a masked drawing mode where zero pixels are not output.
245 */
FUNC_LINEAR_DRAW_256_SPRITE(BITMAP * dst,BITMAP * src,int dx,int dy)246 void FUNC_LINEAR_DRAW_256_SPRITE(BITMAP *dst, BITMAP *src, int dx, int dy)
247 {
248 int x, y, w, h;
249 int dxbeg, dybeg;
250 int sxbeg, sybeg;
251 int *table;
252
253 ASSERT(dst);
254 ASSERT(src);
255
256 if (dst->clip) {
257 int tmp;
258
259 tmp = dst->cl - dx;
260 sxbeg = ((tmp < 0) ? 0 : tmp);
261 dxbeg = sxbeg + dx;
262
263 tmp = dst->cr - dx;
264 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
265 if (w <= 0)
266 return;
267
268 tmp = dst->ct - dy;
269 sybeg = ((tmp < 0) ? 0 : tmp);
270 dybeg = sybeg + dy;
271
272 tmp = dst->cb - dy;
273 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
274 if (h <= 0)
275 return;
276 }
277 else {
278 w = src->w;
279 h = src->h;
280 sxbeg = 0;
281 sybeg = 0;
282 dxbeg = dx;
283 dybeg = dy;
284 }
285
286 table = _palette_expansion_table(bitmap_color_depth(dst));
287 ASSERT(table);
288
289 if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
290 bmp_select(dst);
291
292 for (y = 0; y < h; y++) {
293 unsigned char *s = src->line[sybeg + y] + sxbeg;
294 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
295
296 for (x = w - 1; x >= 0; s++, INC_PIXEL_PTR(d), x--) {
297 unsigned long c = *s;
298 if (c != 0) {
299 c = table[c];
300 PUT_PIXEL(d, c);
301 }
302 }
303 }
304
305 bmp_unwrite_line(dst);
306 }
307 else {
308 for (y = 0; y < h; y++) {
309 unsigned char *s = src->line[sybeg + y] + sxbeg;
310 PIXEL_PTR d = OFFSET_PIXEL_PTR(dst->line[dybeg + y], dxbeg);
311
312 for (x = w - 1; x >= 0; s++, INC_PIXEL_PTR(d), x--) {
313 unsigned long c = *s;
314 if (c != 0) {
315 c = table[c];
316 PUT_MEMORY_PIXEL(d, c);
317 }
318 }
319 }
320 }
321 }
322
323
324
325 /* _linear_draw_sprite_v_flip:
326 * Draws a sprite to a linear bitmap, flipping vertically.
327 */
FUNC_LINEAR_DRAW_SPRITE_V_FLIP(BITMAP * dst,BITMAP * src,int dx,int dy)328 void FUNC_LINEAR_DRAW_SPRITE_V_FLIP(BITMAP *dst, BITMAP *src, int dx, int dy)
329 {
330 int x, y, w, h;
331 int dxbeg, dybeg;
332 int sxbeg, sybeg;
333
334 ASSERT(dst);
335 ASSERT(src);
336
337 if (dst->clip) {
338 int tmp;
339
340 tmp = dst->cl - dx;
341 sxbeg = ((tmp < 0) ? 0 : tmp);
342 dxbeg = sxbeg + dx;
343
344 tmp = dst->cr - dx;
345 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
346 if (w <= 0)
347 return;
348
349 tmp = dst->ct - dy;
350 sybeg = ((tmp < 0) ? 0 : tmp);
351 dybeg = sybeg + dy;
352
353 tmp = dst->cb - dy;
354 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
355 if (h <= 0)
356 return;
357
358 /* use backward drawing onto dst */
359 sybeg = src->h - (sybeg + h);
360 dybeg += h - 1;
361 }
362 else {
363 w = src->w;
364 h = src->h;
365 sxbeg = 0;
366 sybeg = 0;
367 dxbeg = dx;
368 dybeg = dy + h - 1;
369 }
370
371 if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
372 bmp_select(dst);
373
374 for (y = 0; y < h; y++) {
375 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
376 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg - y), dxbeg);
377
378 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
379 unsigned long c = GET_MEMORY_PIXEL(s);
380 if (!IS_SPRITE_MASK(src, c)) {
381 PUT_PIXEL(d, c);
382 }
383 }
384 }
385
386 bmp_unwrite_line(dst);
387 }
388 else {
389 for (y = 0; y < h; y++) {
390 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
391 PIXEL_PTR d = OFFSET_PIXEL_PTR(dst->line[dybeg - y], dxbeg);
392
393 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
394 unsigned long c = GET_MEMORY_PIXEL(s);
395 if (!IS_SPRITE_MASK(src, c)) {
396 PUT_MEMORY_PIXEL(d, c);
397 }
398 }
399 }
400 }
401 }
402
403
404
405 /* _linear_draw_sprite_h_flip:
406 * Draws a sprite to a linear bitmap, flipping horizontally.
407 */
FUNC_LINEAR_DRAW_SPRITE_H_FLIP(BITMAP * dst,BITMAP * src,int dx,int dy)408 void FUNC_LINEAR_DRAW_SPRITE_H_FLIP(BITMAP *dst, BITMAP *src, int dx, int dy)
409 {
410 int x, y, w, h;
411 int dxbeg, dybeg;
412 int sxbeg, sybeg;
413
414 ASSERT(dst);
415 ASSERT(src);
416
417 if (dst->clip) {
418 int tmp;
419
420 tmp = dst->cl - dx;
421 sxbeg = ((tmp < 0) ? 0 : tmp);
422 dxbeg = sxbeg + dx;
423
424 tmp = dst->cr - dx;
425 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
426 if (w <= 0)
427 return;
428
429 /* use backward drawing onto dst */
430 sxbeg = src->w - (sxbeg + w);
431 dxbeg += w - 1;
432
433 tmp = dst->ct - dy;
434 sybeg = ((tmp < 0) ? 0 : tmp);
435 dybeg = sybeg + dy;
436
437 tmp = dst->cb - dy;
438 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
439 if (h <= 0)
440 return;
441 }
442 else {
443 w = src->w;
444 h = src->h;
445 sxbeg = 0;
446 sybeg = 0;
447 dxbeg = dx + w - 1;
448 dybeg = dy;
449 }
450
451 if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
452 bmp_select(dst);
453
454 for (y = 0; y < h; y++) {
455 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
456 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
457
458 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
459 unsigned long c = GET_MEMORY_PIXEL(s);
460 if (!IS_SPRITE_MASK(src, c)) {
461 PUT_PIXEL(d, c);
462 }
463 }
464 }
465
466 bmp_unwrite_line(dst);
467 }
468 else {
469 for (y = 0; y < h; y++) {
470 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
471 PIXEL_PTR d = OFFSET_PIXEL_PTR(dst->line[dybeg + y], dxbeg);
472
473 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
474 unsigned long c = GET_MEMORY_PIXEL(s);
475 if (!IS_SPRITE_MASK(src, c)) {
476 PUT_MEMORY_PIXEL(d, c);
477 }
478 }
479 }
480 }
481 }
482
483
484
485 /* _linear_draw_sprite_vh_flip:
486 * Draws a sprite to a linear bitmap, flipping both vertically and horizontally.
487 */
FUNC_LINEAR_DRAW_SPRITE_VH_FLIP(BITMAP * dst,BITMAP * src,int dx,int dy)488 void FUNC_LINEAR_DRAW_SPRITE_VH_FLIP(BITMAP *dst, BITMAP *src, int dx, int dy)
489 {
490 int x, y, w, h;
491 int dxbeg, dybeg;
492 int sxbeg, sybeg;
493
494 ASSERT(dst);
495 ASSERT(src);
496
497 if (dst->clip) {
498 int tmp;
499
500 tmp = dst->cl - dx;
501 sxbeg = ((tmp < 0) ? 0 : tmp);
502 dxbeg = sxbeg + dx;
503
504 tmp = dst->cr - dx;
505 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
506 if (w <= 0)
507 return;
508
509 /* use backward drawing onto dst */
510 sxbeg = src->w - (sxbeg + w);
511 dxbeg += w - 1;
512
513 tmp = dst->ct - dy;
514 sybeg = ((tmp < 0) ? 0 : tmp);
515 dybeg = sybeg + dy;
516
517 tmp = dst->cb - dy;
518 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
519 if (h <= 0)
520 return;
521
522 /* use backward drawing onto dst */
523 sybeg = src->h - (sybeg + h);
524 dybeg += h - 1;
525 }
526 else {
527 w = src->w;
528 h = src->h;
529 sxbeg = 0;
530 sybeg = 0;
531 dxbeg = dx + w - 1;
532 dybeg = dy + h - 1;
533 }
534
535 if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
536 bmp_select(dst);
537
538 for (y = 0; y < h; y++) {
539 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
540 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg - y), dxbeg);
541
542 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
543 unsigned long c = GET_MEMORY_PIXEL(s);
544 if (!IS_SPRITE_MASK(src, c)) {
545 PUT_PIXEL(d, c);
546 }
547 }
548 }
549
550 bmp_unwrite_line(dst);
551 }
552 else {
553 for (y = 0; y < h; y++) {
554 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
555 PIXEL_PTR d = OFFSET_PIXEL_PTR(dst->line[dybeg - y], dxbeg);
556
557 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), DEC_PIXEL_PTR(d), x--) {
558 unsigned long c = GET_MEMORY_PIXEL(s);
559 if (!IS_SPRITE_MASK(src, c)) {
560 PUT_MEMORY_PIXEL(d, c);
561 }
562 }
563 }
564 }
565 }
566
567
568
569 /* _linear_draw_trans_sprite:
570 * Draws a translucent sprite onto a linear bitmap.
571 */
FUNC_LINEAR_DRAW_TRANS_SPRITE(BITMAP * dst,BITMAP * src,int dx,int dy)572 void FUNC_LINEAR_DRAW_TRANS_SPRITE(BITMAP *dst, BITMAP *src, int dx, int dy)
573 {
574 int x, y, w, h;
575 int dxbeg, dybeg;
576 int sxbeg, sybeg;
577 DTS_BLENDER blender;
578
579 ASSERT(dst);
580 ASSERT(src);
581
582 if (dst->clip) {
583 int tmp;
584
585 tmp = dst->cl - dx;
586 sxbeg = ((tmp < 0) ? 0 : tmp);
587 dxbeg = sxbeg + dx;
588
589 tmp = dst->cr - dx;
590 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
591 if (w <= 0)
592 return;
593
594 tmp = dst->ct - dy;
595 sybeg = ((tmp < 0) ? 0 : tmp);
596 dybeg = sybeg + dy;
597
598 tmp = dst->cb - dy;
599 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
600 if (h <= 0)
601 return;
602 }
603 else {
604 w = src->w;
605 h = src->h;
606 sxbeg = 0;
607 sybeg = 0;
608 dxbeg = dx;
609 dybeg = dy;
610 }
611
612 blender = MAKE_DTS_BLENDER();
613
614 if ((src->vtable->color_depth == 8) && (dst->vtable->color_depth != 8)) {
615 bmp_select(dst);
616
617 for (y = 0; y < h; y++) {
618 unsigned char *s = src->line[sybeg + y] + sxbeg;
619 PIXEL_PTR ds = OFFSET_PIXEL_PTR(bmp_read_line(dst, dybeg + y), dxbeg);
620 PIXEL_PTR dd = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
621
622 for (x = w - 1; x >= 0; s++, INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), x--) {
623 unsigned long c = *s;
624 #if PP_DEPTH == 8
625 c = DTS_BLEND(blender, GET_PIXEL(ds), c);
626 PUT_PIXEL(dd, c);
627 #else
628 if (!IS_SPRITE_MASK(src, c)) {
629 c = DTS_BLEND(blender, GET_PIXEL(ds), c);
630 PUT_PIXEL(dd, c);
631 }
632 #endif
633 }
634 }
635
636 bmp_unwrite_line(dst);
637 }
638 else if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
639 bmp_select(dst);
640
641 for (y = 0; y < h; y++) {
642 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
643 PIXEL_PTR ds = OFFSET_PIXEL_PTR(bmp_read_line(dst, dybeg + y), dxbeg);
644 PIXEL_PTR dd = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
645
646 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), x--) {
647 unsigned long c = GET_MEMORY_PIXEL(s);
648 #if PP_DEPTH == 8
649 c = DTS_BLEND(blender, GET_PIXEL(ds), c);
650 PUT_PIXEL(dd, c);
651 #else
652 if (!IS_SPRITE_MASK(src, c)) {
653 c = DTS_BLEND(blender, GET_PIXEL(ds), c);
654 PUT_PIXEL(dd, c);
655 }
656 #endif
657 }
658 }
659
660 bmp_unwrite_line(dst);
661 }
662 else {
663 for (y = 0; y < h; y++) {
664 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
665 PIXEL_PTR d = OFFSET_PIXEL_PTR(dst->line[dybeg + y], dxbeg);
666
667 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
668 unsigned long c = GET_MEMORY_PIXEL(s);
669 #if PP_DEPTH == 8
670 c = DTS_BLEND(blender, GET_MEMORY_PIXEL(d), c);
671 PUT_MEMORY_PIXEL(d, c);
672 #else
673 if (!IS_SPRITE_MASK(src, c)) {
674 c = DTS_BLEND(blender, GET_MEMORY_PIXEL(d), c);
675 PUT_MEMORY_PIXEL(d, c);
676 }
677 #endif
678 }
679 }
680 }
681 }
682
683
684
685 #if (PP_DEPTH != 8) && (PP_DEPTH != 32)
686
687 /* _linear_draw_trans_rgba_sprite:
688 * Draws a translucent RGBA sprite onto a linear bitmap.
689 */
FUNC_LINEAR_DRAW_TRANS_RGBA_SPRITE(BITMAP * dst,BITMAP * src,int dx,int dy)690 void FUNC_LINEAR_DRAW_TRANS_RGBA_SPRITE(BITMAP *dst, BITMAP *src, int dx, int dy)
691 {
692 int x, y, w, h;
693 int dxbeg, dybeg;
694 int sxbeg, sybeg;
695 RGBA_BLENDER blender;
696
697 ASSERT(dst);
698 ASSERT(src);
699
700 if (dst->clip) {
701 int tmp;
702
703 tmp = dst->cl - dx;
704 sxbeg = ((tmp < 0) ? 0 : tmp);
705 dxbeg = sxbeg + dx;
706
707 tmp = dst->cr - dx;
708 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
709 if (w <= 0)
710 return;
711
712 tmp = dst->ct - dy;
713 sybeg = ((tmp < 0) ? 0 : tmp);
714 dybeg = sybeg + dy;
715
716 tmp = dst->cb - dy;
717 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
718 if (h <= 0)
719 return;
720 }
721 else {
722 w = src->w;
723 h = src->h;
724 sxbeg = 0;
725 sybeg = 0;
726 dxbeg = dx;
727 dybeg = dy;
728 }
729
730 blender = MAKE_RGBA_BLENDER();
731
732 bmp_select(dst);
733
734 for (y = 0; y < h; y++) {
735 uint32_t *s = (uint32_t *)src->line[sybeg + y] + sxbeg;
736 PIXEL_PTR ds = OFFSET_PIXEL_PTR(bmp_read_line(dst, dybeg + y), dxbeg);
737 PIXEL_PTR dd = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
738
739 for (x = w - 1; x >= 0; s++, INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), x--) {
740 unsigned long c = *s;
741
742 if (c != MASK_COLOR_32) {
743 c = RGBA_BLEND(blender, GET_PIXEL(ds), c);
744 PUT_PIXEL(dd, c);
745 }
746 }
747 }
748
749 bmp_unwrite_line(dst);
750 }
751
752 #endif
753
754
755
756 /* _linear_draw_lit_sprite:
757 * Draws a lit sprite onto a linear bitmap.
758 */
FUNC_LINEAR_DRAW_LIT_SPRITE(BITMAP * dst,BITMAP * src,int dx,int dy,int color)759 void FUNC_LINEAR_DRAW_LIT_SPRITE(BITMAP *dst, BITMAP *src, int dx, int dy, int color)
760 {
761 int x, y, w, h;
762 int dxbeg, dybeg;
763 int sxbeg, sybeg;
764 DLS_BLENDER blender;
765
766 ASSERT(dst);
767 ASSERT(src);
768
769 if (dst->clip) {
770 int tmp;
771
772 tmp = dst->cl - dx;
773 sxbeg = ((tmp < 0) ? 0 : tmp);
774 dxbeg = sxbeg + dx;
775
776 tmp = dst->cr - dx;
777 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
778 if (w <= 0)
779 return;
780
781 tmp = dst->ct - dy;
782 sybeg = ((tmp < 0) ? 0 : tmp);
783 dybeg = sybeg + dy;
784
785 tmp = dst->cb - dy;
786 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
787 if (h <= 0)
788 return;
789 }
790 else {
791 w = src->w;
792 h = src->h;
793 sxbeg = 0;
794 sybeg = 0;
795 dxbeg = dx;
796 dybeg = dy;
797 }
798
799 blender = MAKE_DLS_BLENDER(color);
800
801 if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
802 bmp_select(dst);
803
804 for (y = 0; y < h; y++) {
805 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
806 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
807
808 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
809 unsigned long c = GET_MEMORY_PIXEL(s);
810
811 if (!IS_MASK(c)) {
812 c = DLS_BLEND(blender, color, c);
813 PUT_PIXEL(d, c);
814 }
815 }
816 }
817
818 bmp_unwrite_line(dst);
819 }
820 else {
821 for (y = 0; y < h; y++) {
822 PIXEL_PTR s = OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
823 PIXEL_PTR d = OFFSET_PIXEL_PTR(dst->line[dybeg + y], dxbeg);
824
825 for (x = w - 1; x >= 0; INC_PIXEL_PTR(s), INC_PIXEL_PTR(d), x--) {
826 unsigned long c = GET_MEMORY_PIXEL(s);
827
828 if (!IS_MASK(c)) {
829 c = DLS_BLEND(blender, color, c);
830 PUT_MEMORY_PIXEL(d, c);
831 }
832 }
833 }
834 }
835 }
836
837
838
839 /* _linear_draw_character:
840 * For proportional font output onto a linear bitmap: uses the sprite as
841 * a mask, replacing all set pixels with the specified color.
842 */
FUNC_LINEAR_DRAW_CHARACTER(BITMAP * dst,BITMAP * src,int dx,int dy,int color,int bg)843 void FUNC_LINEAR_DRAW_CHARACTER(BITMAP *dst, BITMAP *src, int dx, int dy, int color, int bg)
844 {
845 int x, y, w, h;
846 int dxbeg, dybeg;
847 int sxbeg, sybeg;
848
849 ASSERT(dst);
850 ASSERT(src);
851
852 if (dst->clip) {
853 int tmp;
854
855 tmp = dst->cl - dx;
856 sxbeg = ((tmp < 0) ? 0 : tmp);
857 dxbeg = sxbeg + dx;
858
859 tmp = dst->cr - dx;
860 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
861 if (w <= 0)
862 return;
863
864 tmp = dst->ct - dy;
865 sybeg = ((tmp < 0) ? 0 : tmp);
866 dybeg = sybeg + dy;
867
868 tmp = dst->cb - dy;
869 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
870 if (h <= 0)
871 return;
872 }
873 else {
874 w = src->w;
875 h = src->h;
876 sxbeg = 0;
877 sybeg = 0;
878 dxbeg = dx;
879 dybeg = dy;
880 }
881
882 bmp_select(dst);
883
884 if (bg < 0) {
885 /* Masked character. */
886 for (y = 0; y < h; y++) {
887 unsigned char *s = src->line[sybeg + y] + sxbeg;
888 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
889
890 for (x = w - 1; x >= 0; s++, INC_PIXEL_PTR(d), x--) {
891 unsigned long c = *s;
892
893 if (c != 0) {
894 PUT_PIXEL(d, color);
895 }
896 }
897 }
898 }
899 else {
900 /* Opaque character. */
901 for (y = 0; y < h; y++) {
902 unsigned char *s = src->line[sybeg + y] + sxbeg;
903 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
904
905 for (x = w - 1; x >= 0; s++, INC_PIXEL_PTR(d), x--) {
906 unsigned long c = *s;
907
908 if (c != 0) {
909 PUT_PIXEL(d, color);
910 }
911 else {
912 PUT_PIXEL(d, bg);
913 }
914 }
915 }
916 }
917
918 bmp_unwrite_line(dst);
919 }
920
921
922
923 /* _linear_draw_rle_sprite:
924 * Draws an RLE sprite onto a linear bitmap at the specified position.
925 */
FUNC_LINEAR_DRAW_RLE_SPRITE(BITMAP * dst,AL_CONST RLE_SPRITE * src,int dx,int dy)926 void FUNC_LINEAR_DRAW_RLE_SPRITE(BITMAP *dst, AL_CONST RLE_SPRITE *src, int dx, int dy)
927 {
928 int x, y, w, h;
929 int dxbeg, dybeg;
930 int sxbeg, sybeg;
931 RLE_PTR s;
932
933 ASSERT(dst);
934 ASSERT(src);
935
936 if (dst->clip) {
937 int tmp;
938
939 tmp = dst->cl - dx;
940 sxbeg = ((tmp < 0) ? 0 : tmp);
941 dxbeg = sxbeg + dx;
942
943 tmp = dst->cr - dx;
944 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
945 if (w <= 0)
946 return;
947
948 tmp = dst->ct - dy;
949 sybeg = ((tmp < 0) ? 0 : tmp);
950 dybeg = sybeg + dy;
951
952 tmp = dst->cb - dy;
953 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
954 if (h <= 0)
955 return;
956 }
957 else {
958 w = src->w;
959 h = src->h;
960 sxbeg = 0;
961 sybeg = 0;
962 dxbeg = dx;
963 dybeg = dy;
964 }
965
966 s = (RLE_PTR) (src->dat);
967
968 /* Clip top. */
969 for (y = sybeg - 1; y >= 0; y--) {
970 long c = *s++;
971
972 while (!RLE_IS_EOL(c)) {
973 if (c > 0)
974 s += c;
975 c = *s++;
976 }
977 }
978
979 bmp_select(dst);
980
981 /* Visible part. */
982 if (sxbeg || dx+src->w >= dst->cr) {
983 for (y = 0; y < h; y++) {
984 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
985 long c = *s++;
986
987 /* Clip left. */
988 for (x = sxbeg; x > 0; ) {
989 if (RLE_IS_EOL(c))
990 goto next_line;
991 else if (c > 0) {
992 /* Run of solid pixels. */
993 if ((x - c) >= 0) {
994 /* Fully clipped. */
995 x -= c;
996 s += c;
997 }
998 else {
999 /* Visible on the right. */
1000 c -= x;
1001 s += x;
1002 break;
1003 }
1004 }
1005 else {
1006 /* Run of transparent pixels. */
1007 if ((x + c) >= 0) {
1008 /* Fully clipped. */
1009 x += c;
1010 }
1011 else {
1012 /* Visible on the right. */
1013 c += x;
1014 break;
1015 }
1016 }
1017
1018 c = *s++;
1019 }
1020
1021 /* Visible part. */
1022 for (x = w; x > 0; ) {
1023 if (RLE_IS_EOL(c))
1024 goto next_line;
1025 else if (c > 0) {
1026 /* Run of solid pixels. */
1027 if ((x - c) >= 0) {
1028 /* Fully visible. */
1029 x -= c;
1030 for (c--; c >= 0; s++, INC_PIXEL_PTR(d), c--) {
1031 unsigned long col = *s;
1032 PUT_PIXEL(d, col);
1033 }
1034 }
1035 else {
1036 /* Clipped on the right. */
1037 c -= x;
1038 for (x--; x >= 0; s++, INC_PIXEL_PTR(d), x--) {
1039 unsigned long col = *s;
1040 PUT_PIXEL(d, col);
1041 }
1042 break;
1043 }
1044 }
1045 else {
1046 /* Run of transparent pixels. */
1047 x += c;
1048 d = OFFSET_PIXEL_PTR(d, -c);
1049 }
1050
1051 c = *s++;
1052 }
1053
1054 /* Clip right. */
1055 while (!RLE_IS_EOL(c)) {
1056 if (c > 0)
1057 s += c;
1058 c = *s++;
1059 }
1060
1061 next_line: ;
1062 }
1063 }
1064 else {
1065 for (y = 0; y < h; y++) {
1066 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
1067 long c = *s++;
1068
1069 /* Visible part. */
1070 for (x = w; x > 0; ) {
1071 if (RLE_IS_EOL(c))
1072 goto next_line2;
1073 else if (c > 0) {
1074 /* Run of solid pixels. */
1075 if ((x - c) >= 0) {
1076 /* Fully visible. */
1077 x -= c;
1078 for (c--; c >= 0; s++, INC_PIXEL_PTR(d), c--) {
1079 unsigned long col = *s;
1080 PUT_PIXEL(d, col);
1081 }
1082 }
1083 else {
1084 /* Clipped on the right. */
1085 c -= x;
1086 for (x--; x >= 0; s++, INC_PIXEL_PTR(d), x--) {
1087 unsigned long col = *s;
1088 PUT_PIXEL(d, col);
1089 }
1090 break;
1091 }
1092 }
1093 else {
1094 /* Run of transparent pixels. */
1095 x += c;
1096 d = OFFSET_PIXEL_PTR(d, -c);
1097 }
1098
1099 c = *s++;
1100 }
1101
1102 next_line2: ;
1103 }
1104 }
1105
1106 bmp_unwrite_line(dst);
1107 }
1108
1109
1110
1111 /* _linear_draw_trans_rle_sprite:
1112 * Draws a translucent RLE sprite onto a linear bitmap.
1113 */
FUNC_LINEAR_DRAW_TRANS_RLE_SPRITE(BITMAP * dst,AL_CONST RLE_SPRITE * src,int dx,int dy)1114 void FUNC_LINEAR_DRAW_TRANS_RLE_SPRITE(BITMAP *dst, AL_CONST RLE_SPRITE *src, int dx, int dy)
1115 {
1116 int x, y, w, h;
1117 int dxbeg, dybeg;
1118 int sxbeg, sybeg;
1119 RLE_PTR s;
1120 DTS_BLENDER blender;
1121
1122 ASSERT(dst);
1123 ASSERT(src);
1124
1125 if (dst->clip) {
1126 int tmp;
1127
1128 tmp = dst->cl - dx;
1129 sxbeg = ((tmp < 0) ? 0 : tmp);
1130 dxbeg = sxbeg + dx;
1131
1132 tmp = dst->cr - dx;
1133 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
1134 if (w <= 0)
1135 return;
1136
1137 tmp = dst->ct - dy;
1138 sybeg = ((tmp < 0) ? 0 : tmp);
1139 dybeg = sybeg + dy;
1140
1141 tmp = dst->cb - dy;
1142 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
1143 if (h <= 0)
1144 return;
1145 }
1146 else {
1147 w = src->w;
1148 h = src->h;
1149 sxbeg = 0;
1150 sybeg = 0;
1151 dxbeg = dx;
1152 dybeg = dy;
1153 }
1154
1155 blender = MAKE_DTS_BLENDER();
1156 s = (RLE_PTR) (src->dat);
1157
1158 /* Clip top. */
1159 for (y = sybeg - 1; y >= 0; y--) {
1160 long c = *s++;
1161
1162 while (!RLE_IS_EOL(c)) {
1163 if (c > 0)
1164 s += c;
1165 c = *s++;
1166 }
1167 }
1168
1169 bmp_select(dst);
1170
1171 /* Visible part. */
1172 if (sxbeg || dx+src->w >= dst->cr) {
1173 for (y = 0; y < h; y++) {
1174 PIXEL_PTR ds = OFFSET_PIXEL_PTR(bmp_read_line(dst, dybeg + y), dxbeg);
1175 PIXEL_PTR dd = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
1176 long c = *s++;
1177
1178 /* Clip left. */
1179 for (x = sxbeg; x > 0; ) {
1180 if (RLE_IS_EOL(c))
1181 goto next_line;
1182 else if (c > 0) {
1183 /* Run of solid pixels. */
1184 if ((x - c) >= 0) {
1185 /* Fully clipped. */
1186 x -= c;
1187 s += c;
1188 }
1189 else {
1190 /* Visible on the right. */
1191 c -= x;
1192 s += x;
1193 break;
1194 }
1195 }
1196 else {
1197 /* Run of transparent pixels. */
1198 if ((x + c) >= 0) {
1199 /* Fully clipped. */
1200 x += c;
1201 }
1202 else {
1203 /* Visible on the right. */
1204 c += x;
1205 break;
1206 }
1207 }
1208
1209 c = *s++;
1210 }
1211
1212 /* Visible part. */
1213 for (x = w; x > 0; ) {
1214 if (RLE_IS_EOL(c))
1215 goto next_line;
1216 else if (c > 0) {
1217 /* Run of solid pixels. */
1218 if ((x - c) >= 0) {
1219 /* Fully visible. */
1220 x -= c;
1221 for (c--; c >= 0; s++, INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), c--) {
1222 unsigned long col = DTS_BLEND(blender, GET_PIXEL(ds), *s);
1223 PUT_PIXEL(dd, col);
1224 }
1225 }
1226 else {
1227 /* Clipped on the right. */
1228 c -= x;
1229 for (x--; x >= 0; s++, INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), x--) {
1230 unsigned long col = DTS_BLEND(blender, GET_PIXEL(ds), *s);
1231 PUT_PIXEL(dd, col);
1232 }
1233 break;
1234 }
1235 }
1236 else {
1237 /* Run of transparent pixels. */
1238 x += c;
1239 ds = OFFSET_PIXEL_PTR(ds, -c);
1240 dd = OFFSET_PIXEL_PTR(dd, -c);
1241 }
1242
1243 c = *s++;
1244 }
1245
1246 /* Clip right. */
1247 while (!RLE_IS_EOL(c)) {
1248 if (c > 0)
1249 s += c;
1250 c = *s++;
1251 }
1252
1253 next_line:{}
1254 }
1255 }
1256 else {
1257 for (y = 0; y < h; y++) {
1258 PIXEL_PTR ds = OFFSET_PIXEL_PTR(bmp_read_line(dst, dybeg + y), dxbeg);
1259 PIXEL_PTR dd = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
1260 long c = *s++;
1261
1262 /* Visible part. */
1263 for (x = w; x > 0; ) {
1264 if (RLE_IS_EOL(c))
1265 goto next_line2;
1266 else if (c > 0) {
1267 /* Run of solid pixels. */
1268 if ((x - c) >= 0) {
1269 /* Fully visible. */
1270 x -= c;
1271 for (c--; c >= 0; s++, INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), c--) {
1272 unsigned long col = DTS_BLEND(blender, GET_PIXEL(ds), *s);
1273 PUT_PIXEL(dd, col);
1274 }
1275 }
1276 else {
1277 /* Clipped on the right. */
1278 c -= x;
1279 for (x--; x >= 0; s++, INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), x--) {
1280 unsigned long col = DTS_BLEND(blender, GET_PIXEL(ds), *s);
1281 PUT_PIXEL(dd, col);
1282 }
1283 break;
1284 }
1285 }
1286 else {
1287 /* Run of transparent pixels. */
1288 x += c;
1289 ds = OFFSET_PIXEL_PTR(ds, -c);
1290 dd = OFFSET_PIXEL_PTR(dd, -c);
1291 }
1292
1293 c = *s++;
1294 }
1295
1296 /* Clip right. */
1297 while (!RLE_IS_EOL(c)) {
1298 if (c > 0)
1299 s += c;
1300 c = *s++;
1301 }
1302
1303 next_line2:{}
1304 }
1305 }
1306
1307 bmp_unwrite_line(dst);
1308 }
1309
1310
1311
1312 #if (PP_DEPTH != 8) && (PP_DEPTH != 32)
1313
1314 /* _linear_draw_trans_rgba_rle_sprite:
1315 * Draws a translucent RGBA RLE sprite onto a linear bitmap.
1316 */
FUNC_LINEAR_DRAW_TRANS_RGBA_RLE_SPRITE(BITMAP * dst,AL_CONST RLE_SPRITE * src,int dx,int dy)1317 void FUNC_LINEAR_DRAW_TRANS_RGBA_RLE_SPRITE(BITMAP *dst, AL_CONST RLE_SPRITE *src, int dx, int dy)
1318 {
1319 int x, y, w, h;
1320 int dxbeg, dybeg;
1321 int sxbeg, sybeg;
1322 uint32_t *s;
1323 RGBA_BLENDER blender;
1324
1325 ASSERT(dst);
1326 ASSERT(src);
1327
1328 if (dst->clip) {
1329 int tmp;
1330
1331 tmp = dst->cl - dx;
1332 sxbeg = ((tmp < 0) ? 0 : tmp);
1333 dxbeg = sxbeg + dx;
1334
1335 tmp = dst->cr - dx;
1336 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
1337 if (w <= 0)
1338 return;
1339
1340 tmp = dst->ct - dy;
1341 sybeg = ((tmp < 0) ? 0 : tmp);
1342 dybeg = sybeg + dy;
1343
1344 tmp = dst->cb - dy;
1345 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
1346 if (h <= 0)
1347 return;
1348 }
1349 else {
1350 w = src->w;
1351 h = src->h;
1352 sxbeg = 0;
1353 sybeg = 0;
1354 dxbeg = dx;
1355 dybeg = dy;
1356 }
1357
1358 blender = MAKE_RGBA_BLENDER();
1359 s = (uint32_t *) (src->dat);
1360
1361 /* Clip top. */
1362 for (y = sybeg - 1; y >= 0; y--) {
1363 long c = *s++;
1364
1365 while (c != MASK_COLOR_32) {
1366 if (c > 0)
1367 s += c;
1368 c = *s++;
1369 }
1370 }
1371
1372 bmp_select(dst);
1373
1374 /* Visible part. */
1375 if (sxbeg || dx+src->w >= dst->cr) {
1376 for (y = 0; y < h; y++) {
1377 PIXEL_PTR ds = OFFSET_PIXEL_PTR(bmp_read_line(dst, dybeg + y), dxbeg);
1378 PIXEL_PTR dd = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
1379 long c = *s++;
1380
1381 /* Clip left. */
1382 for (x = sxbeg; x > 0; ) {
1383 if (c == MASK_COLOR_32)
1384 goto next_line;
1385 else if (c > 0) {
1386 /* Run of solid pixels. */
1387 if ((x - c) >= 0) {
1388 /* Fully clipped. */
1389 x -= c;
1390 s += c;
1391 }
1392 else {
1393 /* Visible on the right. */
1394 c -= x;
1395 s += x;
1396 break;
1397 }
1398 }
1399 else {
1400 /* Run of transparent pixels. */
1401 if ((x + c) >= 0) {
1402 /* Fully clipped. */
1403 x += c;
1404 }
1405 else {
1406 /* Visible on the right. */
1407 c += x;
1408 break;
1409 }
1410 }
1411
1412 c = *s++;
1413 }
1414
1415 /* Visible part. */
1416 for (x = w; x > 0; ) {
1417 if (c == MASK_COLOR_32)
1418 goto next_line;
1419 else if (c > 0) {
1420 /* Run of solid pixels. */
1421 if ((x - c) >= 0) {
1422 /* Fully visible. */
1423 x -= c;
1424 for (c--; c >= 0; s++, INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), c--) {
1425 unsigned long col = RGBA_BLEND(blender, GET_PIXEL(ds), *s);
1426 PUT_PIXEL(dd, col);
1427 }
1428 }
1429 else {
1430 /* Clipped on the right. */
1431 c -= x;
1432 for (x--; x >= 0; s++, INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), x--) {
1433 unsigned long col = RGBA_BLEND(blender, GET_PIXEL(ds), *s);
1434 PUT_PIXEL(dd, col);
1435 }
1436 break;
1437 }
1438 }
1439 else {
1440 /* Run of transparent pixels. */
1441 x += c;
1442 ds = OFFSET_PIXEL_PTR(ds, -c);
1443 dd = OFFSET_PIXEL_PTR(dd, -c);
1444 }
1445
1446 c = *s++;
1447 }
1448
1449 /* Clip right. */
1450 while (c != MASK_COLOR_32) {
1451 if (c > 0)
1452 s += c;
1453 c = *s++;
1454 }
1455
1456 next_line:{}
1457 }
1458 }
1459 else {
1460 for (y = 0; y < h; y++) {
1461 PIXEL_PTR ds = OFFSET_PIXEL_PTR(bmp_read_line(dst, dybeg + y), dxbeg);
1462 PIXEL_PTR dd = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
1463 long c = *s++;
1464
1465 /* Visible part. */
1466 for (x = w; x > 0; ) {
1467 if (c == MASK_COLOR_32)
1468 goto next_line2;
1469 else if (c > 0) {
1470 /* Run of solid pixels. */
1471 if ((x - c) >= 0) {
1472 /* Fully visible. */
1473 x -= c;
1474 for (c--; c >= 0; s++, INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), c--) {
1475 unsigned long col = RGBA_BLEND(blender, GET_PIXEL(ds), *s);
1476 PUT_PIXEL(dd, col);
1477 }
1478 }
1479 else {
1480 /* Clipped on the right. */
1481 c -= x;
1482 for (x--; x >= 0; s++, INC_PIXEL_PTR(ds), INC_PIXEL_PTR(dd), x--) {
1483 unsigned long col = RGBA_BLEND(blender, GET_PIXEL(ds), *s);
1484 PUT_PIXEL(dd, col);
1485 }
1486 break;
1487 }
1488 }
1489 else {
1490 /* Run of transparent pixels. */
1491 x += c;
1492 ds = OFFSET_PIXEL_PTR(ds, -c);
1493 dd = OFFSET_PIXEL_PTR(dd, -c);
1494 }
1495
1496 c = *s++;
1497 }
1498
1499 next_line2:{}
1500 }
1501 }
1502
1503 bmp_unwrite_line(dst);
1504 }
1505
1506 #endif
1507
1508
1509
1510 /* _linear_draw_lit_rle_sprite:
1511 * Draws a tinted RLE sprite onto a linear bitmap.
1512 */
FUNC_LINEAR_DRAW_LIT_RLE_SPRITE(BITMAP * dst,AL_CONST RLE_SPRITE * src,int dx,int dy,int color)1513 void FUNC_LINEAR_DRAW_LIT_RLE_SPRITE(BITMAP *dst, AL_CONST RLE_SPRITE *src, int dx, int dy, int color)
1514 {
1515 int x, y, w, h;
1516 int dxbeg, dybeg;
1517 int sxbeg, sybeg;
1518 RLE_PTR s;
1519 DLS_BLENDER blender;
1520
1521 ASSERT(dst);
1522 ASSERT(src);
1523
1524 if (dst->clip) {
1525 int tmp;
1526
1527 tmp = dst->cl - dx;
1528 sxbeg = ((tmp < 0) ? 0 : tmp);
1529 dxbeg = sxbeg + dx;
1530
1531 tmp = dst->cr - dx;
1532 w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
1533 if (w <= 0)
1534 return;
1535
1536 tmp = dst->ct - dy;
1537 sybeg = ((tmp < 0) ? 0 : tmp);
1538 dybeg = sybeg + dy;
1539
1540 tmp = dst->cb - dy;
1541 h = ((tmp > src->h) ? src->h : tmp) - sybeg;
1542 if (h <= 0)
1543 return;
1544 }
1545 else {
1546 w = src->w;
1547 h = src->h;
1548 sxbeg = 0;
1549 sybeg = 0;
1550 dxbeg = dx;
1551 dybeg = dy;
1552 }
1553
1554 blender = MAKE_DLS_BLENDER(color);
1555 s = (RLE_PTR) (src->dat);
1556
1557 /* Clip top. */
1558 for (y = sybeg - 1; y >= 0; y--) {
1559 long c = *s++;
1560
1561 while (!RLE_IS_EOL(c)) {
1562 if (c > 0)
1563 s += c;
1564 c = *s++;
1565 }
1566 }
1567
1568 bmp_select(dst);
1569
1570 /* Visible part. */
1571 if (sxbeg || dx+src->w >= dst->cr) {
1572 for (y = 0; y < h; y++) {
1573 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
1574 long c = *s++;
1575
1576 /* Clip left. */
1577 for (x = sxbeg; x > 0; ) {
1578 if (RLE_IS_EOL(c))
1579 goto next_line;
1580 else if (c > 0) {
1581 /* Run of solid pixels. */
1582 if ((x - c) >= 0) {
1583 /* Fully clipped. */
1584 x -= c;
1585 s += c;
1586 }
1587 else {
1588 /* Visible on the right. */
1589 c -= x;
1590 s += x;
1591 break;
1592 }
1593 }
1594 else {
1595 /* Run of transparent pixels. */
1596 if ((x + c) >= 0) {
1597 /* Fully clipped. */
1598 x += c;
1599 }
1600 else {
1601 /* Visible on the right. */
1602 c += x;
1603 break;
1604 }
1605 }
1606
1607 c = *s++;
1608 }
1609
1610 /* Visible part. */
1611 for (x = w; x > 0; ) {
1612 if (RLE_IS_EOL(c))
1613 goto next_line;
1614 else if (c > 0) {
1615 /* Run of solid pixels. */
1616 if ((x - c) >= 0) {
1617 /* Fully visible. */
1618 x -= c;
1619 for (c--; c >= 0; s++, INC_PIXEL_PTR(d), c--) {
1620 unsigned long col = DLS_BLEND(blender, color, *s);
1621 PUT_PIXEL(d, col);
1622 }
1623 }
1624 else {
1625 /* Clipped on the right. */
1626 c -= x;
1627 for (x--; x >= 0; s++, INC_PIXEL_PTR(d), x--) {
1628 unsigned long col = DLS_BLEND(blender, color, *s);
1629 PUT_PIXEL(d, col);
1630 }
1631 break;
1632 }
1633 }
1634 else {
1635 /* Run of transparent pixels. */
1636 x += c;
1637 d = OFFSET_PIXEL_PTR(d, -c);
1638 }
1639
1640 c = *s++;
1641 }
1642
1643 /* Clip right. */
1644 while (!RLE_IS_EOL(c)) {
1645 if (c > 0)
1646 s += c;
1647 c = *s++;
1648 }
1649
1650 next_line:{}
1651
1652 }
1653 }
1654 else {
1655 for (y = 0; y < h; y++) {
1656 PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
1657 long c = *s++;
1658
1659 /* Visible part. */
1660 for (x = w; x > 0; ) {
1661 if (RLE_IS_EOL(c))
1662 goto next_line2;
1663 else if (c > 0) {
1664 /* Run of solid pixels. */
1665 if ((x - c) >= 0) {
1666 /* Fully visible. */
1667 x -= c;
1668 for (c--; c >= 0; s++, INC_PIXEL_PTR(d), c--) {
1669 unsigned long col = DLS_BLEND(blender, color, *s);
1670 PUT_PIXEL(d, col);
1671 }
1672 }
1673 else {
1674 /* Clipped on the right. */
1675 c -= x;
1676 for (x--; x >= 0; s++, INC_PIXEL_PTR(d), x--) {
1677 unsigned long col = DLS_BLEND(blender, color, *s);
1678 PUT_PIXEL(d, col);
1679 }
1680 break;
1681 }
1682 }
1683 else {
1684 /* Run of transparent pixels. */
1685 x += c;
1686 d = OFFSET_PIXEL_PTR(d, -c);
1687 }
1688
1689 c = *s++;
1690 }
1691
1692 next_line2:{}
1693 }
1694 }
1695
1696 bmp_unwrite_line(dst);
1697 }
1698
1699 #endif /* !__bma_cspr_h */
1700
1701