--- uae/src/gfxutil.c 2018/04/24 16:39:49 1.1.1.3 +++ uae/src/gfxutil.c 2018/04/24 16:41:57 1.1.1.4 @@ -27,13 +27,13 @@ */ static uae_u8 dither[4][4] = { - {0,8,2,10}, - {12,4,14,6}, - {3,11,1,9}, - {14 /* 15 */,7,13,5} + { 0, 8, 2, 10 }, + { 12, 4, 14, 6 }, + { 3, 11, 1, 9 }, + { 14 /* 15 */, 7, 13, 5 } }; -unsigned long doMask(int p, int bits, int shift) +unsigned long doMask (int p, int bits, int shift) { /* p is a value from 0 to 15 (Amiga color value) * scale to 0..255, shift to align msb with mask, and apply mask */ @@ -45,10 +45,42 @@ unsigned long doMask(int p, int bits, in return val; } -void alloc_colors64k(int rw, int gw, int bw, int rs, int gs, int bs) +int bits_in_mask (unsigned long mask) +{ + int n = 0; + while (mask) { + n += mask & 1; + mask >>= 1; + } + return n; +} + +int mask_shift (unsigned long mask) +{ + int n = 0; + while (!(mask & 1)) { + n++; + mask >>= 1; + } + return n; +} + +unsigned long doMask256 (int p, int bits, int shift) +{ + /* p is a value from 0 to 255 (Amiga color value) + * shift to align msb with mask, and apply mask */ + + unsigned long val = p * 0x01010101UL; + val >>= (32 - bits); + val <<= shift; + + return val; +} + +void alloc_colors64k (int rw, int gw, int bw, int rs, int gs, int bs) { int i; - for(i=0; i<4096; i++) { + for (i = 0; i < 4096; i++) { int r = i >> 8; int g = (i >> 4) & 0xF; int b = i & 0xF; @@ -60,12 +92,12 @@ static int allocated[4096]; static int color_diff[4096]; static int newmaxcol = 0; -void setup_maxcol(int max) +void setup_maxcol (int max) { newmaxcol = max; } -void alloc_colors256(allocfunc_type allocfunc) +void alloc_colors256 (allocfunc_type allocfunc) { int nb_cols[3]; /* r,g,b */ int maxcol = newmaxcol == 0 ? 256 : newmaxcol; @@ -73,16 +105,16 @@ void alloc_colors256(allocfunc_type allo xcolnr *map; - map = (xcolnr *)malloc(sizeof(xcolnr) * maxcol); - if(!map) { - write_log("Not enough mem for colormap!\n"); - abort(); + map = (xcolnr *)malloc (sizeof(xcolnr) * maxcol); + if (!map) { + write_log ("Not enough mem for colormap!\n"); + abort (); } /* * compute #cols per components */ - for(i = 1; i*i*i <= maxcol; ++i) + for (i = 1; i*i*i <= maxcol; ++i) ; --i; @@ -93,15 +125,15 @@ void alloc_colors256(allocfunc_type allo /* * set the colormap */ - l=0; - for(i = 0; i < nb_cols[RED]; ++i) { + l = 0; + for (i = 0; i < nb_cols[RED]; ++i) { int r = (i * 15) / (nb_cols[RED] - 1); - for(j = 0; j < nb_cols[GRN]; ++j) { + for (j = 0; j < nb_cols[GRN]; ++j) { int g = (j * 15) / (nb_cols[GRN] - 1); - for(k = 0; k < nb_cols[BLU]; ++k) { + for (k = 0; k < nb_cols[BLU]; ++k) { int b = (k * 15) / (nb_cols[BLU] - 1); int result; - result = allocfunc(r, g, b, map + l); + result = allocfunc (r, g, b, map + l); l++; } } @@ -114,32 +146,32 @@ void alloc_colors256(allocfunc_type allo { int diffr, diffg, diffb, maxdiff = 0, won = 0, lost; int r, d = 8; - for(r=0; r<16; ++r) { + for (r = 0; r < 16; ++r) { int cr, g, q; - k = nb_cols[RED]-1; + k = nb_cols[RED]-1; cr = (r * k) / 15; - q = (r * k) % 15; - if(q > d && cr < k) ++cr; - diffr = abs(cr*k-r); - for(g=0; g<16; ++g) { + q = (r * k) % 15; + if (q > d && cr < k) ++cr; + diffr = abs (cr*k - r); + for (g = 0; g < 16; ++g) { int cg, b; - k = nb_cols[GRN]-1; + k = nb_cols[GRN]-1; cg = (g * k) / 15; q = (g * k) % 15; - if(q > d && cg < k) ++cg; - diffg = abs(cg*k-g); - for(b=0; b<16; ++b) { - int cb, rgb = (r<<8) | (g<<4) | b; + if (q > d && cg < k) ++cg; + diffg = abs (cg*k - g); + for (b = 0; b < 16; ++b) { + int cb, rgb = (r << 8) | (g << 4) | b; - k = nb_cols[BLU]-1; + k = nb_cols[BLU]-1; cb = (b * k) / 15; - q = (b * k) % 15; - if(q > d && cb < k) ++cb; - diffb = abs(cb*k-b); - xcolors[rgb] = map[(cr*nb_cols[GRN]+cg)*nb_cols[BLU]+cb]; - color_diff[rgb] = diffr+diffg+diffb; + q = (b * k) % 15; + if (q > d && cb < k) ++cb; + diffb = abs (cb*k - b); + xcolors[rgb] = map[(cr * nb_cols[GRN] + cg) * nb_cols[BLU] + cb]; + color_diff[rgb] = diffr + diffg + diffb; if (color_diff[rgb] > maxdiff) maxdiff = color_diff[rgb]; } @@ -148,14 +180,14 @@ void alloc_colors256(allocfunc_type allo while (maxdiff > 0 && l < maxcol) { int newmaxdiff = 0; lost = 0; won++; - for(r = 15; r >= 0; r--) { - int cr, g, q; + for (r = 15; r >= 0; r--) { + int g; - for(g = 15; g >= 0; g--) { - int cg, b; + for (g = 15; g >= 0; g--) { + int b; - for(b = 15; b >= 0; b--) { - int cb, rgb = (r<<8) | (g<<4) | b; + for (b = 15; b >= 0; b--) { + int rgb = (r << 8) | (g << 4) | b; if (color_diff[rgb] == maxdiff) { int result; @@ -163,7 +195,7 @@ void alloc_colors256(allocfunc_type allo if (l >= maxcol) lost++; else { - result = allocfunc(r, g, b, xcolors + rgb); + result = allocfunc (r, g, b, xcolors + rgb); l++; } color_diff[rgb] = 0; @@ -196,24 +228,24 @@ uae_u8 cidx[4][8*4096]; /* fast, but mem /* * Compute dithering structures */ -void setup_greydither_maxcol(int maxcol, allocfunc_type allocfunc) +void setup_greydither_maxcol (int maxcol, allocfunc_type allocfunc) { - int i,j,k,l,t; + int i,j,k; xcolnr *map; for (i = 0; i < 4096; i++) xcolors[i] = i; - map = (xcolnr *)malloc(sizeof(xcolnr) * maxcol); - if(!map) { - write_log("Not enough mem for colormap!\n"); + map = (xcolnr *)malloc (sizeof(xcolnr) * maxcol); + if (!map) { + write_log ("Not enough mem for colormap!\n"); abort(); } /* * set the colormap */ - for(i = 0; i < maxcol; ++i) { + for (i = 0; i < maxcol; ++i) { int c, result; c = (15 * i + (maxcol-1)/2) / (maxcol - 1); result = allocfunc(c, c, c, map + i); @@ -223,15 +255,15 @@ void setup_greydither_maxcol(int maxcol, /* * for each componant compute the mapping */ - for(i=0;i<4;++i) { - for(j=0;j<4;++j) { + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { int r, d = dither[i][j]*17; - for(r=0; r<16; ++r) { + for (r = 0; r<16; ++r) { int g; - for(g=0; g<16; ++g) { + for (g = 0; g < 16; ++g) { int b; - for(b=0; b<16; ++b) { - int rgb = (r<<8) | (g<<4) | b; + for (b = 0; b < 16; ++b) { + int rgb = (r << 8) | (g << 4) | b; int c,p,q; c = (77 * r + @@ -241,7 +273,7 @@ void setup_greydither_maxcol(int maxcol, k = maxcol-1; p = (c * k) / 256; q = (c * k) % 256; - if(q /*/ k*/> d /*/ k*/ && p < k) ++p; + if (q /*/ k*/> d /*/ k*/ && p < k) ++p; /* sam: ^^^^^^^ */ /* It seems that produces better output */ cidx[i][rgb + (j+4)*4096] = @@ -254,23 +286,23 @@ void setup_greydither_maxcol(int maxcol, free (map); } -void setup_greydither(int bits, allocfunc_type allocfunc) +void setup_greydither (int bits, allocfunc_type allocfunc) { setup_greydither_maxcol(1 << bits, allocfunc); } -void setup_dither(int bits, allocfunc_type allocfunc) +void setup_dither (int bits, allocfunc_type allocfunc) { int nb_cols[3]; /* r,g,b */ int maxcol = 1 << bits; - int i,j,k,l,t; + int i,j,k,l; xcolnr *map; int *redvals, *grnvals, *bluvals; - map = (xcolnr *)malloc(sizeof(xcolnr) * maxcol); - if(!map) { - write_log("Not enough mem for colormap!\n"); + map = (xcolnr *)malloc (sizeof(xcolnr) * maxcol); + if (!map) { + write_log ("Not enough mem for colormap!\n"); abort(); } @@ -280,7 +312,7 @@ void setup_dither(int bits, allocfunc_ty /* * compute #cols per components */ - for(i = 1; i*i*i <= maxcol; ++i) + for (i = 1; i*i*i <= maxcol; ++i) ; --i; @@ -288,25 +320,26 @@ void setup_dither(int bits, allocfunc_ty nb_cols[GRN] = i; nb_cols[BLU] = i; - if(nb_cols[RED]*(++i)*nb_cols[BLU] <= maxcol) { + if (nb_cols[RED]*(++i)*nb_cols[BLU] <= maxcol) { nb_cols[GRN] = i; - if((i)*nb_cols[GRN]*nb_cols[BLU] <= maxcol) nb_cols[RED] = i; + if ((i)*nb_cols[GRN]*nb_cols[BLU] <= maxcol) + nb_cols[RED] = i; } - redvals = (int *)malloc(sizeof(int) * maxcol); + redvals = (int *)malloc (sizeof(int) * maxcol); grnvals = redvals + nb_cols[RED]; bluvals = grnvals + nb_cols[GRN]; /* * set the colormap */ - l=0; - for(i = 0; i < nb_cols[RED]; ++i) { + l = 0; + for (i = 0; i < nb_cols[RED]; ++i) { int r = (i * 15) / (nb_cols[RED] - 1); redvals[i] = r; - for(j = 0; j < nb_cols[GRN]; ++j) { + for (j = 0; j < nb_cols[GRN]; ++j) { int g = (j * 15) / (nb_cols[GRN] - 1); grnvals[j] = g; - for(k = 0; k < nb_cols[BLU]; ++k) { + for (k = 0; k < nb_cols[BLU]; ++k) { int b = (k * 15) / (nb_cols[BLU] - 1); int result; bluvals[k] = b; @@ -322,67 +355,74 @@ void setup_dither(int bits, allocfunc_ty */ { int r; - for(r=0; r<16; ++r) { + for (r = 0; r < 16; ++r) { int g; - for(g=0; g<16; ++g) { + for (g = 0; g < 16; ++g) { int b; - for(b=0; b<16; ++b) { - int rederr = 0, grnerr = 0, bluerr = 0; - int rgb = (r<<8) | (g<<4) | b; + for (b = 0; b < 16; ++b) { + int rgb = (r << 8) | (g << 4) | b; - for(i=0;i<4;++i) for(j=0;j<4;++j) { + for (i = 0; i < 4; ++i) for (j = 0; j < 4; ++j) { int d = dither[i][j]; int cr, cg, cb, k, q; #if 0 /* Slightly different algorithm. Needs some tuning. */ + int rederr = 0, grnerr = 0, bluerr = 0; + k = nb_cols[RED]-1; cr = r * k / 15; q = r * k - 15*cr; - if (cr < 0) cr = 0; - else - if(q / k > d / k && rederr <= 0) ++cr; + if (cr < 0) + cr = 0; + else if (q / k > d / k && rederr <= 0) + ++cr; if (cr > k) cr = k; rederr += redvals[cr]-r; k = nb_cols[GRN]-1; cg = g * k / 15; q = g * k - 15*cg; - if (cg < 0) cg = 0; - else - if (q / k > d / k && grnerr <= 0) ++cg; + if (cg < 0) + cg = 0; + else if (q / k > d / k && grnerr <= 0) + ++cg; if (cg > k) cg = k; grnerr += grnvals[cg]-g; k = nb_cols[BLU]-1; cb = b * k / 15; q = b * k - 15*cb; - if (cb < 0) cb = 0; - else - if (q / k > d / k && bluerr <= 0) ++cb; + if (cb < 0) + cb = 0; + else if (q / k > d / k && bluerr <= 0) + ++cb; if (cb > k) cb = k; bluerr += bluvals[cb]-b; #else k = nb_cols[RED]-1; cr = r * k / 15; q = r * k - 15*cr; - if (cr < 0) cr = 0; - else - if(q /*/ k*/ > d /*/ k*/) ++cr; + if (cr < 0) + cr = 0; + else if (q /*/ k*/ > d /*/ k*/) + ++cr; if (cr > k) cr = k; k = nb_cols[GRN]-1; cg = g * k / 15; q = g * k - 15*cg; - if (cg < 0) cg = 0; - else - if (q /*/ k*/ > d /*/ k*/) ++cg; + if (cg < 0) + cg = 0; + else if (q /*/ k*/ > d /*/ k*/) + ++cg; if (cg > k) cg = k; k = nb_cols[BLU]-1; cb = b * k / 15; q = b * k - 15*cb; - if (cb < 0) cb = 0; - else - if (q /*/ k*/ > d /*/ k*/) ++cb; + if (cb < 0) + cb = 0; + else if (q /*/ k*/ > d /*/ k*/) + ++cb; if (cb > k) cb = k; #endif cidx[i][rgb + (j+4)*4096] = cidx[i][rgb + j*4096] = map[(cr*nb_cols[GRN]+cg)*nb_cols[BLU]+cb]; @@ -391,6 +431,7 @@ void setup_dither(int bits, allocfunc_ty } } } + free (redvals); free (map); } @@ -401,14 +442,14 @@ void setup_dither(int bits, allocfunc_ty * yourself unhappy. */ -void DitherLine(uae_u8 *l, uae_u16 *r4g4b4, int x, int y, uae_s16 len, int bits) +void DitherLine (uae_u8 *l, uae_u16 *r4g4b4, int x, int y, uae_s16 len, int bits) { uae_u8 *dith = cidx[y&3]+(x&3)*4096; uae_u8 d = 0; int bitsleft = 8; - if(bits == 8) { - while(len>0) { + if (bits == 8) { + while (len > 0) { *l++ = dith[0*4096 + *r4g4b4++]; *l++ = dith[1*4096 + *r4g4b4++]; *l++ = dith[2*4096 + *r4g4b4++]; @@ -418,7 +459,7 @@ void DitherLine(uae_u8 *l, uae_u16 *r4g4 return; } - while(len) { + while (len) { int v; v = dith[0*4096 + *r4g4b4++]; bitsleft -= bits;