home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / code_examples / cmanual_456 / colourwindow / colourwindow.c < prev    next >
C/C++ Source or Header  |  1990-11-24  |  37KB  |  1,302 lines

  1. /* Name: ColourWindow.c
  2.  
  3.    CCC                                W     W
  4.   C   C                               W     W
  5.   C      OOO  L      OOO  U   U RRRR  W     W III N   N DDD    OOO  W     W
  6.   C     O   O L     O   O U   U R   R W     W  I  NN  N D  D  O   O W     W
  7.   C     O   O L     O   O U   U RRRR  W  W  W  I  N N N D   D O   O W  W  W
  8.   C   C O   O L     O   O U   U R  R   W W W   I  N  NN D  D  O   O  W W W
  9.    CCC   OOO  LLLLL  OOO   UUU  R   R   W W   III N   N DDD    OOO    W W
  10.  
  11.  
  12.   COLOUR WINDOW   VERSION 1.00   90-07-22
  13.  
  14.   Yet another program dedicated to Sioe-Lin Kwik.
  15.   
  16.  
  17.   COLOUR WINDOW was created by Anders Bjerin, and is distributed as
  18.   public domain with NO RIGHTS RESERVED. That means that you can do
  19.   what ever you want with the program.
  20.   
  21.   You may use COLOUR WINDOW in your own programs, commercial or not,
  22.   and do not even need to mention that you have used it. You may
  23.   alter the source code to fit your needs, and you may spread it to
  24.   anyone.
  25.   
  26.     
  27.   
  28.   COLOUR WINDOW is written to be as easy as possible to use, and is
  29.   fully amigaized. COLOUR WINDOW is very easy to install in your
  30.   program, and I have even done an example on how to use it. The
  31.   source code is full of comments to make it easier for you to change
  32.   something in the program. If you would have any problems, feel
  33.   free to contact me.
  34.  
  35.   If you have any questions, ideas, programs (PD or your own) etc etc,
  36.   or just want to say hello, PLEASE WRITE TO ME:
  37.  
  38.   Anders Bjerin
  39.   Amiga C Club (ACC)
  40.   Tulevagen 22
  41.   181 41  LIDINGO
  42.   SWEDEN
  43.  
  44.  
  45.  
  46.   III N   N FFFFF  OOO  RRRR  M   M  AAA  TTTTTTT III  OOO  N   N
  47.    I  NN  N F     O   O R   R MM MM A   A    T     I  O   O NN  N
  48.    I  N N N FFF   O   O RRRR  M M M AAAAA    T     I  O   O N N N
  49.    I  N  NN F     O   O R  R  M   M A   A    T     I  O   O N  NN
  50.   III N   N F      OOO  R   R M   M A   A    T    III  OOO  N   N
  51.  
  52.   ColourWindow is the first and only true colour requester in the
  53.   Public Domain. It adjust itself to any depth (2, 4, 8, 16 or 32
  54.   colours), and can be used with high- as well as low resolution
  55.   screens. Everything is done by the rules, and this program will
  56.   return everything it has taken, and use a minimum of processing
  57.   time. It is yet another program releaced from the Amiga C Club! 
  58.  
  59.   result = ColourWindow( screen, title, x, y );
  60.  
  61.   result:    (UBYTE) ColourWindow will return a flag which tells
  62.              your program what has happened:
  63.                OK      The user selected the OK gadget.
  64.                CANCEL  The user selected the CANCEL gadget.
  65.                QUIT    The user closed the window.
  66.                ERROR   Something went wrong. (Not enough memory,
  67.                        or the x, y coordinates were too big so
  68.                        the window could not fit on the screen.)
  69.  
  70.   screen:    (struct Screen *) Pointer to the screen ColourWindow
  71.              should be connected to. If you want that the user
  72.              should be able to change the colour of the Workbench
  73.              screen, set the pointer to NULL. (REMEMBER! The
  74.              Workbench screen's colours should normally only
  75.              be changed with Preferences!)
  76.               
  77.   title:     (STRPTR) Pointer to a string containing the title of
  78.              Colour Window, or NULL if you do not want any title.
  79.  
  80.   x:         (SHORT) X position of Colour Window.
  81.  
  82.   y:         (SHORT) Y position of Colour Window.
  83.  
  84.  
  85.   Remember to include the file "ColourWindow.h"!
  86.  
  87.  
  88.  
  89.   Program:                 ColourWindow
  90.   Version:                 1.00
  91.   Programmer:              Anders Bjerin
  92.   Language:                C (100%)
  93.   Compiler:                Lattice C Compiler, V5.04
  94.   Linker:                  Blink, V5.04
  95.   AmigaDOS:                V1.2 and V1.3
  96.   Ref. nr:                 4A-636-2B
  97.  
  98.   Amiga is a registered trademark of Commodore-Amiga, Inc.
  99.   AmigaDOS is a registered trademark of Commodore-Amiga, Inc.
  100.   Lattice is a registered trademark of Lattice, Inc.
  101.  
  102.  
  103.  
  104.   ENJOY YOUR AMIGA, AND MAKE EVERYONE ELSE ENJOY IT TOO!
  105.  
  106.   Anders Bjerin
  107.  
  108. */
  109.  
  110.  
  111.  
  112. #include <intuition/intuition.h>
  113. #include "ColourWindow.h"
  114.  
  115.  
  116.  
  117. /* The Intuition and Graphics library must be opened before a program */
  118. /* may call teh ColourWindow() function:                              */
  119. extern struct IntuitionBase *IntuitionBase;
  120. extern struct GfxBase *GfxBase;
  121.  
  122.  
  123.  
  124. /* Sprite Data for the three pointers we will use: */
  125.  
  126. /* 1. Pointer data: "TO" */
  127. USHORT chip pointer_to_data[36]=
  128. {
  129.   0x0000, 0x0000,
  130.  
  131.   0x0000, 0xfc00,
  132.   0x7c00, 0xfe00,
  133.   0x7c00, 0x8600,
  134.   0x7800, 0x8c00,
  135.   0x7c00, 0x8600,
  136.   0x6e00, 0x9300,
  137.   0x0700, 0x6980,
  138.   0x0380, 0x04c0,
  139.   0x01c0, 0x0260,
  140.   0x0080, 0x0140,
  141.   0x0000, 0x0080,
  142.   0x3e70, 0x0108,
  143.   0x0888, 0x0444,
  144.   0x0888, 0x0444,
  145.   0x0888, 0x0444,
  146.   0x0870, 0x0408,
  147.  
  148.   0x0000, 0x0000
  149. };
  150.  
  151. /* 2. Pointer data: "TWO" */
  152. USHORT chip pointer_two_data[36]=
  153. {
  154.   0x0000, 0x0000,
  155.  
  156.   0x0000, 0x0c30,
  157.   0x0810, 0x1c38,
  158.   0x1818, 0x2fec,
  159.   0x3ffc, 0x47e6,
  160.   0x7ffe, 0x8003,
  161.   0x3ffc, 0x4002,
  162.   0x1818, 0x27e4,
  163.   0x0810, 0x1428,
  164.   0x0000, 0x0c30,
  165.   0x0000, 0x0000,
  166.   0x0000, 0x0000,
  167.   0x0000, 0x0000,
  168.   0x0000, 0x0000,
  169.   0x0000, 0x0000,
  170.   0x0000, 0x0000,
  171.   0x0000, 0x0000,
  172.  
  173.   0x0000, 0x0000
  174. };
  175.  
  176. /* 3. Pointer data: "NORMAL" */
  177. USHORT chip pointer_normal_data[36]=
  178. {
  179.   0x0000, 0x0000,
  180.  
  181.   0x0000, 0xfc00,
  182.   0x7c00, 0xfe00,
  183.   0x7c00, 0x8600,
  184.   0x7800, 0x8c00,
  185.   0x7c00, 0x8600,
  186.   0x6e00, 0x9300,
  187.   0x0700, 0x6980,
  188.   0x0380, 0x04c0,
  189.   0x01c0, 0x0260,
  190.   0x0080, 0x0140,
  191.   0x0000, 0x0080,
  192.   0x0000, 0x0000,
  193.   0x0000, 0x0000,
  194.   0x0000, 0x0000,
  195.   0x0000, 0x0000,
  196.   0x0000, 0x0000,
  197.  
  198.   0x0000, 0x0000
  199. };
  200.  
  201.  
  202.  
  203. /* Normal Topaz font, 80 characters/line, ROM: */
  204. struct TextAttr rom_font=
  205. {
  206.   "topaz.font", /* The name of the font. */
  207.   TOPAZ_EIGHTY, /* 80 characters/line. */
  208.   FS_NORMAL,    /* Normal (plain) style. */
  209.   FPF_ROMFONT   /* ROM font. */
  210. };
  211.  
  212.  
  213.  
  214. /* PROPORTIONAL GADGET: RED */
  215.  
  216. struct IntuiText red_text=
  217. {
  218.   1,          /* FrontPen */
  219.   0,          /* BackPen */
  220.   JAM1,       /* DrawMode */
  221.   -10, 2,     /* LeftEdge */
  222.   &rom_font,  /* ITextFont */
  223.   "R",        /* IText */
  224.   NULL,       /* NextText */
  225. };
  226.  
  227. struct Image red_knob;
  228.  
  229. struct PropInfo red_info=
  230. {
  231.   AUTOKNOB|        /* Flatgs */
  232.   FREEHORIZ,
  233.   0,               /* HorizPot */
  234.   0,               /* VertPot */
  235.   MAXBODY/16,      /* HorizBody */
  236.   0,               /* VertBody */
  237.   0, 0, 0, 0, 0, 0 /* Initialized and maintained by Intuition. */
  238. };
  239.  
  240. struct Gadget red_gadget=
  241. {
  242.   NULL,             /* NextGadget */
  243.   15,               /* LeftEdge */
  244.   11,               /* TopEdge */
  245.   153,              /* Width */
  246.   11,               /* Height */
  247.   GADGHCOMP,        /* Flags */
  248.   GADGIMMEDIATE|    /* Activation */
  249.   RELVERIFY|
  250.   FOLLOWMOUSE,
  251.   PROPGADGET,       /* GadgetType */
  252.   (APTR) &red_knob, /* GadgetRender */
  253.   NULL,             /* SelectRender */
  254.   &red_text,        /* GadgetText */
  255.   0,                /* MutualExclude */
  256.   (APTR) &red_info, /* SpecialInfo */
  257.   0,                /* GadgetID */
  258.   NULL              /* UserData */
  259. };
  260.  
  261.  
  262.  
  263. /* PROPORTIONAL GADGET: GREEN */
  264.  
  265. struct IntuiText green_text=
  266. {
  267.   1,          /* FrontPen */
  268.   0,          /* BackPen */
  269.   JAM1,       /* DrawMode */
  270.   -10, 2,     /* LeftEdge */
  271.   &rom_font,  /* ITextFont */
  272.   "G",        /* IText */
  273.   NULL,       /* NextText */
  274. };
  275.  
  276. struct Image green_knob;
  277.  
  278. struct PropInfo green_info=
  279. {
  280.   AUTOKNOB|        /* Flatgs */
  281.   FREEHORIZ,
  282.   0,               /* HorizPot */
  283.   0,               /* VertPot */
  284.   MAXBODY/16,      /* HorizBody */
  285.   0,               /* VertBody */
  286.   0, 0, 0, 0, 0, 0 /* Initialized and maintained by Intuition. */
  287. };
  288.  
  289. struct Gadget green_gadget=
  290. {
  291.   &red_gadget,        /* NextGadget */
  292.   15,                 /* LeftEdge */
  293.   23,                 /* TopEdge */
  294.   153,                /* Width */
  295.   11,                 /* Height */
  296.   GADGHCOMP,          /* Flags */
  297.   GADGIMMEDIATE|      /* Activation */
  298.   RELVERIFY|
  299.   FOLLOWMOUSE,
  300.   PROPGADGET,         /* GadgetType */
  301.   (APTR) &green_knob, /* GadgetRender */
  302.   NULL,               /* SelectRender */
  303.   &green_text,        /* GadgetText */
  304.   0,                  /* MutualExclude */
  305.   (APTR) &green_info, /* SpecialInfo */
  306.   0,                  /* GadgetID */
  307.   NULL                /* UserData */
  308. };
  309.  
  310.  
  311.  
  312. /* PROPORTIONAL GADGET: BLUE */
  313.  
  314. struct IntuiText blue_text=
  315. {
  316.   1,          /* FrontPen */
  317.   0,          /* BackPen */
  318.   JAM1,       /* DrawMode */
  319.   -10, 2,     /* LeftEdge */
  320.   &rom_font,  /* ITextFont */
  321.   "B",        /* IText */
  322.   NULL,       /* NextText */
  323. };
  324.  
  325. struct Image blue_knob;
  326.  
  327. struct PropInfo blue_info=
  328. {
  329.   AUTOKNOB|        /* Flatgs */
  330.   FREEHORIZ,
  331.   0,               /* HorizPot */
  332.   0,               /* VertPot */
  333.   MAXBODY/16,      /* HorizBody */
  334.   0,               /* VertBody */
  335.   0, 0, 0, 0, 0, 0 /* Initialized and maintained by Intuition. */
  336. };
  337.  
  338. struct Gadget blue_gadget=
  339. {
  340.   &green_gadget,     /* NextGadget */
  341.   15,                /* LeftEdge */
  342.   35,                /* TopEdge */
  343.   153,               /* Width */
  344.   11,                /* Height */
  345.   GADGHCOMP,         /* Flags */
  346.   GADGIMMEDIATE|     /* Activation */
  347.   RELVERIFY|
  348.   FOLLOWMOUSE,
  349.   PROPGADGET,        /* GadgetType */
  350.   (APTR) &blue_knob, /* GadgetRender */
  351.   NULL,              /* SelectRender */
  352.   &blue_text,        /* GadgetText */
  353.   0,                 /* MutualExclude */
  354.   (APTR) &blue_info, /* SpecialInfo */
  355.   0,                 /* GadgetID */
  356.   NULL               /* UserData */
  357. };
  358.  
  359.  
  360.  
  361. /* Data for a six-letter box: */
  362.  
  363. SHORT points6[10]=
  364. {
  365.   0,   0,
  366.   52,  0,
  367.   52, 10,
  368.   0,  10,
  369.   0,   0
  370. };
  371.  
  372. struct Border box6=
  373. {
  374.   0,       /* LeftEdge */
  375.   0,       /* TopEdge */
  376.   1,       /* FrontPen */
  377.   0,       /* BackPen */
  378.   JAM1,    /* DrawMode */
  379.   5,       /* Count */
  380.   points6, /* XY */
  381.   NULL     /* NextBorder */
  382. };
  383.  
  384.  
  385.  
  386. /* Data for a four-letter box: */
  387.  
  388. SHORT points4[10]=
  389. {
  390.   0,   0,
  391.   36,  0,
  392.   36, 10,
  393.   0,  10,
  394.   0,   0
  395. };
  396.  
  397. struct Border box4=
  398. {
  399.   0,       /* LeftEdge */
  400.   0,       /* TopEdge */
  401.   1,       /* FrontPen */
  402.   0,       /* BackPen */
  403.   JAM1,    /* DrawMode */
  404.   5,       /* Count */
  405.   points4, /* XY */
  406.   NULL     /* NextBorder */
  407. };
  408.  
  409.  
  410.  
  411. /* Data for a two-letter box: */
  412.  
  413. SHORT points2[10]=
  414. {
  415.   0,   0,
  416.   20,  0,
  417.   20, 10,
  418.   0,  10,
  419.   0,   0
  420. };
  421.  
  422. struct Border box2=
  423. {
  424.   0,       /* LeftEdge */
  425.   0,       /* TopEdge */
  426.   1,       /* FrontPen */
  427.   0,       /* BackPen */
  428.   JAM1,    /* DrawMode */
  429.   5,       /* Count */
  430.   points2, /* XY */
  431.   NULL     /* NextBorder */
  432. };
  433.  
  434.  
  435.  
  436. /* BOOLEAN GADGET: SPREAD */
  437.  
  438. struct IntuiText spread_text=
  439. {
  440.   1,          /* FrontPen */
  441.   0,          /* BackPen */
  442.   JAM1,       /* DrawMode */
  443.   3, 2,       /* LeftEdge, TopEdge */
  444.   &rom_font,  /* ITextFont */
  445.   "SPREAD",   /* IText */
  446.   NULL,       /* NextText */
  447. };
  448.  
  449. struct Gadget spread_gadget=
  450. {
  451.   &blue_gadget, /* NextGadget */
  452.   195,          /* LeftEdge */
  453.   23,           /* TopEdge */
  454.   53,           /* Width */
  455.   11,           /* Height */
  456.   GADGHCOMP,    /* Flags */
  457.   RELVERIFY,    /* Activation */
  458.   BOOLGADGET,   /* GadgetType */
  459.   (APTR) &box6, /* GadgetRender */
  460.   NULL,         /* SelectRender */
  461.   &spread_text, /* GadgetText */
  462.   0,            /* MutualExclude */
  463.   NULL,         /* SpecialInfo */
  464.   0,            /* GadgetID */
  465.   NULL          /* UserData */
  466. };
  467.  
  468.  
  469.  
  470. /* BOOLEAN GADGET: EX */
  471.  
  472. struct IntuiText ex_text=
  473. {
  474.   1,          /* FrontPen */
  475.   0,          /* BackPen */
  476.   JAM1,       /* DrawMode */
  477.   3, 2,       /* LeftEdge, TopEdge */
  478.   &rom_font,  /* ITextFont */
  479.   "EX",       /* IText */
  480.   NULL,       /* NextText */
  481. };
  482.  
  483. struct Gadget ex_gadget=
  484. {
  485.   &spread_gadget, /* NextGadget */
  486.   251,            /* LeftEdge */
  487.   23,             /* TopEdge */
  488.   21,             /* Width */
  489.   11,             /* Height */
  490.   GADGHCOMP,      /* Flags */
  491.   RELVERIFY,      /* Activation */
  492.   BOOLGADGET,     /* GadgetType */
  493.   (APTR) &box2,   /* GadgetRender */
  494.   NULL,           /* SelectRender */
  495.   &ex_text,       /* GadgetText */
  496.   0,              /* MutualExclude */
  497.   NULL,           /* SpecialInfo */
  498.   0,              /* GadgetID */
  499.   NULL            /* UserData */
  500. };
  501.  
  502.  
  503.  
  504. /* BOOLEAN GADGET: COPY */
  505.  
  506. struct IntuiText copy_text=
  507. {
  508.   1,          /* FrontPen */
  509.   0,          /* BackPen */
  510.   JAM1,       /* DrawMode */
  511.   3, 2,       /* LeftEdge, TopEdge */
  512.   &rom_font,  /* ITextFont */
  513.   "COPY",     /* IText */
  514.   NULL,       /* NextText */
  515. };
  516.  
  517. struct Gadget copy_gadget=
  518. {
  519.   &ex_gadget,   /* NextGadget */
  520.   195,          /* LeftEdge */
  521.   35,           /* TopEdge */
  522.   37,           /* Width */
  523.   11,           /* Height */
  524.   GADGHCOMP,    /* Flags */
  525.   RELVERIFY,    /* Activation */
  526.   BOOLGADGET,   /* GadgetType */
  527.   (APTR) &box4, /* GadgetRender */
  528.   NULL,         /* SelectRender */
  529.   ©_text,   /* GadgetText */
  530.   0,            /* MutualExclude */
  531.   NULL,         /* SpecialInfo */
  532.   0,            /* GadgetID */
  533.   NULL          /* UserData */
  534. };
  535.  
  536.  
  537.  
  538. /* BOOLEAN GADGET: UNDO */
  539.  
  540. struct IntuiText undo_text=
  541. {
  542.   1,          /* FrontPen */
  543.   0,          /* BackPen */
  544.   JAM1,       /* DrawMode */
  545.   3, 2,       /* LeftEdge, TopEdge */
  546.   &rom_font,  /* ITextFont */
  547.   "UNDO",     /* IText */
  548.   NULL,       /* NextText */
  549. };
  550.  
  551. struct Gadget undo_gadget=
  552. {
  553.   ©_gadget, /* NextGadget */
  554.   235,          /* LeftEdge */
  555.   35,           /* TopEdge */
  556.   37,           /* Width */
  557.   11,           /* Height */
  558.   GADGHCOMP,    /* Flags */
  559.   RELVERIFY,    /* Activation */
  560.   BOOLGADGET,   /* GadgetType */
  561.   (APTR) &box4, /* GadgetRender */
  562.   NULL,         /* SelectRender */
  563.   &undo_text,   /* GadgetText */
  564.   0,            /* MutualExclude */
  565.   NULL,         /* SpecialInfo */
  566.   0,            /* GadgetID */
  567.   NULL          /* UserData */
  568. };
  569.  
  570.  
  571.  
  572. /* BOOLEAN GADGET: OK */
  573.  
  574. struct IntuiText ok_text=
  575. {
  576.   1,          /* FrontPen */
  577.   0,          /* BackPen */
  578.   JAM1,       /* DrawMode */
  579.   3, 2,       /* LeftEdge, TopEdge */
  580.   &rom_font,  /* ITextFont */
  581.   "OK",       /* IText */
  582.   NULL,       /* NextText */
  583. };
  584.  
  585. struct Gadget ok_gadget=
  586. {
  587.   &undo_gadget, /* NextGadget */
  588.   195,          /* LeftEdge */
  589.   65,           /* TopEdge */
  590.   21,           /* Width */
  591.   11,           /* Height */
  592.   GADGHCOMP,    /* Flags */
  593.   RELVERIFY,    /* Activation */
  594.   BOOLGADGET,   /* GadgetType */
  595.   (APTR) &box2, /* GadgetRender */
  596.   NULL,         /* SelectRender */
  597.   &ok_text,     /* GadgetText */
  598.   0,            /* MutualExclude */
  599.   NULL,         /* SpecialInfo */
  600.   0,            /* GadgetID */
  601.   NULL          /* UserData */
  602. };
  603.  
  604.  
  605.  
  606. /* BOOLEAN GADGET: CANCEL */
  607.  
  608. struct IntuiText cancel_text=
  609. {
  610.   1,          /* FrontPen */
  611.   0,          /* BackPen */
  612.   JAM1,       /* DrawMode */
  613.   3, 2,       /* LeftEdge, TopEdge */
  614.   &rom_font,  /* ITextFont */
  615.   "CANCEL",   /* IText */
  616.   NULL,       /* NextText */
  617. };
  618.  
  619. struct Gadget cancel_gadget=
  620. {
  621.   &ok_gadget,   /* NextGadget */
  622.   219,          /* LeftEdge */
  623.   65,           /* TopEdge */
  624.   53,           /* Width */
  625.   11,           /* Height */
  626.   GADGHCOMP,    /* Flags */
  627.   RELVERIFY,    /* Activation */
  628.   BOOLGADGET,   /* GadgetType */
  629.   (APTR) &box6, /* GadgetRender */
  630.   NULL,         /* SelectRender */
  631.   &cancel_text, /* GadgetText */
  632.   0,            /* MutualExclude */
  633.   NULL,         /* SpecialInfo */
  634.   0,            /* GadgetID */
  635.   NULL          /* UserData */
  636. };
  637.  
  638.  
  639.  
  640. /* Declare and initialize the ColourWindow data structure: */
  641. struct NewWindow colour_window_data=
  642. {
  643.   0,             /* LeftEdge    x position, will be changed.             */
  644.   0,             /* TopEdge     y position, will be cahnged.             */
  645.   277,           /* Width       277 pixels wide.                         */
  646.   80,            /* Height      80 lines high.                           */
  647.   0,             /* DetailPen   Text should be drawn with col. reg. 0    */
  648.   1,             /* BlockPen    Blocks should be drawn with col. reg. 1  */
  649.   MOUSEMOVE|     /* IDCMPFlags  Report when: 1. The mouse moves          */
  650.   MOUSEBUTTONS|  /*                          2. Buttons are pressed      */
  651.   GADGETDOWN|    /*                          3. Gadgets down             */
  652.   GADGETUP|      /*                          4. Gadgets up               */
  653.   CLOSEWINDOW,   /*                          5. Window is closed.        */
  654.   SMART_REFRESH| /* Flags       Intuition should refresh the window.     */
  655.   WINDOWDRAG|    /*             Special gadgets: Window Drag             */
  656.   WINDOWDEPTH|   /*                              Depth Gadgets           */
  657.   WINDOWCLOSE|   /*                              Close Gadget            */
  658.   ACTIVATE|      /*             The window should be activated.          */
  659.   RMBTRAP,       /*             No menu operations.                      */
  660.   &cancel_gadget,/* FirstGadget Pointer to the first gadget.             */
  661.   NULL,          /* CheckMark   Use Intuition's default CheckMark.       */
  662.   NULL,          /* Title       Title of the window, will be changed.    */
  663.   NULL,          /* Screen      Pointer to the screen, will be changewd. */
  664.   NULL,          /* BitMap      No Custom BitMap.                        */
  665.   0,             /* MinWidth    We do not need to care about these since */
  666.   0,             /* MinHeight   we have not supplied the window with a   */
  667.   0,             /* MaxWidth    Sizing Gadget.                           */
  668.   0,             /* MaxHeight                                            */
  669.   WBENCHSCREEN   /* Type        Connected to the WBS, will be changed.   */
  670. };
  671.  
  672.  
  673.  
  674. /* Declare the functions we are going to use: */
  675. UBYTE ColourWindow();
  676. void Box();
  677. void PrintValues();
  678. void IntToStr2();
  679. void DrawScale();
  680. void DrawColourBoxes();
  681. void SelectColour();
  682. void FixProp();
  683. void Spread();
  684.  
  685.  
  686.  
  687. UBYTE ColourWindow( screen, title, x, y )
  688. struct Screen *screen;
  689. STRPTR title;
  690. SHORT x, y;
  691. {
  692.   UBYTE count; /* How many colours: 2, 4, 8, 16 or 32. */
  693.   UBYTE loop;  /* Used in loops.                       */
  694.  
  695.   UBYTE order = WORKING; /* WORKING, CANCEL, QUIT or OK.     */
  696.   UBYTE mode = NOTHING;  /* NOTHING, COPY, EXCHANGE, SPREAD. */
  697.  
  698.   /* Intuition message:                                        */
  699.   ULONG class;          /* IDCMP flag.                         */
  700.   USHORT code;          /* Extra information. (SELECTDOWN)     */
  701.   SHORT mousex, mousey; /* Mouse position.                     */
  702.   APTR address;         /* Pointer to the broadcasting gadget. */
  703.  
  704.   /* Pointer to the message structure: */
  705.   struct IntuiMessage *my_message;
  706.  
  707.   UBYTE red, green, blue; /* RGB colour values. */
  708.  
  709.   /* If the prop. gadgets need to be refreshed: */
  710.   BOOL refresh_red = FALSE;
  711.   BOOL refresh_green = FALSE;
  712.   BOOL refresh_blue = FALSE;
  713.  
  714.   UBYTE rgb1[32][3]; /* Master backup of the colour values.        */
  715.   UBYTE rgb2[32][3]; /* Backup of the colour values. Used by "UNDO". */
  716.  
  717.   UBYTE colour = 0;     /* Colour register we are working with.  */
  718.   UBYTE old_colour = 0; /* Colour register we worked with.       */
  719.   UWORD *colour_table;  /* Pointer to the screen's colour table. */
  720.  
  721.   struct Window *colour_window; /* Pointer to the ColourWindow. */
  722.  
  723.  
  724.  
  725.   /* Before we open the window we need to set the last values in the */
  726.   /* colour_window_data structure:                                   */
  727.  
  728.   if( screen ) /* Check if we are going to use a CUSTOM screen. */
  729.   {
  730.     colour_window_data.Screen = screen;
  731.     colour_window_data.Type = CUSTOMSCREEN;
  732.   }
  733.   
  734.   colour_window_data.Title = title; /* Set the title of the window. */
  735.  
  736.   colour_window_data.LeftEdge = x; /* Set the x and y position of the */
  737.   colour_window_data.TopEdge = y;  /* ColourWindow.                   */
  738.  
  739.  
  740.  
  741.   /* Open the window: */
  742.   colour_window = (struct Window *) OpenWindow( &colour_window_data );
  743.   
  744.   if(colour_window == NULL)
  745.     return( ERROR ); /* Could NOT open the Window! */
  746.  
  747.  
  748.  
  749.   /* If we do not have a pointer to a screen, we look in the Window */
  750.     /* structure to find the pointer to the Workbench Screen:         */
  751.     if( screen == NULL )
  752.       screen = colour_window->WScreen; 
  753.  
  754.   /* Find the colour table: */
  755.   colour_table = (UWORD *) screen->ViewPort.ColorMap->ColorTable;
  756.  
  757.  
  758.  
  759.   /* Change the pointer: "normal" */
  760.   SetPointer( colour_window, pointer_normal_data, 16, 16, -1, -1 );
  761.  
  762.  
  763.  
  764.   /* Update the prop. gadgets values: */
  765.   FixProp( colour_table, colour, colour_window );
  766.  
  767.   /* Draw the colour boxes: */
  768.   DrawColourBoxes( screen->BitMap.Depth, colour_window->RPort );
  769.   /* Select a colour (colour register 0): */
  770.   SelectColour( screen->BitMap.Depth, colour_window->RPort,
  771.                 colour, old_colour );
  772.  
  773.   /* Prepare the pencisl, and drawing modes: */
  774.   SetAPen( colour_window->RPort, 1 );
  775.   SetBPen( colour_window->RPort, 0 );
  776.   SetDrMd( colour_window->RPort, JAM2 );
  777.  
  778.   Box( colour_window->RPort, 171, 11, 191, 21 ); /* Box for R's values. */
  779.   Box( colour_window->RPort, 171, 23, 191, 33 ); /* Box for G's values. */
  780.   Box( colour_window->RPort, 171, 35, 191, 45 ); /* Box for B's values. */
  781.   Box( colour_window->RPort, 195, 11, 271, 21 ); /* Box for selected c. */
  782.  
  783.   /* Draw the scale under the prop. gadget: */
  784.   DrawScale( colour_window->RPort );
  785.  
  786.   /* Initialize the RGB values, corresponding to the prop. gadgets: */
  787.   red = red_info.HorizPot / (float)MAXPOT * 15 + 0.5;
  788.   green = green_info.HorizPot / (float) MAXPOT * 15 + 0.5;
  789.   blue = blue_info.HorizPot / (float) MAXPOT * 15 + 0.5;
  790.  
  791.   /* Print the RGB values: */
  792.   PrintValues( colour_window->RPort, red, green, blue );
  793.  
  794.   /* Calculate how many colours, 2, 4, 8, 16 or 32: */
  795.   count = 1 << screen->BitMap.Depth;
  796.  
  797.   /* Make a backup and a master back up of the screen's colour table: */
  798.   for( loop = 0; loop < count; loop++ )
  799.   {
  800.     /* Master back up: (Used if the user selects the CANCEL or */
  801.     /* CLOSEWINDOW gadgets)                                    */
  802.     rgb1[ loop ][ 0 ] = (colour_table[ loop ] & 0xF00) >> 8;
  803.     rgb1[ loop ][ 1 ] = (colour_table[ loop ] & 0x0F0) >> 4;
  804.     rgb1[ loop ][ 2 ] = colour_table[ loop ] & 0x00F;
  805.  
  806.     /* Back up: (Used if the user selects the UNDO gadget. Only the */
  807.     /* last change will be corrected.)                              */
  808.     rgb2[ loop ][ 0 ] = rgb1[ loop ][ 0 ];
  809.     rgb2[ loop ][ 1 ] = rgb1[ loop ][ 1 ];
  810.     rgb2[ loop ][ 2 ] = rgb1[ loop ][ 2 ];
  811.   }
  812.  
  813.  
  814.  
  815.   /* Stay in the while loop until the user has selected the CLOSEWINDOW, */
  816.   /* CANCEL or OK gadget:                                                */
  817.   while( order == WORKING )
  818.   {
  819.     /* Wait until we have recieved a message: */
  820.     /* As long as the user does not work with the Colour Window, the   */
  821.     /* CPU can work undisturbed with other tasks. I wish more programs */
  822.     /* used this function...                                           */
  823.     Wait( 1 << colour_window->UserPort->mp_SigBit );
  824.  
  825.     /* We have now recieved one or more messages. */
  826.  
  827.     /* Since we may recieve several messages we stay in the while loop  */
  828.     /* and collect, save, reply and execute the messages until there is */
  829.     /* a pause:                                                         */
  830.     while( my_message = (struct IntuiMessage *)
  831.            GetMsg( colour_window->UserPort) )
  832.     {
  833.       /* Save some important values:                              */
  834.       class = my_message->Class;      /* IDCMP flag.              */
  835.       code = my_message->Code;        /* Extra information.       */
  836.       mousex = my_message->MouseX;    /* X position of the mouse. */
  837.       mousey = my_message->MouseY;    /* Y position of the mouse. */
  838.       address = my_message->IAddress; /* Pointer to the gadget.   */
  839.  
  840.       /* After we have read the message we reply as fast as possible: */
  841.       /* REMEMBER! Do never try to read a message after you have      */
  842.       /* replied! Some other process has maybe changed it.            */
  843.       ReplyMsg( my_message );
  844.  
  845.       /* Check which IDCMP flag was sent: */
  846.       switch( class )
  847.       {
  848.         case MOUSEBUTTONS:
  849.           /* The user clicked inside the ColourWindow. */
  850.           
  851.           /* Change the pointer: "normal" */
  852.           SetPointer( colour_window, pointer_normal_data,
  853.                       16, 16, -1, -1 );
  854.  
  855.           /* Check if the left mouse button was pressed: */
  856.           if( code == SELECTDOWN )
  857.           {
  858.             old_colour = colour;
  859.             colour = ReadPixel( colour_window->RPort, mousex, mousey );
  860.             
  861.             if( colour != old_colour )
  862.             {
  863.               /* A new colour was selected. */
  864.               
  865.               /* Make a backup of the colour table: */
  866.               for( loop = 0; loop < count; loop++ )
  867.               {
  868.                 rgb2[ loop ][ 0 ] = (colour_table[ loop ] & 0xF00) >> 8;
  869.                 rgb2[ loop ][ 1 ] = (colour_table[ loop ] & 0x0F0) >> 4;
  870.                 rgb2[ loop ][ 2 ] = colour_table[ loop ] & 0x00F;
  871.               }
  872.          
  873.               switch( mode )
  874.               {
  875.                 case COPY:
  876.                   SetRGB4( &screen->ViewPort, colour, red, green, blue );
  877.                   break;
  878.                   
  879.                 case EXCHANGE:
  880.                   SetRGB4( &screen->ViewPort, old_colour,
  881.                          (colour_table[ colour ] & 0xF00) >> 8,
  882.                          (colour_table[ colour ] & 0x0F0) >> 4,
  883.                          colour_table[ colour ] & 0x00F );
  884.                   SetRGB4( &screen->ViewPort, colour, red, green, blue );
  885.                   break;
  886.               
  887.                 case SPREAD:
  888.                   Spread( colour, old_colour, colour_table,
  889.                           &screen->ViewPort );
  890.                   break;
  891.               }         
  892.               
  893.               /* Select the new colour: */
  894.               SelectColour( screen->BitMap.Depth,
  895.                             colour_window->RPort,
  896.                             colour, old_colour );
  897.  
  898.               /* Show the new colour in the colour box: */
  899.               SetAPen( colour_window->RPort, colour );
  900.               RectFill( colour_window->RPort, 196, 12, 270, 20 );
  901.               SetAPen( colour_window->RPort, 1 );
  902.  
  903.               /* Update the prop. gadgets: */
  904.               FixProp( colour_table, colour, colour_window );
  905.             }
  906.             /* Change mode to NOTHING: */
  907.             mode = NOTHING;
  908.           }
  909.           break;
  910.         
  911.         case GADGETDOWN:
  912.           /* One of the prop. gadgets have been selected. */
  913.           /* Change mode to NOTHING: */
  914.           mode = NOTHING;
  915.           /* Change the pointer: "two arrows" */
  916.           SetPointer( colour_window, pointer_two_data,
  917.                       16, 16, -8, -5 );
  918.           break;
  919.         
  920.         case GADGETUP:
  921.           /* The user has released a gadget. */
  922.           /* Change mode to NOTHING: */
  923.           mode = NOTHING;
  924.           SetPointer( colour_window, pointer_normal_data,
  925.           /* Change the pointer: "normal" */
  926.                     16, 16, -1, -1 );
  927.           
  928.           if( address == (APTR) &red_gadget )
  929.             refresh_red = TRUE;
  930.           
  931.           if( address == (APTR) &green_gadget )
  932.             refresh_green = TRUE;
  933.           
  934.           if( address == (APTR) &blue_gadget )
  935.             refresh_blue = TRUE;
  936.           
  937.           if( address == (APTR) ©_gadget )
  938.           {
  939.             /* Change the pointer: "TO" */
  940.             SetPointer( colour_window, pointer_to_data,
  941.                         16, 16, -1, -1 );
  942.             
  943.             /* Change mode to COPY: */
  944.             mode = COPY;
  945.           }
  946.           
  947.           if( address == (APTR) &ex_gadget )
  948.           {
  949.             /* Change the pointer: "TO" */
  950.             SetPointer( colour_window, pointer_to_data,
  951.                         16, 16, -1, -1 );
  952.             
  953.             /* Change mode to COPY: */
  954.             mode = EXCHANGE;
  955.           }
  956.           
  957.           if( address == (APTR) &spread_gadget )
  958.           {
  959.             /* Change the pointer: "TO" */
  960.             SetPointer( colour_window, pointer_to_data,
  961.                         16, 16, -1, -1 );
  962.             
  963.             /* Change mode to SPREAD: */
  964.             mode = SPREAD;
  965.           }
  966.           
  967.           if( address == (APTR) &undo_gadget )
  968.           {
  969.             /* Restore the colours. Use the normal backup: */
  970.             for( loop = 0; loop < count; loop++ )
  971.               SetRGB4( &screen->ViewPort, loop, rgb2[ loop ][ 0 ],
  972.                        rgb2[ loop ][ 1 ], rgb2[ loop ][ 2 ] );
  973.  
  974.             /* Update the prop. gadgets: */
  975.             FixProp( colour_table, colour, colour_window );
  976.           }
  977.           
  978.           if( address == (APTR) &ok_gadget )
  979.             order = OK;
  980.           
  981.           if( address == (APTR) &cancel_gadget )
  982.             order = CANCEL;
  983.           
  984.           break;
  985.  
  986.         case CLOSEWINDOW:
  987.           /* The user has selected the Close window gadget. */
  988.           order = QUIT;
  989.           break;
  990.       }
  991.     }
  992.     
  993.     /* Calculate the new RGB values with the prop. gadg. values: */
  994.     red = red_info.HorizPot / (float)MAXPOT * 15 + 0.5;
  995.     green = green_info.HorizPot / (float) MAXPOT * 15 + 0.5;
  996.     blue = blue_info.HorizPot / (float) MAXPOT * 15 + 0.5;
  997.  
  998.     /* Change the colour: */
  999.     SetRGB4( &screen->ViewPort, colour, red, green, blue );
  1000.     
  1001.     if( refresh_red )
  1002.     {
  1003.       ModifyProp( &red_gadget, colour_window, NULL, red_info.Flags,
  1004.                   (USHORT) (red / (float) 15 * MAXPOT), 0,
  1005.                   red_info.HorizBody, 0 );
  1006.       refresh_red = FALSE;
  1007.     }
  1008.     
  1009.     if( refresh_green )
  1010.     {
  1011.       ModifyProp( &green_gadget, colour_window, NULL, green_info.Flags,
  1012.                   (USHORT) (green / (float) 15 * MAXPOT), 0,
  1013.                   green_info.HorizBody, 0 );
  1014.       refresh_green = FALSE;
  1015.     }
  1016.     
  1017.     if( refresh_blue )
  1018.     {
  1019.       ModifyProp( &blue_gadget, colour_window, NULL, blue_info.Flags,
  1020.                   (USHORT) (blue / (float) 15 * MAXPOT), 0,
  1021.                   blue_info.HorizBody, 0 );
  1022.       refresh_blue = FALSE;
  1023.     }
  1024.     
  1025.     /* Print the new values in the RGB value boxes: */
  1026.     PrintValues( colour_window->RPort, red, green, blue );
  1027.   }
  1028.  
  1029.  
  1030.  
  1031.   /* If the user has selected the CANCEL or CLOSEWINDOW gadget we will */
  1032.   /* Restore the colours by using the master backup:                   */
  1033.   if( order == QUIT || order == CANCEL )
  1034.     for( loop = 0; loop < count; loop++ )
  1035.        SetRGB4( &screen->ViewPort, loop, rgb1[ loop ][ 0 ],
  1036.                 rgb1[ loop ][ 1 ], rgb1[ loop ][ 2 ] );
  1037.  
  1038.  
  1039.  
  1040.   /* Close the ColourWindow and return the control to the calling prog: */
  1041.   CloseWindow( colour_window );
  1042.   return( order );
  1043. }
  1044.  
  1045.  
  1046.  
  1047. /* This function will draw a box with help of four coordinates: */ 
  1048. void Box( rp, x1, y1, x2, y2 )
  1049. struct RastPort *rp;
  1050. UWORD x1, y1, x2, y2;
  1051. {
  1052.   Move( rp, x1, y1 );
  1053.   Draw( rp, x2, y1 );
  1054.   Draw( rp, x2, y2 );
  1055.   Draw( rp, x1, y2 );
  1056.   Draw( rp, x1, y1 );
  1057. }
  1058.  
  1059.  
  1060.  
  1061. /* This function will print the RGB values: */
  1062. void PrintValues( rp, red, green, blue )
  1063. struct RastPort *rp;
  1064. UBYTE red, green, blue;
  1065. {
  1066.   char colour_string[7];
  1067.  
  1068.   /* RED: */
  1069.   IntToStr2( colour_string, red );
  1070.   Move( rp, 174, 19 );
  1071.   Text( rp, colour_string, 2 );
  1072.  
  1073.   /* GREEN: */
  1074.   IntToStr2( colour_string, green );
  1075.   Move( rp, 174, 31 );
  1076.   Text( rp, colour_string, 2 );
  1077.  
  1078.   /* BLUE: */
  1079.   IntToStr2( colour_string, blue );
  1080.   Move( rp, 174, 43 );
  1081.   Text( rp, colour_string, 2 );
  1082. }
  1083.  
  1084.  
  1085.  
  1086. /* This function will shange a two dig. integer into a string: */
  1087. void IntToStr2( string, number )
  1088. STRPTR string;
  1089. int number;
  1090. {
  1091.   stci_d( string, number );
  1092.   if( number < 10 )
  1093.   {
  1094.     string[1] = string[0];
  1095.     string[0] = ' ';
  1096.   }
  1097. }
  1098.  
  1099.  
  1100.  
  1101. /* This function will draw the scale under the prop. gadgets: */
  1102. void DrawScale( rp )
  1103. struct RastPort *rp;
  1104. {
  1105.   int loop;
  1106.   
  1107.   for( loop=0; loop < 17; loop++ )
  1108.   {
  1109.     Move( rp, 19 + loop * 9, 48 );
  1110.     Draw( rp, 19 + loop * 9, 50 + (loop % 2 ? 0 : 2) );
  1111.   }
  1112. }
  1113.  
  1114.  
  1115.  
  1116. /* This function will draw the colour boxes at the bottom of the window: */
  1117. void DrawColourBoxes( depth, rp )
  1118. UBYTE depth;
  1119. struct RastPort *rp;
  1120. {
  1121.   int loop1, loop2;
  1122.   
  1123.   switch( depth )
  1124.   {
  1125.     case 5: for( loop1 = 0; loop1 < 2; loop1++ )
  1126.               for( loop2 = 0; loop2 < 16; loop2++ )
  1127.               {
  1128.                 SetAPen( rp, loop1*16+loop2 );
  1129.                 RectFill( rp, 6+11*loop2, 57+10*loop1,
  1130.                               15+11*loop2, 65+10*loop1 );
  1131.               }
  1132.               break;
  1133.               
  1134.     case 4: for( loop1 = 0; loop1 < 16; loop1++ )
  1135.             {
  1136.               SetAPen( rp, loop1 );
  1137.               RectFill( rp, 6+11*loop1, 57,
  1138.                             15+11*loop1, 75 );
  1139.             }
  1140.             break;
  1141.             
  1142.     case 3: for( loop1 = 0; loop1 < 8; loop1++ )
  1143.             {
  1144.               SetAPen( rp, loop1 );
  1145.               RectFill( rp, 6+22*loop1, 57,
  1146.                             26+22*loop1, 75 );
  1147.             }
  1148.             break;
  1149.             
  1150.     case 2: for( loop1 = 0; loop1 < 4; loop1++ )
  1151.             {
  1152.               SetAPen( rp, loop1 );
  1153.               RectFill( rp, 6+44*loop1, 57,
  1154.                             48+44*loop1, 75 );
  1155.             }
  1156.             break;
  1157.             
  1158.     case 1: for( loop1 = 0; loop1 < 2; loop1++ )
  1159.             {
  1160.               SetAPen( rp, loop1 );
  1161.               RectFill( rp, 6+88*loop1, 57,
  1162.                             92+88*loop1, 75 );
  1163.             }
  1164.   }
  1165. }
  1166.  
  1167.  
  1168.  
  1169. /* This function will draw a box around the selected colour: */
  1170. void SelectColour( depth, rp, colour, old_colour )
  1171. UBYTE depth;
  1172. struct RastPort *rp;
  1173. UBYTE colour, old_colour;
  1174. {
  1175.   switch( depth )
  1176.   {
  1177.     case 5: SetAPen( rp, 0 );
  1178.             if( old_colour < 16 )
  1179.               Box( rp, 5+11*old_colour, 56, 16+11*old_colour, 66 );
  1180.             else
  1181.               Box( rp, 5+11*(old_colour-16), 66,
  1182.                        16+11*(old_colour-16), 76 );
  1183.             
  1184.             SetAPen( rp, 1 );
  1185.             if( colour < 16 )
  1186.               Box( rp, 5+11*colour, 56, 16+11*colour, 66 );
  1187.             else
  1188.               Box( rp, 5+11*(colour-16), 66,
  1189.                        16+11*(colour-16), 76 );
  1190.             break;
  1191.  
  1192.     case 4: SetAPen( rp, 0 );
  1193.             Box( rp, 5+11*old_colour, 56, 16+11*old_colour, 76 );
  1194.             SetAPen( rp, 1 );
  1195.             Box( rp, 5+11*colour, 56, 16+11*colour, 76 );
  1196.             break;
  1197.  
  1198.     case 3: SetAPen( rp, 0 );
  1199.             Box( rp, 5+22*old_colour, 56, 27+22*old_colour, 76 );
  1200.             SetAPen( rp, 1 );
  1201.             Box( rp, 5+22*colour, 56, 27+22*colour, 76 );
  1202.             break;
  1203.  
  1204.     case 2: SetAPen( rp, 0 );
  1205.             Box( rp, 5+44*old_colour, 56, 49+44*old_colour, 76 );
  1206.             SetAPen( rp, 1 );
  1207.             Box( rp, 5+44*colour, 56, 49+44*colour, 76 );
  1208.             break;
  1209.  
  1210.     case 1: SetAPen( rp, 0 );
  1211.             Box( rp, 5+88*old_colour, 56, 93+88*old_colour, 76 );
  1212.             SetAPen( rp, 1 );
  1213.             Box( rp, 5+88*colour, 56, 93+88*colour, 76 );
  1214.             break;
  1215.   }
  1216. }
  1217.  
  1218.  
  1219.  
  1220. /* This function will update the prop. gadgets: */
  1221. void FixProp( colour_table, colour, window )
  1222. UWORD *colour_table;
  1223. UBYTE colour;
  1224. struct Window *window;
  1225. {
  1226.   UBYTE red, green, blue;
  1227.  
  1228.   red = (colour_table[ colour ] & 0xF00) >> 8;
  1229.   green = (colour_table[ colour ] & 0x0F0) >> 4;
  1230.   blue = colour_table[ colour ] & 0x00F;
  1231.  
  1232.   ModifyProp( &red_gadget, window, NULL,
  1233.               red_info.Flags,
  1234.               (USHORT) (red / (float) 15 * MAXPOT), 0,
  1235.               red_info.HorizBody, 0 );
  1236.   ModifyProp( &green_gadget, window, NULL,
  1237.               green_info.Flags,
  1238.               (USHORT) (green / (float) 15 * MAXPOT), 0,
  1239.               green_info.HorizBody, 0 );
  1240.   ModifyProp( &blue_gadget, window, NULL,
  1241.               blue_info.Flags,
  1242.               (USHORT) (blue / (float) 15 * MAXPOT), 0,
  1243.               blue_info.HorizBody, 0 );
  1244. }
  1245.  
  1246.  
  1247.  
  1248. /* This function will calculate the colour values between the new and */
  1249. /* the old colour reg:                                                */
  1250. void Spread( col, old_col, colour_table, vp )
  1251. UBYTE col, old_col;
  1252. UWORD *colour_table;
  1253. struct ViewPort *vp;
  1254. {
  1255.   UBYTE c1, c2, dif;
  1256.   UBYTE r1, g1, b1;
  1257.   UBYTE r2, g2, b2;
  1258.   float dr, dg, db;
  1259.   float fr, fg, fb;
  1260.   UBYTE loop;
  1261.  
  1262.  
  1263.   c1 = col > old_col ? old_col: col; /* Lowest reg.  */
  1264.   c2 = col > old_col ? col: old_col; /* Highest reg. */
  1265.   dif = c2 - c1;                     /* Difference.  */
  1266.   
  1267.   /* Get the RGB values: */
  1268.   r1 = (colour_table[ c1 ] & 0xF00) >> 8;
  1269.   g1 = (colour_table[ c1 ] & 0x0F0) >> 4;
  1270.   b1 = colour_table[ c1 ] & 0x00F;
  1271.   
  1272.   /* Get the RGB values: */
  1273.   r2 = (colour_table[ c2 ] & 0xF00) >> 8;
  1274.   g2 = (colour_table[ c2 ] & 0x0F0) >> 4;
  1275.   b2 = colour_table[ c2 ] & 0x00F;
  1276.   
  1277.   /* Calculate the difference between the RGB values: */
  1278.   dr = (r2 - r1) / (float) dif;
  1279.   dg = (g2 - g1) / (float) dif;
  1280.   db = (b2 - b1) / (float) dif;
  1281.   
  1282.   /* Initialize the float RGB values: */
  1283.   fr = r1;
  1284.   fg = g1;
  1285.   fb = b1;
  1286.  
  1287.   for( loop = c1+1; loop < c2; loop++ )
  1288.   {
  1289.     /* Add the difference: */
  1290.     fr += dr;
  1291.     fg += dg;
  1292.     fb += db;
  1293.  
  1294.     /* Round off to the nearest whole number: */
  1295.     r1 = fr + 0.5;
  1296.     g1 = fg + 0.5;
  1297.     b1 = fb + 0.5;
  1298.     
  1299.     /* Change the colour: */
  1300.     SetRGB4( vp, loop, r1, g1, b1 );
  1301.   }
  1302. }