/* hamstuff.c - routines to be given a set of colors. These will be plotted in ham mode. This is based on hamrtn.c */ #include #include #include #include "globals.h" extern UWORD colortable[]; extern UBYTE near[]; extern UWORD nearmc[]; /* near is 4096 long and is configured as a 16*16*16 array */ /* each byte gives the distance to the nearest colortable entry */ /* the high order nible is the index into the color table and the */ /* low order nible is the distance. */ /* color[16] - colormap containing rgb values fairly evenly */ /* spread throughout 16x16x16 space. */ /* near[4096] - table of distance. For each r,g,b */ /* address = (r<<8 | g<<4 | b) & 0xfff */ /* near>>4 gives the nearest color (index) and */ /* near & 0x0f gives the distance. */ /* nearmc[4096] - table of distance minus color */ /* This contains the nearest color ignoring a color */ /* (nearmc >> 8) & 0xf is for red, */ /* (nearmc >> 4) & 0xf is for green, */ /* and nearmc & 0xf is for blue */ #define INDEXNEAR(r,g,b) near[(((r)<<8) | ((g)<<4) | (b))&0xfff] #define PLOTABS(x,y,color) {mywritepixel(&ibitmap,x,y,color); \ i = colortable[color]; \ pr = i >> 8; \ pg = (i >> 4) & 0x0f; \ pb = i & 0x0f; \ if (!exact) \ mywritepixel(&ibitmap,ox,oy,near[oc]>>4);} #define RED 0x20 #define GREEN 0x30 #define BLUE 0x10 extern struct RastPort *rp; static short pr, pg, pb; static int ox, oy, oc; void setcolor(xpos,ypos,yepos,r,b,g,exact) int xpos,ypos,yepos,r,b,g,exact; { short d1, dr, dg, db; int i; r &= 0x0f; b &= 0x0f; g &= 0x0f; if (bw) mywritepixel(&ibitmap,xpos,ypos,(r+b+g)/3); else { d1 = INDEXNEAR(r,g,b); if (((d1 & 0x0f) == 0) || (exact)) { /* equals existing color */ PLOTABS(xpos,ypos,(d1>>4)); if (exact) mywritepixel(&ibitmap,xpos,yepos,d1>>4); } else { /* calculate nearest dist from prev */ dr = r - pr; if (dr < 0) dr = -dr; dg = g - pg; if (dg < 0) dg = -dg; db = b - pb; if (db < 0) db = -db; if (dr > dg) { if (dr > db) { /* dr is max */ if ((d1 & 0x0f) < (dg+db)) { PLOTABS(xpos,ypos,(d1>>4)); } else { mywritepixel(&ibitmap,xpos,ypos,RED | r); pr = r; mywritepixel(&ibitmap,ox,oy,(nearmc[oc]>>8)); } } else { /* if (dr > db) . . . */ /* db is max */ if ((d1 & 0x0f) < (dg+dr)) { PLOTABS(xpos,ypos,(d1>>4)); } else { mywritepixel(&ibitmap,xpos,ypos, BLUE | b); pb = b; mywritepixel(&ibitmap,ox,oy,(nearmc[oc] & 0xf)); } } } else { /* if (dr > dg) . . . */ if (dg > db) { /* dg is max */ if ((d1 & 0x0f) < (dr+db)) { PLOTABS(xpos,ypos,(d1>>4)); } else { mywritepixel(&ibitmap,xpos,ypos,GREEN | g); pg = g; mywritepixel(&ibitmap,ox,oy, (nearmc[oc]>>4)& 0xf); } } else { /* if (dg > db) . . . */ /* db is max */ if ((d1 & 0x0f) < (dg+dr)) { PLOTABS(xpos,ypos,(d1>>4)); } else { mywritepixel(&ibitmap,xpos,ypos,BLUE | b); pb = b; mywritepixel(&ibitmap,ox,oy,(nearmc[oc] & 0xf)); } } } /* end if (dr > dg) */ } /* end else for if ((d1 & 0x0f) == 0) */ oc = r<<8 | g<<4 | b; ox = xpos; oy = yepos; } } /* end setcolor */ void dolast() { if (!bw) mywritepixel(&ibitmap,ox,oy,near[oc]>>4); } int match(r,g,b) int r,g,b; { if (bw) return(0.5 + ((float)(r + g + b)) / 3.0); else return(INDEXNEAR(r,g,b) >> 4); }