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

1.1       root        1:  /* 
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   * 
                      4:   * Common code needed by all the various graphics systems.
                      5:   * 
                      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"
                     14: #include "memory.h"
                     15: #include "custom.h"
                     16: #include "newcpu.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:  */
                     28: static UBYTE dither[4][4] =
                     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];
                     60: 
                     61: void alloc_colors256(allocfunc_type allocfunc)
                     62: {
                     63:     int nb_cols[3]; /* r,g,b */
                     64:     int maxcol = 256;
                     65:     int i,j,k,l,t;
                     66:     int diff[4096];
                     67: 
                     68:     xcolnr *map;
                     69:     
                     70:     map = (xcolnr *)malloc(sizeof(xcolnr) * maxcol);
                     71:     
                     72:     /*
                     73:      * compute #cols per components
                     74:      */
                     75:     for(i = 1; i*i*i <= maxcol; ++i)
                     76:        ;
                     77:     --i;
                     78: 
                     79:     nb_cols[RED] = i;
                     80:     nb_cols[GRN] = i;
                     81:     nb_cols[BLU] = i;
                     82: 
                     83:     /*
                     84:      * set the colormap
                     85:      */
                     86:     l=0;
                     87:     for(i = 0; i < nb_cols[RED]; ++i) {
                     88:        int r = (i * 15 + (nb_cols[RED] - 1)/2) / (nb_cols[RED] - 1);
                     89:        for(j = 0; j < nb_cols[GRN]; ++j) {
                     90:            int g = (j * 15 + (nb_cols[GRN] - 1)/2) / (nb_cols[GRN] - 1);
                     91:            for(k = 0; k < nb_cols[BLU]; ++k) { 
                     92:                int b = (k * 15 + (nb_cols[BLU] - 1)/2) / (nb_cols[BLU] - 1);
                     93:                int result;
                     94:                result = allocfunc(r, g, b, map + l);
                     95:                l++;
                     96:            }
                     97:        }
                     98:     }
                     99: /*    printf("%d color(s) lost\n",maxcol - l);*/
                    100: 
                    101:     /*
                    102:      * for each component compute the mapping
                    103:      */
                    104:     {
                    105:        int diffr, diffg, diffb, maxdiff = 0, won = 0, lost;
                    106:        int r, d = 8;
                    107:        for(r=0; r<16; ++r) {
                    108:            int cr, g, q;
                    109:          
                    110:            k  = nb_cols[RED]-1;
                    111:            cr = (r * k) / 15;
                    112:            q  = (r * k) % 15;
                    113:            if(q > d && cr < k) ++cr;
                    114:            diffr = abs(cr*k-r);
                    115:            for(g=0; g<16; ++g) {
                    116:                int cg, b;
                    117:              
                    118:                k  = nb_cols[GRN]-1;
                    119:                cg = (g * k) / 15;
                    120:                q  = (g * k) % 15;
                    121:                if(q > d && cg < k) ++cg;
                    122:                diffg = abs(cg*k-g);
                    123:                for(b=0; b<16; ++b) {
                    124:                    int cb, rgb = (r<<8) | (g<<4) | b;
                    125: 
                    126:                    k  = nb_cols[BLU]-1;
                    127:                    cb = (b * k) / 15;
                    128:                    q  = (b * k) % 15;
                    129:                    if(q > d && cb < k) ++cb;
                    130:                    diffb = abs(cb*k-b);
                    131:                    xcolors[rgb] = map[(cr*nb_cols[GRN]+cg)*nb_cols[BLU]+cb];
                    132:                    diff[rgb] = diffr+diffg+diffb;
                    133:                    if (diff[rgb] > maxdiff)
                    134:                        maxdiff = diff[rgb];
                    135:                }
                    136:            }
                    137:        }
                    138:        while (maxdiff > 0 && l < maxcol) {
                    139:            int newmaxdiff = 0;
                    140:            lost = 0; won++;
                    141:            for(r = 15; r >= 0; r--) {
                    142:                int cr, g, q;
                    143:          
                    144:                for(g = 15; g >= 0; g--) {
                    145:                    int cg, b;
                    146:              
                    147:                    for(b = 15; b >= 0; b--) {
                    148:                        int cb, rgb = (r<<8) | (g<<4) | b;
                    149: 
                    150:                        if (diff[rgb] == maxdiff) {
                    151:                            int result;
                    152:                        
                    153:                            if (l >= maxcol)
                    154:                                lost++;
                    155:                            else {
                    156:                                result = allocfunc(r, g, b, xcolors + rgb);
                    157:                                l++;
                    158:                            }
                    159:                            diff[rgb] = 0;
                    160:                        } else if (diff[rgb] > newmaxdiff)
                    161:                                newmaxdiff = diff[rgb];
                    162:                        
                    163:                    }
                    164:                }
                    165:            }
                    166:            maxdiff = newmaxdiff;
                    167:        }
                    168: /*     printf("%d color(s) lost, %d stages won\n",lost, won);*/
                    169:     }
                    170:     free (map);
                    171: }
                    172: 
                    173: /*
                    174:  * This dithering process works by letting UAE run internaly in 12bit
                    175:  * mode and doing the dithering on the fly when rendering to the display.
                    176:  * The dithering algorithm is quite fast but uses lot of memory (4*8*2^12 =
                    177:  * 128Kb). I don't think that is a trouble right now, but when UAE will 
                    178:  * emulate AGA and work internaly in 24bit mode, that dithering algorithm
                    179:  * will need 4*8*2^24 = 512Mb. Obviously that fast algorithm will not be
                    180:  * tractable. However, we could then use an other algorithm, slower, but 
                    181:  * far more reasonable (I am thinking about the one that is used in DJPEG).
                    182:  */
                    183: 
                    184: UBYTE cidx[4][8*4096]; /* fast, but memory hungry =:-( */
                    185: 
                    186: /*
                    187:  * Compute dithering structures
                    188:  */
                    189: void setup_greydither(int bits, allocfunc_type allocfunc)
                    190: {
                    191:     int i,j,k,l,t;
                    192:     int maxcol = 1 << bits;
                    193:     xcolnr *map;
                    194:     
                    195:     for (i = 0; i < 4096; i++)
                    196:        xcolors[i] = i;
                    197:     
                    198:     map = (xcolnr *)malloc(sizeof(xcolnr) * maxcol);
                    199: 
                    200:     /*
                    201:      * set the colormap
                    202:      */
                    203:     for(i = 0; i < maxcol; ++i) {
                    204:        int c, result;
                    205:        c = (15 * i + (maxcol-1)/2) / (maxcol - 1);
                    206:         result = allocfunc(c, c, c, map + i);
                    207:        /* @@@ check for errors */
                    208:     }
                    209: 
                    210:     /*
                    211:      * for each componant compute the mapping
                    212:      */
                    213:     for(i=0;i<4;++i) {
                    214:        for(j=0;j<4;++j) {
                    215:            int r, d = dither[i][j]*17;
                    216:            for(r=0; r<16; ++r) {
                    217:                int g;
                    218:                for(g=0; g<16; ++g) {
                    219:                    int  b;
                    220:                    for(b=0; b<16; ++b) {
                    221:                        int rgb = (r<<8) | (g<<4) | b;
                    222:                        int c,p,q;
                    223:                        
                    224:                        c = (77  * r + 
                    225:                             151 * g + 
                    226:                             28  * b) / 15; /* c in 0..256 */
                    227:                        
                    228:                        k = maxcol-1;  
                    229:                        p = (c * k) / 256;
                    230:                        q = (c * k) % 256;
                    231:                        if(q / k > d / k && p < k) ++p;
                    232:                        cidx[i][rgb + (j+4)*4096] = 
                    233:                            cidx[i][rgb + j*4096] = map[p];
                    234:                    }
                    235:                }
                    236:            }
                    237:        }
                    238:     }
                    239:     free (map);
                    240: }
                    241: 
                    242: void setup_dither(int bits, allocfunc_type allocfunc)
                    243: {
                    244:     int nb_cols[3]; /* r,g,b */
                    245:     int maxcol = 1 << bits;
                    246:     int i,j,k,l,t;
                    247: 
                    248:     xcolnr *map;
                    249:     int *redvals, *grnvals, *bluvals;
                    250:     
                    251:     map = (xcolnr *)malloc(sizeof(xcolnr) * maxcol);
                    252: 
                    253:     for (i = 0; i < 4096; i++)
                    254:        xcolors[i] = i;
                    255:     
                    256:     /*
                    257:      * compute #cols per components
                    258:      */
                    259:     for(i = 1; i*i*i <= maxcol; ++i)
                    260:        ;
                    261:     --i;
                    262: 
                    263:     nb_cols[RED] = i;
                    264:     nb_cols[GRN] = i;
                    265:     nb_cols[BLU] = i;
                    266: 
                    267:     if(nb_cols[RED]*(++i)*nb_cols[BLU] <= maxcol) {
                    268:        nb_cols[GRN] = i;
                    269:        if((i)*nb_cols[GRN]*nb_cols[BLU] <= maxcol) nb_cols[RED] = i;
                    270:     }
                    271: 
                    272:     redvals = (int *)malloc(sizeof(int) * maxcol);
                    273:     grnvals = redvals + nb_cols[RED];
                    274:     bluvals = grnvals + nb_cols[BLU];
                    275:     /*
                    276:      * set the colormap
                    277:      */
                    278:     l=0;
                    279:     for(i = 0; i < nb_cols[RED]; ++i) {
                    280:        int r = (i * 15 + (nb_cols[RED] - 1)/2) / (nb_cols[RED] - 1);
                    281:        redvals[i] = r;
                    282:        for(j = 0; j < nb_cols[GRN]; ++j) {
                    283:            int g = (j * 15 + (nb_cols[GRN] - 1)/2) / (nb_cols[GRN] - 1);
                    284:            grnvals[j] = g;
                    285:            for(k = 0; k < nb_cols[BLU]; ++k) { 
                    286:                int b = (k * 15 + (nb_cols[BLU] - 1)/2) / (nb_cols[BLU] - 1);
                    287:                int result;
                    288:                bluvals[k] = b;
                    289:                result = allocfunc(r, g, b, map + l);
                    290:                l++;
                    291:            }
                    292:        }
                    293:     }
                    294:     fprintf(stderr, "%d color(s) lost\n",maxcol - l);
                    295: 
                    296:     /*
                    297:      * for each component compute the mapping
                    298:      */
                    299:     {
                    300:        int r;
                    301:        for(r=0; r<16; ++r) {
                    302:            int g;
                    303:            for(g=0; g<16; ++g) {
                    304:                int b;
                    305:                for(b=0; b<16; ++b) {
                    306:                    int rederr = 0, grnerr = 0, bluerr = 0;
                    307:                    int rgb = (r<<8) | (g<<4) | b;
                    308: 
                    309:                    for(i=0;i<4;++i) for(j=0;j<4;++j) {
                    310:                        int d = dither[i][j];
                    311:                        int cr, cg, cb, k, q;
                    312: #if 0 /* Slightly different algorithm. Needs some tuning. */
                    313:                        k  = nb_cols[RED]-1;
                    314:                        cr = r * k / 15;
                    315:                        q  = r * k - 15*cr;
                    316:                        if (cr < 0) cr = 0;
                    317:                        else
                    318:                            if(q / k > d / k && rederr <= 0) ++cr;
                    319:                        if (cr > k) cr = k;
                    320:                        rederr += redvals[cr]-r;
                    321:              
                    322:                        k  = nb_cols[GRN]-1;
                    323:                        cg = g * k / 15;
                    324:                        q  = g * k - 15*cg;
                    325:                        if (cg < 0) cg = 0;
                    326:                        else
                    327:                            if (q / k > d / k && grnerr <= 0) ++cg;
                    328:                        if (cg > k) cg = k;
                    329:                        grnerr += grnvals[cg]-g;
                    330: 
                    331:                        k  = nb_cols[BLU]-1;
                    332:                        cb = b * k / 15;
                    333:                        q  = b * k - 15*cb;
                    334:                        if (cb < 0) cb = 0;
                    335:                        else
                    336:                            if (q / k > d / k && bluerr <= 0) ++cb;
                    337:                        if (cb > k) cb = k;
                    338:                        bluerr += bluvals[cb]-b;
                    339: #else
                    340:                        k  = nb_cols[RED]-1;
                    341:                        cr = r * k / 15;
                    342:                        q  = r * k - 15*cr;
                    343:                        if (cr < 0) cr = 0;
                    344:                        else
                    345:                            if(q / k > d / k) ++cr;
                    346:                        if (cr > k) cr = k;
                    347:              
                    348:                        k  = nb_cols[GRN]-1;
                    349:                        cg = g * k / 15;
                    350:                        q  = g * k - 15*cg;
                    351:                        if (cg < 0) cg = 0;
                    352:                        else
                    353:                            if (q / k > d / k) ++cg;
                    354:                        if (cg > k) cg = k;
                    355: 
                    356:                        k  = nb_cols[BLU]-1;
                    357:                        cb = b * k / 15;
                    358:                        q  = b * k - 15*cb;
                    359:                        if (cb < 0) cb = 0;
                    360:                        else
                    361:                            if (q / k > d / k) ++cb;
                    362:                        if (cb > k) cb = k;
                    363: #endif
                    364:                        cidx[i][rgb + (j+4)*4096] = cidx[i][rgb + j*4096] = map[(cr*nb_cols[GRN]+cg)*nb_cols[BLU]+cb];
                    365:                    }
                    366:                }
                    367:            }
                    368:        }
                    369:     }
                    370:     free (map);
                    371: }
                    372: 
                    373: #ifndef X86_ASSEMBLY
                    374: /*
                    375:  * Dither the line.
                    376:  * Make sure you call this only with (len & 3) == 0, or you'll just make
                    377:  * yourself unhappy.
                    378:  */
                    379: 
                    380: void DitherLine(UBYTE *l, UWORD *r4g4b4, int x, int y, UWORD len, int bits)
                    381: {
                    382:     UBYTE *dith = cidx[y&3]+(x&3)*4096;
                    383:     UBYTE d = 0;
                    384:     int bitsleft = 8;
                    385:     
                    386:     while(len) {
                    387:        int v;
                    388:        v = dith[0*4096 + *r4g4b4++];
                    389:        bitsleft -= bits;
                    390:        d |= (v << bitsleft);
                    391:        if (!bitsleft)
                    392:            *l++ = d, bitsleft = 8, d = 0;
                    393:        
                    394:        v = dith[1*4096 + *r4g4b4++];
                    395:        bitsleft -= bits;
                    396:        d |= (v << bitsleft);
                    397:        if (!bitsleft)
                    398:            *l++ = d, bitsleft = 8, d = 0;
                    399:        
                    400:        v = dith[2*4096 + *r4g4b4++];
                    401:        bitsleft -= bits;
                    402:        d |= (v << bitsleft);
                    403:        if (!bitsleft)
                    404:            *l++ = d, bitsleft = 8, d = 0;
                    405:        
                    406:        v = dith[3*4096 + *r4g4b4++];
                    407:        bitsleft -= bits;
                    408:        d |= (v << bitsleft);
                    409:        if (!bitsleft)
                    410:            *l++ = d, bitsleft = 8, d = 0;
                    411:        len -= 4;
                    412:     }
                    413: }
                    414: #endif

unix.superglobalmegacorp.com

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