/*
 * Article 639 of net.micro.amiga:
 * ion: version B 2.10.2 9/17/84 chuqui version 1.9 3/12/85; site unisoft.UUCP
 * Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site amiga.amiga.UUCP
 * Path: unisoft!dual!lll-crg!gymble!umcp-cs!seismo!caip!topaz!packard!ihnp1!ihnp4!nsc!pyramid!amiga!bobp
 * From: bobp@amiga.UUCP (Robert S. Pariseau)
 * Newsgroups: net.micro.amiga
 * Subject: Fun with 6 Bit Planes (SOURCE)
 * Message-ID: <214@amiga.amiga.UUCP>
 * Date: 9 Nov 85 10:15:42 GMT
 * Date-Received: 18 Nov 85 19:15:06 GMT
 * Reply-To: bobp@snake.UUCP (Robert S. Pariseau)
 * Organization: Commodore-Amiga Inc., 983 University Ave #D, Los Gatos CA 95030
 * Lines: 270
 * 
 * 
 * TITLE:  Fun With 6 Bit Planes (SOURCE)
 * 
 * There are lots of fun things you can do in 6 bit planes on the Amiga,
 * including Hold and Modify color displays and dual-playfield mode
 * with two separately scroll-able, completely independent, 8 color
 * playfields with overlay and transparency.
 * 
 * But tonight I'm going to discuss something you don't already know about
 * your Amiga -- even if you've read all the tech manuals cover to cover.
 * 
 * The specs for the Amiga say that in a completely static, low-resolution
 * display, with nothing fancy going on (like Hold and Modify), you can
 * display up to 32 colors simultaneously out of a pallette of 4096.
 * 
 * Well not quite.
 * 
 * You can actually display up to 64 distinct colors out of that pallette
 * of 4096!  Yes, an unlimited choice of any of 64 colors at each pixel
 * in the screen!
 * 
 * Have I got your attention?
 * 
 * Welcome to Extra-Half-Brite mode.
 * 
 * The Amiga display hardware automatically enters Extra-Half-Brite mode
 * whenever you select a 6 plane display (which must be low res due to
 * the hardware) and have NOT selected either Hold and Modify or Dual
 * Playfield mode.
 * 
 * The graphics kernel software further enforces the rule that you must
 * set the EXTRA_HALFBRITE flag in the ViewModes for the ViewPort (Screen
 * in Intution lingo) or it will automatically trim your screen down to
 * 5 planes.  This is done both for backward compatability and to insure
 * support in future Amiga architectures.
 * 
 * Consider the playfield data bits for a given pixel.  The bits from the
 * first five planes form a color register selector for that pixel,
 * allowing you to choose among the 32 color registers in the Amiga.  The
 * bit from the sixth plane is interpreted as follows:
 *   0 -- Use the color in the selected color register just as specified.
 * 
 *   1 -- Take the color in the selected color register, shift each of
 *        its R, G, and B components right one bit, and use the new
 *        color value thus formed.
 * 
 * The net result is as if you had 64 color registers where the colors
 * in the top 32 were "half-intensity" counterparts of the colors in the
 * bottom 32!
 * 
 * Of course, that means there is a dependency between the choice of
 * colors in the 32 real registers and the resulting colors in the
 * 32 psuedo-registers.  Nevertheless, I assert we have as much right
 * to claim 64 colors on screen as IBM has to claim 16 colors from a
 * monitor that is physically capable of producing only 8 colors at
 * 2 intensities!  At least we can select our 32 colors out of a
 * pallatte of 4096!
 * 
 * Note also that, since fractional color components have no meaning
 * in the hardware, there are several distinct real colors that produce
 * the same extra color.  For instance (in hex):
 *   888 --> 444,    988 --> 444,   898 --> 444,   999 --> 444,  etc.
 * 
 * Despite all this quibbling, with a little thought it's easy to see
 * how you can choose a set of 32 real colors to make sure all 64 real
 * plus extra colors are distinct.  And they are every-pixel-addressable!
 * 
 * Why have we kept this little jewel a secret?  No, it's not that we
 * were planning to lull the competition into complacency and then
 * spring an instant double of the Amiga's color capacity on them.
 * 
 * Actually, the rev of the custom chips in which this worked was the
 * last rev before we went into production.  Thus the info was too
 * late to make it into the current version of the Amiga Hardware
 * Manual.
 * 
 * Some caveats.  Although ALL the consumer machines have the necessary
 * chip rev, there are some older developer's machines out there which
 * can't do this trick.  BEWARE!  Some of the store demo units come out
 * of that older developer's stock and won't contain the Extra-Half-Brite
 * hardware.  Note that you can't hurt anything by running such a program
 * on an older machine -- the values in the 6th bit plane will simply
 * be ignored.
 * 
 * Also the V1.0 printer device will not correctly handle this trick
 * for color printing -- it works fine in V1.1.
 * 
 * The sample program below shows Extra-Half-Brite mode in operation.
 */

