00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "mmsgui/fb/mmsfbconv.h"
00034
00035 #ifdef __HAVE_PF_AiRGB__
00036
00037 #include "mmstools/mmstools.h"
00038
00039 void mmsfb_stretchblit_blend_coloralpha_airgb_to_airgb(MMSFBExternalSurfaceBuffer *extbuf, int src_height, int sx, int sy, int sw, int sh,
00040 unsigned int *dst, int dst_pitch, int dst_height, int dx, int dy, int dw, int dh,
00041 unsigned char alpha) {
00042
00043 if (alpha == 0xff) {
00044
00045 mmsfb_stretchblit_blend_airgb_to_airgb(extbuf, src_height, sx, sy, sw, sh,
00046 dst, dst_pitch, dst_height, dx, dy, dw, dh);
00047 return;
00048 }
00049
00050
00051 static bool firsttime = true;
00052 if (firsttime) {
00053 printf("DISKO: Using accelerated stretch & blend coloralpha AiRGB to AiRGB.\n");
00054 firsttime = false;
00055 }
00056
00057
00058 if (!alpha)
00059
00060 return;
00061
00062
00063 unsigned int *src = (unsigned int *)extbuf->ptr;
00064 int src_pitch = extbuf->pitch;
00065
00066
00067 int src_pitch_pix = src_pitch >> 2;
00068 int dst_pitch_pix = dst_pitch >> 2;
00069 unsigned int *src_end = src + sx + src_pitch_pix * (sy + sh);
00070 if (src_end > src + src_pitch_pix * src_height)
00071 src_end = src + src_pitch_pix * src_height;
00072 unsigned int *dst_end = dst + dst_pitch_pix * dst_height;
00073 src+=sx + sy * src_pitch_pix;
00074 dst+=dx + dy * dst_pitch_pix;
00075
00076 int horifact = (dw<<16)/sw;
00077 int vertfact = (dh<<16)/sh;
00078
00079
00080 register unsigned int ALPHA = alpha;
00081 ALPHA++;
00082
00083
00084
00085 int vertcnt = 0x8000;
00086 while ((src < src_end)&&(dst < dst_end)) {
00087
00088 vertcnt+=vertfact;
00089 if (vertcnt & 0xffff0000) {
00090 unsigned int *line_end = src + sw;
00091 unsigned int *old_dst = dst;
00092
00093 do {
00094 int horicnt = 0x8000;
00095 while (src < line_end) {
00096
00097
00098 horicnt+=horifact;
00099
00100 if (horicnt & 0xffff0000) {
00101 register unsigned int SRC = *src;
00102 register unsigned int A = SRC >> 24;
00103
00104 if (A == 0xff) {
00105
00106 do {
00107 dst++;
00108 horicnt-=0x10000;
00109 } while (horicnt & 0xffff0000);
00110 }
00111 else
00112 {
00113
00114 register unsigned int DST = *dst;
00115 unsigned int OLDDST = DST + 1;
00116 register unsigned int d;
00117
00118
00119 A = 0x100 - ((ALPHA * (0x100 - A)) >> 8);
00120 unsigned int sr = (ALPHA * (SRC & 0xff0000)) >> 24;
00121 unsigned int sg = (ALPHA * (SRC & 0xff00)) >> 16;
00122 unsigned int sb = (ALPHA * (SRC & 0xff)) >> 8;
00123
00124 do {
00125 if (DST==OLDDST) {
00126
00127 if (A < 0xff) {
00128
00129 *dst = d;
00130 }
00131 dst++;
00132 DST = *dst;
00133 horicnt-=0x10000;
00134 continue;
00135 }
00136 OLDDST = DST;
00137
00138
00139 unsigned int a = DST >> 24;
00140 unsigned int r = (DST << 8) >> 24;
00141 unsigned int g = (DST << 16) >> 24;
00142 unsigned int b = DST & 0xff;
00143
00144
00145 a = (A * (0x100 - a)) >> 8;
00146 r = (A * r) >> 8;
00147 g = (A * g) >> 8;
00148 b = (A * b) >> 8;
00149
00150
00151 a += 0x100 - A;
00152 r += sr;
00153 g += sg;
00154 b += sb;
00155 d = ((r >> 8) ? 0xff0000 : (r << 16))
00156 | ((g >> 8) ? 0xff00 : (g << 8))
00157 | ((b >> 8) ? 0xff : b);
00158 if (!(a >> 8)) d |= (0x100 - a) << 24;
00159 *dst = d;
00160 dst++;
00161 DST = *dst;
00162 horicnt-=0x10000;
00163 } while (horicnt & 0xffff0000);
00164 }
00165 }
00166
00167 src++;
00168 }
00169 src-=sw;
00170 vertcnt-=0x10000;
00171 dst = old_dst + dst_pitch/4;
00172 old_dst = dst;
00173 } while (vertcnt & 0xffff0000);
00174 }
00175
00176
00177 src+=src_pitch/4;
00178 }
00179 }
00180
00181 #endif