Annotation of uae/src/gfxutil.c, revision 1.1.1.3

1.1.1.3 ! root        1:  /*
1.1       root        2:   * UAE - The Un*x Amiga Emulator
1.1.1.3 ! root        3:   *
1.1       root        4:   * Common code needed by all the various graphics systems.
1.1.1.3 ! root        5:   *
1.1       root        6:   * (c) 1996 Bernd Schmidt, Ed Hanway, Samuel Devulder
                      7:   */
                      8: 
                      9: #include "sysconfig.h"
                     10: #include "sysdeps.h"
                     11: 
                     12: #include "config.h"
                     13: #include "options.h"
1.1.1.3 ! root       14: #include "threaddep/penguin.h"
1.1       root       15: #include "memory.h"
                     16: #include "custom.h"
                     17: #include "keyboard.h"
                     18: #include "xwin.h"
                     19: #include "keybuf.h"
                     20: 
                     21: #define        RED     0
                     22: #define        GRN     1
                     23: #define        BLU     2
                     24: 
                     25: /*
                     26:  * dither matrix
                     27:  */
1.1.1.3 ! root       28: static uae_u8 dither[4][4] =
1.1       root       29: {
                     30:   {0,8,2,10},
                     31:   {12,4,14,6},
                     32:   {3,11,1,9},
                     33:   {14 /* 15 */,7,13,5}
                     34: };
                     35: 
                     36: unsigned long doMask(int p, int bits, int shift)
                     37: {
                     38:     /* p is a value from 0 to 15 (Amiga color value)
                     39:      * scale to 0..255, shift to align msb with mask, and apply mask */
                     40: 
                     41:     unsigned long val = p * 0x11111111UL;
                     42:     val >>= (32 - bits);
                     43:     val <<= shift;
                     44: 
                     45:     return val;
                     46: }
                     47: 
                     48: void alloc_colors64k(int rw, int gw, int bw, int rs, int gs, int bs)
                     49: {
                     50:     int i;
                     51:     for(i=0; i<4096; i++) {
                     52:        int r = i >> 8;
                     53:        int g = (i >> 4) & 0xF;
                     54:        int b = i & 0xF;
                     55:        xcolors[i] = doMask(r, rw, rs) | doMask(g, gw, gs) | doMask(b, bw, bs);
                     56:     }
                     57: }
                     58: 
                     59: static int allocated[4096];
1.1.1.2   root       60: static int color_diff[4096];
                     61: static int newmaxcol = 0;
                     62: 
                     63: void setup_maxcol(int max)
                     64: {
                     65:     newmaxcol = max;
                     66: }
