Annotation of uae/src/gfxutil.c, revision 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.