/*
 *  pixel.c   -  Tom Eshelman  -  Reading, Pa.   12/11/88
 *
 *  Program to draw a pixel display using the assembly routine, _pixel.
 *  C call is -  pixel (&bmap, color, x, y); where color = simple constant.
 *  No interpretation of colors is required.
*/


#include <exec/types.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <functions.h>

#define DEPTH     5L
#define WIDTH     320L
#define HEIGHT    200L

#define VPWIDTH   320L
#define VPHEIGHT  200L
#define NUMCOLS   32L

struct  View      view;
struct  ViewPort  vport;
struct  ColorMap  *cm;

struct  RastPort  rport;
struct  BitMap    bmap;
struct  RasInfo   ri;

struct  GfxBase   *GfxBase;
struct  View      *oldview;

UWORD palette[] =
{
   0x000, 0x00c, 0x04e, 0x08f, 0x0cc, 0x0e5, 0x0f0, 0xdf0,
   0xee0, 0xfc0, 0xe90, 0xf42, 0xe06, 0xd0a, 0xb0c, 0x90c,

   0x70c, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666, 0x777,
   0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd, 0xeee, 0xfff
};


extern void pixel();                      /* Here is our Assembly Routine! */



void main()
{
   register short  i, j;

   if ( ! (GfxBase = (struct GfxBase*) OpenLibrary ("graphics.library", 0L)))
       CloseAll();

   oldview = GfxBase->ActiView;

   make_playfields();

   for ( j = 0; j < 200; j++ )               /* For each of 200 lines..*/

      for ( i = 0; i < 320; i++ )            /* Draw 320 pixels.     */

         pixel ( &bmap, j, i, j );                  /* color no., x, y */

   Delay (100L);

   for ( j = 199; j >= 0; j-- )              /* Erase lines in reverse. */

      for ( i = 319; i >= 0; i-- )

         pixel ( &bmap, 0, i, j );                  /* color, x, y */

   CloseAll();
}


make_playfields ()                  /* The usual graphics setup, as seen   */
{                                   /* in nearly every program in the P.D. */
   short   i;

   InitView (&view);
   InitVPort (&vport);

   view.ViewPort = &vport;

   cm = (struct ColorMap*) GetColorMap (NUMCOLS);

   vport.ColorMap = cm;

   vport.DWidth  = VPWIDTH;
   vport.DHeight = VPHEIGHT;
   vport.RasInfo = &ri;
   vport.Modes   = 0;

   InitBitMap (&bmap, DEPTH, WIDTH, HEIGHT);

   for (i = 0; i < DEPTH; i++)
   {
      if ( !(bmap.Planes[i] = (PLANEPTR) AllocRaster (WIDTH, HEIGHT)))

         CloseAll();

      BltClear (bmap.Planes[i], RASSIZE ( WIDTH, HEIGHT ), 0L);
   }

   ri.BitMap   = &bmap;

   ri.RxOffset = 0;
   ri.RyOffset = 0;

   ri.Next = NULL;

   InitRastPort (&rport);
   rport.BitMap = &bmap;

   MakeVPort (&view, &vport);
   MrgCop (&view);

   LoadRGB4 ( &vport, &palette[0], NUMCOLS );

   LoadView (&view);
}



CloseAll()
{
   short  i;

   for (i = 0; i < DEPTH; i++)
   {
      if (bmap.Planes[i])
         FreeRaster ((char*) bmap.Planes[i], WIDTH, HEIGHT);
   }   

   if (cm)
      FreeColorMap (cm);

   FreeVPortCopLists (&vport);               /* Because of MakeVPort */
   FreeCprList (view.LOFCprList);            /* and MrgCop calls.    */

   LoadView (oldview);

   Delay(50L);

   CloseLibrary((long)GfxBase);

}   