1.1       root       67: 
                     68: void alloc_colors256(allocfunc_type allocfunc)
                     69: {
                     70:     int nb_cols[3]; /* r,g,b */
1.1.1.2   root       71:     int maxcol = newmaxcol == 0 ? 256 : newmaxcol;
1.1       root       72:     int i,j,k,l,t;
                     73: 
                     74:     xcolnr *map;
1.1.1.3 ! root       75: 
1.1       root       76:     map = (xcolnr *)malloc(sizeof(xcolnr) * maxcol);
1.1.1.3 ! root       77:     if(!map) {
        !            78:        write_log("Not enough mem for colormap!\n");
        !            79:        abort();
        !            80:     }
        !            81: 
1.1       root       82:     /*
                     83:      * compute #cols per components
                     84:      */
                     85:     for(i = 1; i*i*i <= maxcol; ++i)
                     86:        ;
                     87:     --i;
                     88: 
                     89:     nb_cols[RED] = i;
                     90:     nb_cols[GRN] = i;
                     91:     nb_cols[BLU] = i;
                     92: 
                     93:     /*
                     94:      * set the colormap
                     95:      */
                     96:     l=0;
                     97:     for(i = 0; i < nb_cols[RED]; ++i) {
1.1.1.3 ! root       98:        int r = (i * 15) / (nb_cols[RED] - 1);
1.1       root       99:        for(j = 0; j < nb_cols[GRN]; ++j) {
1.1.1.3 ! root      100:            int g = (j * 15) / (nb_cols[GRN] - 1);
        !           101:            for(k = 0; k < nb_cols[BLU]; ++k) {
        !           102:                int b = (k * 15) / (nb_cols[BLU] - 1);
1.1       root      103:                int result;
                    104:                result = allocfunc(r, g, b, map + l);
                    105:                l++;
                    106:            }
                    107:        }
                    108:     }
                    109: /*    printf("%d color(s) lost\n",maxcol - l);*/
                    110: 
                    111:     /*
                    112:      * for each component compute the mapping
                    113:      */
                    114:     {
                    115:        int diffr, diffg, diffb, maxdiff = 0, won = 0, lost;
                    116:        int r, d = 8;
                    117:        for(r=0; r<16; ++r) {
                    118:            int cr, g, q;
1.1.1.3 ! root      119: 
1.1       root      120:            k  = nb_cols[RED]-1;
                    121:            cr = (r * k) / 15;
                    122:            q  = (r * k) % 15;
                    123:            if(q > d && cr < k) ++cr;
                    124:            diffr = abs(cr*k-r);
                    125:            for(g=0; g<16; ++g) {
                    126:                int cg, b;
1.1.1.3 ! root      127: 
1.1       root      128:                k  = nb_cols[GRN]-1;
                    129:                cg = (g * k) / 15;
                    130:                q  = (g * k) % 15;
                    131:                if(q > d && cg < k) ++cg;
                    132:                diffg = abs(cg*k-g);
                    133:                for(b=0; b<16; ++b) {
                    134:                    int cb, rgb = (r<<8) | (g<<4) | b;
                    135: 
                    136:                    k  = nb_cols[BLU]-1;
                    137:                    cb = (b * k) / 15;
                    138:                    q  = (b * k) % 15;
                    139:                    if(q > d && cb < k) ++cb;
                    140:                    diffb = abs(cb*k-b);
                    141:                    xcolors[rgb] = map[(cr*nb_cols[GRN]+cg)*nb_cols[BLU]+cb];
1.1.1.2   root      142:                    color_diff[rgb] = diffr+diffg+diffb;
                    143:                    if (color_diff[rgb] > maxdiff)
                    144:                        maxdiff = color_diff[rgb];
1.1       root      145:                }
                    146:            }
                    147:        }
                    148:        while (maxdiff > 0 && l < maxcol) {
                    149:            int newmaxdiff = 0;
                    150:            lost = 0; won++;
                    151:            for(r = 15; r >= 0; r--) {
                    152:                int cr, g, q;
1.1.1.3 ! root      153: 
1.1       root      154:                for(g = 15; g >= 0; g--) {
                    155:                    int cg, b;
1.1.1.3 ! root      156: 
1.1       root      157:                    for(b = 15; b >= 0; b--) {
                    158:                        int cb, rgb = (r<<8) | (g<<4) | b;
                    159: 
1.1.1.2   root      160:                        if (color_diff[rgb] == maxdiff) {
1.1       root      161:                            int result;
1.1.1.3 ! root      162: 
1.1       root      163:                            if (l >= maxcol)
                    164:                                lost++;
                    165:                            else {
                    166:                                result = allocfunc(r, g, b, xcolors + rgb);
                    167:                                l++;
                    168:                            }
1.1.1.2   root      169:                            color_diff[rgb] = 0;
                    170:                        } else if (color_diff[rgb] > newmaxdiff)
                    171:                                newmaxdiff = color_diff[rgb];
1.1.1.3 ! root      172: 
1.1       root      173:                    }
                    174:                }
                    175:            }
                    176:            maxdiff = newmaxdiff;
                    177:        }
                    178: /*     printf("%d color(s) lost, %d stages won\n",lost, won);*/
                    179:     }
                    180:     free (map);
                    181: }
                    182: 
                    183: /*
                    184:  * This dithering process works by letting UAE run internaly in 12bit
                    185:  * mode and doing the dithering on the fly when rendering to the display.
                    186:  * The dithering algorithm is quite fast but uses lot of memory (4*8*2^12 =
1.1.1.3 ! root      187:  * 128Kb). I don't think that is a trouble right now, but when UAE will
1.1       root      188:  * emulate AGA and work internaly in 24bit mode, that dithering algorithm
                    189:  * will need 4*8*2^24 = 512Mb. Obviously that fast algorithm will not be
1.1.1.3 ! root      190:  * tractable. However, we could then use an other algorithm, slower, but
1.1       root      191:  * far more reasonable (I am thinking about the one that is used in DJPEG).
                    192:  */
                    193: 