/*
 * 
 * -------------------------Program Notes
 * 
 * The Extra program will compile and link cleanly using the native
 * Amiga Lattice C tools on the standard V1.0 C disk.  The Make
 * script in the examples directory will do all the work for you.
 * 
 * I suggest you copy your source file into ram disk, cd over to your
 * C development disk, and type
 *   1> execute Make ram:Extra    [assumes you are where Make is]
 * 
 * Afterwards, copy the resulting Extra program back out of ram: to
 * someplace safe from power failures.
 * 
 * The program itself is pretty straightforward.  It opens a 6 plane
 * low res custom screen and then opens a window in that screen.
 * 64 color patches are then drawn into that window with color register
 * usage increasing left to right then top to bottom from 0 to 63.  For
 * simplicity, this program uses the default color pallette supplied
 * with the new screen.
 * 
 * Due to the EXTRA_HALFBRITE special ViewMode in the screen definition,
 * the bottom 4 rows of color should be the half intensity counterparts
 * of the corresponding patches in the top 4 rows.
 * 
 * The program waits for a CLOSEWINDOW message from Intution, then
 * cleans up and goes away.
 * 
 * -------------------------Program Source Follows:
 * 
 */
 
/***********************************************************************
 *  Extra -- Program to demonstrate Extra-Half-Brite graphics display
 *           mode on the Amiga.
 *
 *  Dale Luck    -- October, 1985
 *  Bob Pariseau -- November 8, 1985  (Editorial changes)
 *
 **********************************************************************/

#include <exec/types.h>
#include <exec/tasks.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <devices/keymap.h>
#include <graphics/copper.h>
#include <graphics/display.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <graphics/view.h>
#include <graphics/gels.h>
#include <graphics/regions.h>
#include <hardware/blit.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>


struct   GfxBase        *GfxBase;         /* Export library base pointers */
struct   IntuitionBase  *IntuitionBase;

struct   Screen   *colscreen;             /* Pointers to new screen and   */
struct   Window   *wndo;                  /* window.                      */

struct   NewScreen newscreen;             /* OpenX() arguments for new    */
struct   NewWindow newwindow;             /* screen and window.           */

struct   TextAttr Font =
{
   "topaz.font",            /* Use standard system font */
   8,
   FS_NORMAL,
   FPF_ROMFONT,
};

struct IntuiMessage *message;



main()
{
   if ((IntuitionBase = (struct  IntuitionBase *)OpenLibrary("intuition.library", 0)) == 0)
   {
      printf("WOT !  No Intuition ???\n");
      exit();
   }

   if ((GfxBase = (struct   GfxBase *)OpenLibrary("graphics.library", 0)) == 0)
   {
      printf("Oh ! No Graphics??\n");
      CloseLibrary(IntuitionBase);
      exit();
   }

/* values for new screen */
   newscreen.LeftEdge       = 0;
   newscreen.TopEdge        = 0;
   newscreen.Width          = 320;
   newscreen.Height         = 200;
   newscreen.Depth          = 6;
   newscreen.DetailPen      = 0;
   newscreen.BlockPen       = 1;
   newscreen.ViewModes      = EXTRA_HALFBRITE;
   newscreen.Type           = CUSTOMSCREEN;
   newscreen.Font           = &Font;
   newscreen.DefaultTitle   = "Six Planes Low Res";
   newscreen.Gadgets        = NULL;
   
   colscreen = (struct Screen *)OpenScreen(&newscreen);
   if (colscreen == 0)
   {
      printf("Screen Failed !!!!!\n");
      CloseLibrary(GfxBase);
      CloseLibrary(IntuitionBase);
      exit();
   }

/* values for new window */
   newwindow.LeftEdge      = 0;
   newwindow.TopEdge       = 15;
   newwindow.Width         = 320;
   newwindow.Height        = 185;
   newwindow.DetailPen     = 0;
   newwindow.BlockPen      = 1;
   newwindow.Flags         = ACTIVATE | SIMPLE_REFRESH | WINDOWCLOSE;
   newwindow.IDCMPFlags    = CLOSEWINDOW;
   newwindow.FirstGadget   = NULL;
   newwindow.CheckMark     = NULL;
   newwindow.Title         = "Extra-Half-Brite Colors!";
   newwindow.Screen        = colscreen;
   newwindow.BitMap        = NULL;
   newwindow.MinWidth      = 20;
   newwindow.MinHeight     = 20;
   newwindow.MaxWidth      = 320;
   newwindow.MaxHeight     = 200;
   newwindow.Type          = CUSTOMSCREEN;

   wndo = (struct Window *)OpenWindow(&newwindow);
   if (wndo == 0)
   {
       printf("Window failed!!!\n"); 
       CloseScreen(colscreen);
       CloseLibrary(GfxBase);
       CloseLibrary(IntuitionBase);
       exit();
   }

   setup(wndo->RPort);

   FOREVER
   {
      WaitPort(wndo->UserPort);
      message = (struct IntuiMessage *)GetMsg(wndo->UserPort);
      if(message->Class == CLOSEWINDOW)
      {
         ReplyMsg(message);       /* Can't reply till done using */
         CloseWindow(wndo);
         CloseScreen(colscreen);
         CloseLibrary(GfxBase);
         CloseLibrary(IntuitionBase);
         exit();
      }
      ReplyMsg(message);
   }
 
}

setup(rastp)
struct RastPort *rastp;
{
   USHORT   countx;
   USHORT   county;
   USHORT   color;

   for (countx = 0; countx < 8; countx++)
      for (county = 0; county < 8; county++)
      {
         color = (county<<3) + countx;
         SetAPen(rastp,color);
         RectFill(rastp,countx*35+10,county*20+15,countx*35+45,county*20+35);
      }
}

