home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
science
/
chemesthetics
/
source
/
palettereq.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-13
|
17KB
|
558 lines
/****************************************************************************
* *
* Palette Requester *
* *
* (c) Copyright 1989 Jonathan Potter *
* *
* This program is freely redistributable, although all rights to it remain *
* with the author. It may be used freely in any program as long as this *
* notice remains intact, however, if you do this, please mention the *
* author in the program. If you wish to use this in a commercial program *
* of any kind, you must register with a $15 donation. *
* Please send donations, bug reports, comments and suggestions to : *
* *
* Jonathan Potter *
* 3 William Street *
* Clarence Park 5034 *
* South Australia *
* Australia *
* *
* Ph : (08) 2932788 home *
* *
****************************************************************************/
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <libraries/dosextens.h>
#include <graphics/gfxbase.h>
#include "PaletteReq.h"
#define RED 32
#define BLUE 33
#define GREEN 34
#define CRESET 35
#define CCANCEL 36
#define COK 37
#define USER 38
#define SPREAD 39
#define COPY 40
#define HUE 41
#define SAT 42
#define LUM 43
#define INITREG(n) (GetRGB4(cvp->ColorMap,n))
#define REDREG(n) ((n>>8)&0xf)
#define GREENREG(n) ((n>>4)&0xf)
#define BLUEREG(n) (n&0xf)
static int redtable[32], greentable[32], bluetable[32];
static char values[4];
static struct IntuiText
coktext={1,0,JAM1,41,1,NULL,(UBYTE *)"OKAY",NULL},
canceltext={1,0,JAM1,33,1,NULL,(UBYTE *)"CANCEL",NULL},
usertext={1,0,JAM1,0,1,NULL,(UBYTE *)"",NULL},
resettext={1,0,JAM1,37,1,NULL,(UBYTE *)"RESET",NULL},
spreadtext={1,0,JAM1,33,1,NULL,(UBYTE *)"SPREAD",NULL},
copytext={1,0,JAM1,41,1,NULL,(UBYTE *)"COPY",NULL},
RText={1,0,JAM1,-15,1,NULL,"R",NULL},
GText={1,0,JAM1,-15,1,NULL,"G",NULL},
BText={1,0,JAM1,-15,1,NULL,"B",NULL},
HText={1,0,JAM1,106,1,NULL,"H",NULL},
SText={1,0,JAM1,106,1,NULL,"S",NULL},
LText={1,0,JAM1,106,1,NULL,"L",NULL},
valstext={0,1,JAM2,0,0,NULL,values,NULL};
static short border1_xy[]={
0,0,115,0,115,10,0,10,0,0};
static struct Border border1={
-1,-1,1,0,JAM1,5,border1_xy,NULL};
static short border2_xy[]={
0,0,239,0,239,10,0,10,0,0};
static struct Border border2={
-1,-1,1,0,JAM1,5,border2_xy,NULL};
static struct PropInfo
RProp={AUTOKNOB|FREEHORIZ,0,0,1<<12},
GProp={AUTOKNOB|FREEHORIZ,0,0,1<<12},
BProp={AUTOKNOB|FREEHORIZ,0,0,1<<12},
HProp={AUTOKNOB|FREEHORIZ,0,0,1<<12},
SProp={AUTOKNOB|FREEHORIZ,0,0,1<<12},
LProp={AUTOKNOB|FREEHORIZ,0,0,1<<12};
static struct Image RImage, GImage, BImage, HImage, SImage, LImage,
WCol={0,0,235,8,1,NULL,0,1,NULL};
static struct Gadget
cokgadget={
NULL,9,118,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
(APTR)&border1,NULL,&coktext,NULL,NULL,COK,NULL},
cancelgadget={
&cokgadget,133,118,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
(APTR)&border1,NULL,&canceltext,NULL,NULL,CCANCEL,NULL},
usergadget={
&cancelgadget,133,105,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
(APTR)&border1,NULL,&usertext,NULL,NULL,USER,NULL},
resetgadget={
&usergadget,9,105,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
(APTR)&border1,NULL,&resettext,NULL,NULL,CRESET,NULL},
spreadgadget={
&resetgadget,133,92,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
(APTR)&border1,NULL,&spreadtext,NULL,NULL,SPREAD,NULL},
copygadget={
&spreadgadget,9,92,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
(APTR)&border1,NULL,©text,NULL,NULL,COPY,NULL},
Lum={
©gadget,132,79,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
(APTR)&LImage,NULL,<ext,NULL,(APTR)&LProp,LUM,NULL},
Sat={
&Lum,132,67,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
(APTR)&SImage,NULL,&SText,NULL,(APTR)&SProp,SAT,NULL},
Hue={
&Sat,132,55,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
(APTR)&HImage,NULL,&HText,NULL,(APTR)&HProp,HUE,NULL},
Red={
&Hue,24,55,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
(APTR)&RImage,NULL,&RText,NULL,(APTR)&RProp,RED,NULL},
Green={
&Red,24,67,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
(APTR)&GImage,NULL,>ext,NULL,(APTR)&GProp,GREEN,NULL},
Blue={
&Green,24,79,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
(APTR)&BImage,NULL,&BText,NULL,(APTR)&BProp,BLUE,NULL};
static struct NewWindow colwin={
40,23,255,131,0,1,CLOSEWINDOW|GADGETUP|GADGETDOWN|MOUSEBUTTONS|RAWKEY,
WINDOWDRAG|WINDOWCLOSE|ACTIVATE|SMART_REFRESH|RMBTRAP,
&Blue,NULL,"Palette",NULL,NULL,0,0,0,0,CUSTOMSCREEN};
static struct Window *PWindow;
static struct IntuiMessage *PMsg;
static struct ViewPort *cvp;
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
static ULONG colb;
palette_request(win,winx,winy,hail,user,depth)
struct Window *win;
int winx, winy;
char *hail;
char *user;
int depth;
{
int col,reg,i,Class,Code,GadgetID,x,y,last,first,sw,sh;
if (!IntuitionBase) return(NO_INTUITION);
if (!GfxBase) return(NO_GRAPHICS);
if (!win) { colwin.Type=WBENCHSCREEN; sw=640; sh=200; }
else {
colwin.Screen=win->WScreen;
sw=win->WScreen->Width; sh=win->WScreen->Height;
}
if (hail) colwin.Title=hail;
if (user) {
if (strlen(user)>14) user[14]='\0';
usertext.IText=user;
usertext.LeftEdge=(115-(strlen(user)*8))/2;
}
else {
resetgadget.NextGadget=&cancelgadget;
resetgadget.Width=238;
resetgadget.GadgetRender=(APTR)&border2;
resettext.LeftEdge=99;
}
if (winx>-1) {
colwin.LeftEdge=winx;
if (winx+255>sw)
colwin.LeftEdge=sw-255;
}
if (winy>-1) {
colwin.TopEdge=winy;
if (winy+131>sh)
colwin.TopEdge=sh-131;
}
PWindow=(struct Window *) OpenWindow(&colwin);
if (!PWindow) return(OPENWINDOW_FAILED);
cvp=&(PWindow->WScreen->ViewPort);
if (!depth) depth=2;
if (depth<1) depth=1; if (depth>5) depth=5;
drawersquares(depth);
InitTable(depth);
col=1; WCol.PlaneOnOff=col;
valstext.FrontPen=col^(power(2,depth)-1); valstext.BackPen=1;
DrawImage(PWindow->RPort,&WCol,10,45);
PosPots(depth,col);
PosHSLPots(depth,col);
FOREVER {
Wait(1<<PWindow->UserPort->mp_SigBit);
while (PMsg=(struct IntuiMessage *) GetMsg(PWindow->UserPort)) {
Class=PMsg->Class; Code=PMsg->Code;
if (Class==GADGETUP || Class==GADGETDOWN)
GadgetID=((struct Gadget *) PMsg->IAddress)->GadgetID;
ReplyMsg((struct Message *) PMsg);
switch (Class) {
case CLOSEWINDOW:
for (reg=0;reg<(power(2,depth));reg++)
SetRGB4(cvp,reg,redtable[reg],greentable[reg],bluetable[reg]);
CloseWindow(PWindow);
return(FALSE);
break;
case MOUSEBUTTONS:
if (Code!=SELECTDOWN) break;
x=PWindow->MouseX; y=PWindow->MouseY;
if (x<12 || x>243 || y<15 || y>40) break;
if (col==ReadPixel(PWindow->RPort,x,y)) break;
col=ReadPixel(PWindow->RPort,x,y);
WCol.PlaneOnOff=col;
DrawImage(PWindow->RPort,&WCol,10,45);
PosPots(depth,col);
PosHSLPots(depth,col);
break;
case GADGETDOWN:
switch (GadgetID) {
case RED:
case GREEN:
case BLUE:
SetCols(depth,col);
while (!(PMsg=(struct IntuiMessage *) GetMsg(PWindow->UserPort)))
SetCols(depth,col);
ReplyMsg((struct Message *) PMsg);
SetCols(depth,col);
break;
case HUE:
case SAT:
case LUM:
SetHSLCols(depth,col);
while (!(PMsg=(struct IntuiMessage *) GetMsg(PWindow->UserPort)))
SetHSLCols(depth,col);
ReplyMsg((struct Message *) PMsg);
SetHSLCols(depth,col);
break;
}
break;
case RAWKEY:
if (Code!=0x45) break;
GadgetID=CRESET; Class=GADGETUP;
case GADGETUP:
switch (GadgetID) {
case CRESET:
for (reg=0;reg<(power(2,depth));reg++) {
SetRGB4(cvp,reg,redtable[reg],greentable[reg],bluetable[reg]);
if (reg==col) {
PosPots(depth,col);
PosHSLPots(depth,col);
}
}
break;
case USER:
if (!user) break;
CloseWindow(PWindow);
return(5);
case COK:
CloseWindow(PWindow);
return(TRUE);
case CCANCEL:
for (reg=0;reg<(power(2,depth));reg++)
SetRGB4(cvp,reg,redtable[reg],greentable[reg],bluetable[reg]);
CloseWindow(PWindow);
return(FALSE);
case COPY:
FOREVER {
Wait(1<<PWindow->UserPort->mp_SigBit);
if (PMsg=(struct IntuiMessage *) GetMsg(PWindow->UserPort)) {
Class=PMsg->Class; Code=PMsg->Code;
ReplyMsg((struct Message *) PMsg);
if (Class!=MOUSEBUTTONS && Code!=SELECTDOWN) continue;
x=PWindow->MouseX; y=PWindow->MouseY;
if (x<12 || x>243 || y<15 || y>40) continue;
GadgetID=ReadPixel(PWindow->RPort,x,y);
if (GadgetID>-1 && GadgetID<32) break;
}
}
colb=INITREG(col);
SetRGB4(cvp,GadgetID,REDREG(colb),GREENREG(colb),BLUEREG(colb));
col=GadgetID;
WCol.PlaneOnOff=col;
DrawImage(PWindow->RPort,&WCol,10,45);
PosPots(depth,col);
PosHSLPots(depth,col);
case SPREAD:
FOREVER {
Wait(1<<PWindow->UserPort->mp_SigBit);
if (PMsg=(struct IntuiMessage *) GetMsg(PWindow->UserPort)) {
Class=PMsg->Class; Code=PMsg->Code;
ReplyMsg((struct Message *) PMsg);
if (Class!=MOUSEBUTTONS && Code!=SELECTDOWN) continue;
x=PWindow->MouseX; y=PWindow->MouseY;
if (x<12 || x>243 || y<15 || y>40) continue;
GadgetID=ReadPixel(PWindow->RPort,x,y);
if (GadgetID>-1 && GadgetID<32) break;
}
}
first=col; last=GadgetID;
if (first>last) {
i=first; first=last; last=i;
}
if (first>=last-1) break;
dospread(first,last);
col=GadgetID;
WCol.PlaneOnOff=col;
DrawImage(PWindow->RPort,&WCol,10,45);
PosPots(depth,col);
PosHSLPots(depth,col);
break;
default:
break;
}
}
}
}
}
static PosPots(depth,col)
int depth,col;
{
ULONG hpr,hpg,hpb;
colb=INITREG(col);
hpr=REDREG(colb)*0x1111;
hpg=GREENREG(colb)*0x1111;
hpb=BLUEREG(colb)*0x1111;
if (RProp.HorizPot==hpr && GProp.HorizPot==hpg && BProp.HorizPot==hpb)
return(0);
NewModifyProp(&Red,PWindow,NULL,FREEHORIZ|AUTOKNOB,hpr,0,1<<12,0,1);
NewModifyProp(&Green,PWindow,NULL,FREEHORIZ|AUTOKNOB,hpg,0,1<<12,0,1);
NewModifyProp(&Blue,PWindow,NULL,FREEHORIZ|AUTOKNOB,hpb,0,1<<12,0,1);
ShowVals(depth,REDREG(colb),GREENREG(colb),BLUEREG(colb),col);
return(0);
}
static PosHSLPots(depth,col)
int depth, col;
{
colb=INITREG(col);
RGBToHSL(colb,&HProp.HorizPot,&SProp.HorizPot,&LProp.HorizPot);
NewModifyProp(&Hue,PWindow,NULL,FREEHORIZ|AUTOKNOB,HProp.HorizPot,0,1<<12,0,1);
NewModifyProp(&Sat,PWindow,NULL,FREEHORIZ|AUTOKNOB,SProp.HorizPot,0,1<<12,0,1);
NewModifyProp(&Lum,PWindow,NULL,FREEHORIZ|AUTOKNOB,LProp.HorizPot,0,1<<12,0,1);
return(0);
}
static SetHSLCols(depth,col)
int depth,col;
{
ULONG rgb, red, green, blue;
rgb=(ULONG) HSLToRGB(HProp.HorizPot,SProp.HorizPot,LProp.HorizPot);
red=rgb>>8; green=rgb>>4; blue=rgb;
SetRGB4(cvp,col,red,green,blue);
PosPots(depth,col);
return(0);
}
static SetCols(depth,col)
int depth;
int col;
{
USHORT re,gr,bl;
re=RProp.HorizPot/0x1111;
gr=GProp.HorizPot/0x1111;
bl=BProp.HorizPot/0x1111;
colb=INITREG(col);
if (re==REDREG(colb) && gr==GREENREG(colb) && bl==BLUEREG(colb)) return(0);
SetRGB4(cvp,col,re,gr,bl);
ShowVals(depth,re,gr,bl,col);
PosHSLPots(depth,col);
return(0);
}
static InitTable(depth)
int depth;
{
int reg;
for (reg=0;reg<(power(2,depth));reg++) {
colb=INITREG(reg);
redtable[reg]=REDREG(colb);
greentable[reg]=GREENREG(colb);
bluetable[reg]=BLUEREG(colb);
}
return(0);
}
static ShowVals(depth,re,gr,bl,col)
int depth,re,gr,bl,col;
{
values[0]=dostr(re);
values[1]=dostr(gr);
values[2]=dostr(bl);
values[3]='\0';
valstext.FrontPen=col^(power(2,depth)-1);
valstext.BackPen=col;
PrintIText(PWindow->RPort,&valstext,115,45);
return(0);
}
static power(base,n)
int base,n;
{
int p;
for (p=1;n>0;--n) p*=base;
return(p);
}
static drawersquares(depth)
int depth;
{
int w,h,ox,x,y,i;
w=235/(power(2,depth)); h=25; ox=12;
if (depth==4) { w=29; h=12; ox=13; }
if (depth==5) { w=14; h=12; ox=17; }
i=0; x=ox; y=15;
while (x<255 && y<45) {
SetAPen(PWindow->RPort,i);
RectFill(PWindow->RPort,x,y,x+w,y+h);
++i;
x+=w;
if (i>=power(2,depth)) break;
if (depth>3 && i==(power(2,(depth-1)))) {
x=ox; y+=h;
}
}
return(0);
}
static dospread(first,last)
int first,last;
{
int redst,greenst,bluest,red1,green1,blue1,red2,green2,blue2,
redw,greenw,bluew,i;
colb=INITREG(first);
red1=REDREG(colb); green1=GREENREG(colb); blue1=BLUEREG(colb);
colb=INITREG(last);
red2=REDREG(colb); green2=GREENREG(colb); blue2=BLUEREG(colb);
redst=((red2-red1)<<8)/(last-first);
greenst=((green2-green1)<<8)/(last-first);
bluest=((blue2-blue1)<<8)/(last-first);
for (i=first+1;i<last;i++) {
redw=red1+(((redst*(i-first))+128)>>8);
greenw=green1+(((greenst*(i-first))+128)>>8);
bluew=blue1+(((bluest*(i-first))+128)>>8);
SetRGB4(cvp,i,redw,greenw,bluew);
}
return(0);
}
/* HSL <-> RGB routines
adapted from the Amiga Programmers' Suite Book 1
by Robert J. Mical
------------------------------------------------------------------------------
* *** hsl.c ****************************************************************
*
* ColorWindow Routine -- HSL Translation Routines
* from Book 1 of the Amiga Programmers' Suite by RJ Mical
*
* Copyright (C) 1986, 1987, Robert J. Mical
* All Rights Reserved.
*
* Any or all of this code can be used in any program as long as this
* entire copyright notice is retained, ok? Thanks.
*
* The Amiga Programmer's Suite Book 1 is copyrighted but freely distributable.
* All copyright notices and all file headers must be retained intact.
* The Amiga Programmer's Suite Book 1 may be compiled and assembled, and the
* resultant object code may be included in any software product. However, no
* portion of the source listings or documentation of the Amiga Programmer's
* Suite Book 1 may be distributed or sold for profit or in a for-profit
* product without the written authorization of the author, RJ Mical.
*
* HISTORY NAME DESCRIPTION
* ----------- -------------- --------------------------------------------
* 3 Jan 87 RJ >:-{)* Clean-up for release
* 27 Feb 86 =RJ Mical= Modified these routines for Zaphod
* January 86 =RJ= Modified the originals for Mandelbrot
* Late 85 =RJ= Created the color window for Graphicraft
*
* *************************************************************************
-----------------------------------------------------------------------------
*/
static HSLToRGB(hue,sat,lum)
USHORT hue, sat, lum;
{
ULONG red,green,blue,rdiff,gdiff,bdiff,foo,ris,fall,inv;
foo=hue/0x2aab; ris=(hue-(foo*0x2aab))*6; fall=0xffff-ris;
red=0xffff; green=0xffff; blue=0xffff;
switch (foo) {
case 0:
green=ris; blue=0;
break;
case 1:
red=fall; blue=0;
break;
case 2:
red=0; blue=ris;
break;
case 3:
red=0; green=fall;
break;
case 4:
red=ris; green=0;
break;
case 5:
green=0; blue=fall;
break;
}
red=(red*lum)>>16; green=(green*lum)>>16; blue=(blue*lum)>>16;
inv=0xffff-sat;
rdiff=lum-red; red=red+((rdiff*inv)>>16);
gdiff=lum-green; green=green+((gdiff*inv)>>16);
bdiff=lum-blue; blue=blue+((bdiff*inv)>>16);
red=(red>>12)&0xf; green=(green>>12)&0xf; blue=(blue>>12)&0xf;
return((SHORT)((red<<8)|(green<<4)|(blue)));
}
static RGBToHSL(rgb,rhue,rsat,rlum)
USHORT rgb;
USHORT *rhue,*rsat,*rlum;
{
LONG min,max,hue,sat,lum,diff,rpart,gpart,bpart,rwork,gwork,bwork;
rwork=((rgb>>8)&0xf)*0x111; gwork=((rgb>>4)&0xf)*0x111; bwork=(rgb&0xf)*0x111;
if (rwork<gwork) min=rwork; else min=gwork; if (bwork<min) min=bwork;
if (rwork>gwork) max=rwork; else max=gwork; if (bwork>max) max=bwork;
lum=max; lum<<=4; diff=max-min;
if (max) {
sat=(diff<<16)/max; if (sat>0xffff) sat=0xffff;
}
else sat=0;
if (sat==0) hue=0;
else {
rpart=(((max-rwork)<<16)/diff)>>4;
gpart=(((max-gwork)<<16)/diff)>>4;
bpart=(((max-bwork)<<16)/diff)>>4;
if (rwork==max) hue=bpart-gpart;
else if (gwork==max) hue=0x2000+rpart-bpart;
else if (bwork==max) hue=0x4000+gpart-rpart;
if (hue<0) hue+=0x6000; hue=(hue*2667)/1000;
}
*rhue=hue; *rsat=sat; *rlum=lum;
return(0);
}
/*--------------------------------------------------------------------------*/
dostr(val)
int val;
{
if (val<10) return(val+48);
return(val+87);
}