1.1.1.3 ! root      194: uae_u8 cidx[4][8*4096]; /* fast, but memory hungry =:-( */
1.1       root      195: 
                    196: /*
                    197:  * Compute dithering structures
                    198:  */
1.1.1.2   root      199: void setup_greydither_maxcol(int maxcol, allocfunc_type allocfunc)
1.1       root      200: {
                    201:     int i,j,k,l,t;
                    202:     xcolnr *map;
1.1.1.3 ! root      203: 
1.1       root      204:     for (i = 0; i < 4096; i++)
                    205:        xcolors[i] = i;
1.1.1.3 ! root      206: 
1.1       root      207:     map = (xcolnr *)malloc(sizeof(xcolnr) * maxcol);
1.1.1.3 ! root      208:     if(!map) {
        !           209:        write_log("Not enough mem for colormap!\n");
        !           210:        abort();
        !           211:     }
1.1       root      212: 
                    213:     /*
                    214:      * set the colormap
                    215:      */
                    216:     for(i = 0; i < maxcol; ++i) {
                    217:        int c, result;
                    218:        c = (15 * i + (maxcol-1)/2) / (maxcol - 1);
1.1.1.3 ! root      219:        result = allocfunc(c, c, c, map + i);
1.1       root      220:        /* @@@ check for errors */
                    221:     }
                    222: 
                    223:     /*
                    224:      * for each componant compute the mapping
                    225:      */
                    226:     for(i=0;i<4;++i) {
                    227:        for(j=0;j<4;++j) {
                    228:            int r, d = dither[i][j]*17;
                    229:            for(r=0; r<16; ++r) {
                    230:                int g;
                    231:                for(g=0; g<16; ++g) {
                    232:                    int  b;
                    233:                    for(b=0; b<16; ++b) {
                    234:                        int rgb = (r<<8) | (g<<4) | b;
                    235:                        int c,p,q;
1.1.1.3 ! root      236: 
        !           237:                        c = (77  * r +
        !           238:                             151 * g +
1.1       root      239:                             28  * b) / 15; /* c in 0..256 */
1.1.1.3 ! root      240: 
        !           241:                        k = maxcol-1;
1.1       root      242:                        p = (c * k) / 256;
                    243:                        q = (c * k) % 256;
1.1.1.2   root      244:                        if(q /*/ k*/> d /*/ k*/ && p < k) ++p;
                    245: /* sam:                      ^^^^^^^ */
                    246: /*  It seems that produces better output */
1.1.1.3 ! root      247:                        cidx[i][rgb + (j+4)*4096] =
1.1       root      248:                            cidx[i][rgb + j*4096] = map[p];
                    249:                    }
                    250:                }
                    251:            }
                    252:        }
                    253:     }
                    254:     free (map);
                    255: }
                    256: 
1.1.1.2   root      257: void setup_greydither(int bits, allocfunc_type allocfunc)
                    258: {
                    259:     setup_greydither_maxcol(1 << bits, allocfunc);
                    260: }
                    261: 
