File:  [UNIX Amiga Emulator] / uae / gfxutil.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:37:58 2018 UTC (8 years, 2 months ago) by root
Branches: MAIN, BSchmidt
CVS tags: uae060, HEAD
uae-0.6.0

 /* 
  * UAE - The Un*x Amiga Emulator
  * 
  * Common code needed by all the various graphics systems.
  * 
  * (c) 1996 Bernd Schmidt, Ed Hanway
  */

#include "sysconfig.h"
#include "sysdeps.h"

#include "config.h"
#include "options.h"
#include "memory.h"
#include "custom.h"
#include "newcpu.h"
#include "keyboard.h"
#include "xwin.h"
#include "keybuf.h"

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 */

    unsigned long val = p * 0x11111111UL;
    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++) {
	int r = i >> 8;
	int g = (i >> 4) & 0xF;
	int b = i & 0xF;
	xcolors[i] = doMask(r, rw, rs) | doMask(g, gw, gs) | doMask(b, bw, bs);
    }
}

static int allocated[4096];

void alloc_colors256(int (* allocfunc)(int, int, int, xcolnr *))
{
    /* This is kind of kludgy...
     * Try to allocate as many different colors as possible. */
    int step = 5, mode = 0, count = 0, col;
    int no_allocated = 0;

    memset(allocated, 0, sizeof allocated);
    fprintf(stderr, "Allocating lots of colors...\n");
    
    do {
	int r, g, b, rs, bs, gs;
	bs = step;
	rs = step;
	gs = step;
	for(b = 0; b < 16; b += bs) {
	    for(r = 0; r < 16; r += rs) {
		for(g = 0; g < 16; g += gs) {
		    int cnr = (r << 8) + (g << 4) + b;
		    if (!allocated[cnr]) {
			int result = allocfunc(r, g, b, xcolors + cnr);
			if (result < 0 || no_allocated == 256)
			    goto finished;
			if (result > 0) {
			    allocated[cnr] = 1;
			    no_allocated++;
			}
		    }
		}
	    }
	}
	if (step > 1)
	    step++;
	step /= 2;
    } while (step);
    
    finished:
#if 0
    for(col = 0; col < 4096; col++) {
	int cnr = col;
	if (!allocated[cnr]) {
	    int r = cnr >> 8;
	    int g = (cnr >> 4) & 0xF;
	    int b = cnr & 0xF;
	    int maxd = 4096,best = 0;
	    int c2;
	    for(c2 = 0; c2 < 4096; c2++)
	    	if (allocated[c2]) {
		    int r2 = c2 >> 8;
		    int g2 = (c2 >> 4) & 0xF;
		    int b2 = c2 & 0xF;
		    int rd = (r2-r)*r*2;
		    int bd = (b2-b)*b*2;
		    int gd = (g2-g)*g*2;
		    int dist = abs(rd) + abs(gd) + abs(bd) + abs(rd-gd)/3 + abs(rd-bd)/3 + abs(gd-bd)/3;
		    if (dist < maxd) {
			maxd = dist;
			best = c2;
		    }
		}
	    cnr = best;
	}
	xcolors[col] = xcolors[cnr];
    }
#else
    for(col = 0; col < 4096; col++) {
	int cnr;
	int dist;
	int r = col >> 8;
	int g = (col >> 4) & 0xF;
	int b = col & 0xF;
	
	if (allocated[col])
	    continue;
	
	for (dist = 2;; dist++) {
	    int r2, g2, b2;
	    int rd, gd, bd;
	    int best = 0, maxd = 32767;
	    for (gd = 0; gd < dist; gd = gd < 0 ? -gd : -gd-1) {
		g2 = g + gd;
		if (g2 < 0 || g2 > 15)
		    continue;
		for (rd = 0; rd < dist; rd = rd < 0 ? -rd : -rd-1) {
		    r2 = r + rd;
		    if (r2 < 0 || r2 > 15)
			continue;
		    for (bd = 0; bd < dist; bd = bd < 0 ? -bd : -bd-1) {
			b2 = b + bd;
			if (b2 < 0 || b2 > 15)
			    continue;
			cnr = (r2 << 8) + (g2 << 4) + b2;
			if (allocated[cnr]) {
			    int rd2 = rd == 0 ? 0 : rd*32/r;
			    int gd2 = gd == 0 ? 0 : gd*32/g;
			    int bd2 = bd == 0 ? 0 : bd*32/b;
			    int dist = abs(rd) + abs(gd) + abs(bd) + abs(rd2-gd2) + abs(rd2-bd2) + abs(gd2-bd2);
			    if (dist < maxd) {
				maxd = dist;
				xcolors[col] = xcolors[cnr];
			    }
			}
		    }
		}
	    }
	    if (maxd != 32767)
		break;
	}
    }
#endif
}


unix.superglobalmegacorp.com

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