1.1       root      262: void setup_dither(int bits, allocfunc_type allocfunc)
                    263: {
                    264:     int nb_cols[3]; /* r,g,b */
                    265:     int maxcol = 1 << bits;
                    266:     int i,j,k,l,t;
                    267: 
                    268:     xcolnr *map;
                    269:     int *redvals, *grnvals, *bluvals;
1.1.1.3 ! root      270: 
1.1       root      271:     map = (xcolnr *)malloc(sizeof(xcolnr) * maxcol);
1.1.1.3 ! root      272:     if(!map) {
        !           273:        write_log("Not enough mem for colormap!\n");
        !           274:        abort();
        !           275:     }
1.1       root      276: 
                    277:     for (i = 0; i < 4096; i++)
                    278:        xcolors[i] = i;
1.1.1.3 ! root      279: 
1.1       root      280:     /*
                    281:      * compute #cols per components
                    282:      */
                    283:     for(i = 1; i*i*i <= maxcol; ++i)
                    284:        ;
                    285:     --i;
                    286: 
                    287:     nb_cols[RED] = i;
                    288:     nb_cols[GRN] = i;
                    289:     nb_cols[BLU] = i;
                    290: 
                    291:     if(nb_cols[RED]*(++i)*nb_cols[BLU] <= maxcol) {
                    292:        nb_cols[GRN] = i;
                    293:        if((i)*nb_cols[GRN]*nb_cols[BLU] <= maxcol) nb_cols[RED] = i;
                    294:     }
                    295: 
                    296:     redvals = (int *)malloc(sizeof(int) * maxcol);
                    297:     grnvals = redvals + nb_cols[RED];
1.1.1.3 ! root      298:     bluvals = grnvals + nb_cols[GRN];
1.1       root      299:     /*
                    300:      * set the colormap
                    301:      */
                    302:     l=0;
                    303:     for(i = 0; i < nb_cols[RED]; ++i) {
1.1.1.3 ! root      304:        int r = (i * 15) / (nb_cols[RED] - 1);
1.1       root      305:        redvals[i] = r;
                    306:        for(j = 0; j < nb_cols[GRN]; ++j) {
1.1.1.3 ! root      307:            int g = (j * 15) / (nb_cols[GRN] - 1);
1.1       root      308:            grnvals[j] = g;
1.1.1.3 ! root      309:            for(k = 0; k < nb_cols[BLU]; ++k) {
        !           310:                int b = (k * 15) / (nb_cols[BLU] - 1);
1.1       root      311:                int result;
                    312:                bluvals[k] = b;
                    313:                result = allocfunc(r, g, b, map + l);
                    314:                l++;
                    315:            }
                    316:        }
                    317:     }
1.1.1.2   root      318: /*    fprintf(stderr, "%d color(s) lost\n",maxcol - l);*/
1.1       root      319: 
                    320:     /*
                    321:      * for each component compute the mapping
                    322:      */
                    323:     {
                    324:        int r;
                    325:        for(r=0; r<16; ++r) {
                    326:            int g;
                    327:            for(g=0; g<16; ++g) {
                    328:                int b;
                    329:                for(b=0; b<16; ++b) {
                    330:                    int rederr = 0, grnerr = 0, bluerr = 0;
                    331:                    int rgb = (r<<8) | (g<<4) | b;
                    332: 
                    333:                    for(i=0;i<4;++i) for(j=0;j<4;++j) {
                    334:                        int d = dither[i][j];
                    335:                        int cr, cg, cb, k, q;
                    336: #if 0 /* Slightly different algorithm. Needs some tuning. */
                    337:                        k  = nb_cols[RED]-1;
                    338:                        cr = r * k / 15;
                    339:                        q  = r * k - 15*cr;
                    340:                        if (cr < 0) cr = 0;
                    341:                        else
                    342:                            if(q / k > d / k && rederr <= 0) ++cr;
                    343:                        if (cr > k) cr = k;
                    344:                        rederr += redvals[cr]-r;
1.1.1.3 ! root      345: 
1.1       root      346:                        k  = nb_cols[GRN]-1;
                    347:                        cg = g * k / 15;
                    348:                        q  = g * k - 15*cg;
                    349:                        if (cg < 0) cg = 0;
                    350:                        else
                    351:                            if (q / k > d / k && grnerr <= 0) ++cg;
                    352:                        if (cg > k) cg = k;
                    353:                        grnerr += grnvals[cg]-g;
                    354: 
                    355:                        k  = nb_cols[BLU]-1;
                    356:                        cb = b * k / 15;
                    357:                        q  = b * k - 15*cb;
                    358:                        if (cb < 0) cb = 0;
                    359:                        else
                    360:                            if (q / k > d / k && bluerr <= 0) ++cb;
                    361:                        if (cb > k) cb = k;
                    362:                        bluerr += bluvals[cb]-b;
                    363: #else
                    364:                        k  = nb_cols[RED]-1;
                    365:                        cr = r * k / 15;
                    366:                        q  = r * k - 15*cr;
                    367:                        if (cr < 0) cr = 0;
                    368:                        else
1.1.1.2   root      369:                            if(q /*/ k*/ > d /*/ k*/) ++cr;
1.1       root      370:                        if (cr > k) cr = k;
1.1.1.3 ! root      371: 
1.1       root      372:                        k  = nb_cols[GRN]-1;
                    373:                        cg = g * k / 15;
                    374:                        q  = g * k - 15*cg;
                    375:                        if (cg < 0) cg = 0;
                    376:                        else
1.1.1.2   root      377:                            if (q /*/ k*/ > d /*/ k*/) ++cg;
1.1       root      378:                        if (cg > k) cg = k;
                    379: 
                    380:                        k  = nb_cols[BLU]-1;
                    381:                        cb = b * k / 15;
                    382:                        q  = b * k - 15*cb;
                    383:                        if (cb < 0) cb = 0;
                    384:                        else
1.1.1.2   root      385:                            if (q /*/ k*/ > d /*/ k*/) ++cb;
1.1       root      386:                        if (cb > k) cb = k;
                    387: #endif
                    388:                        cidx[i][rgb + (j+4)*4096] = cidx[i][rgb + j*4096] = map[(cr*nb_cols[GRN]+cg)*nb_cols[BLU]+cb];
                    389:                    }
                    390:                }
                    391:            }
                    392:        }
                    393:     }
                    394:     free (map);
                    395: }
                    396: 
1.1.1.3 ! root      397: #if !defined X86_ASSEMBLY
1.1       root      398: /*
                    399:  * Dither the line.
                    400:  * Make sure you call this only with (len & 3) == 0, or you'll just make
                    401:  * yourself unhappy.
                    402:  */
                    403: 
1.1.1.3 ! root      404: void DitherLine(uae_u8 *l, uae_u16 *r4g4b4, int x, int y, uae_s16 len, int bits)
1.1       root      405: {
1.1.1.3 ! root      406:     uae_u8 *dith = cidx[y&3]+(x&3)*4096;
        !           407:     uae_u8 d = 0;
1.1       root      408:     int bitsleft = 8;
1.1.1.3 ! root      409: 
        !           410:     if(bits == 8) {
1.1.1.2   root      411:        while(len>0) {
                    412:            *l++ = dith[0*4096 + *r4g4b4++];
                    413:            *l++ = dith[1*4096 + *r4g4b4++];
                    414:            *l++ = dith[2*4096 + *r4g4b4++];
                    415:            *l++ = dith[3*4096 + *r4g4b4++];
                    416:            len -= 4;
                    417:        }
                    418:        return;
                    419:     }
                    420: 
1.1       root      421:     while(len) {
                    422:        int v;
                    423:        v = dith[0*4096 + *r4g4b4++];
                    424:        bitsleft -= bits;
                    425:        d |= (v << bitsleft);
                    426:        if (!bitsleft)
                    427:            *l++ = d, bitsleft = 8, d = 0;
1.1.1.3 ! root      428: 
1.1       root      429:        v = dith[1*4096 + *r4g4b4++];
                    430:        bitsleft -= bits;
                    431:        d |= (v << bitsleft);
                    432:        if (!bitsleft)
                    433:            *l++ = d, bitsleft = 8, d = 0;
1.1.1.3 ! root      434: 
1.1       root      435:        v = dith[2*4096 + *r4g4b4++];
                    436:        bitsleft -= bits;
                    437:        d |= (v << bitsleft);
                    438:        if (!bitsleft)
                    439:            *l++ = d, bitsleft = 8, d = 0;
1.1.1.3 ! root      440: 
1.1       root      441:        v = dith[3*4096 + *r4g4b4++];
                    442:        bitsleft -= bits;
                    443:        d |= (v << bitsleft);
                    444:        if (!bitsleft)
                    445:            *l++ = d, bitsleft = 8, d = 0;
                    446:        len -= 4;
                    447:     }
                    448: }
                    449: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.