[comp.sys.amiga] Functions for using Area routines

james@uw-atm.UUCP (James M Synge) (12/19/86)

I'm posting this for a friend of mine who doesn't have access to the net.


#! /bin/sh
# This is a shell archive.
#
echo extracting README
cat <<SHAR_EOF >README
  AllocArea, DrawArea, and FreeArea:  Three functions to simplify using
the area drawing functions in the Amiga ROM Kernal.

Copyright (c) 1986 Robert W. Albrecht All Rights Reserved.
                   425 Bellevue Way, #22
                   Bellevue, WA 98004

  These functions may be used in your programs and freely distributed.
This is FREEWARE.  Just don't put them in your book or floppy disk for
sale without getting my permission first.  I'll get pretty hacked off if
you do!

  These three functions are designed to solve everyone's problems with the
Amiga area fill functions.  They are so easy to use even a beginner could
be area filling away in no time!

  I hear there has been alot of bitching about the ROM Kernel
documentation.  The problem is where else do you go?  I purchased a book
which claimed to be a handbook for programming on the Amiga, but the
author had obviously not even tried many of the functions.  Always believe
your header files and the ".doc" section of the ROM Kernel Manual.  Please
don't write about it unless you try it first!  P.S. remember your +Cdb
Linker option!

***************************************************************************

  A key component of the way these functions work is:

               THE Area STRUCTURE


LeftEdge, TopEdge  - Offsets from the upper right corner of your RastPort.

Outline            - The AREA OUTLINE pen for your drawing. If the Outline
                     variable is set to NO_OUTLINE no outline is used.

FrontPen, BackPen  - The foreground and background pens for your drawing.

DrawMode           - The Draw Mode ( JAM1, JAM2 etc. ).

Count              - The Number of verticies in your area.

Points             - A pointer to the first element in an array of short
                     that is at least as long as Count * 2. The values are
                     set equal to the x,y values for the verticies of the
                     area drawing. The values are read as XY XY XY XY...

next               - A pointer to the next in a linked list of Area
                     structures. If this is the last Area structure in
                     the list or you are only drawing one Area, set this
                     variable to NULL (0L). If you don't do this you are
                     likely to get some very suprising results.

***************************************************************************

/*  An example program fragment
 *
 *  This is by no means a complete program!
 *  It will draw a lightning bolt on a HIRES RastPort.
 */

#include <intuition/intuition.h>
#include <area.h>

extern struct AreaMem *AllocArea();
struct AreaMem *am;
struct RastPort *rp;

/****** THE DATA ******/

short Bolt_Points[] =
{ 150, 56, 318, 143, 308, 116, 464, 190, 293, 95, 304, 122, };

struct  Area Bolt =
{
0, 0,
(unsigned char) 1,
(unsigned char) 1,
(unsigned char) 1,
(unsigned char) JAM1,
6,
&Bolt_Points[0],
0L,
};

/****** THE CODE ******/

if( am = AllocArea(rp, 640, 200, 10)  )
   {
   DrawArea(rp, &Bolt, 0, 0);
   FreeArea(am);
   }

SHAR_EOF
echo extracting AreaFunctions.c
cat <<SHAR_EOF >AreaFunctions.c
/**********************************************/
/*        DrawArea.c                          */
/*        AllocArea.c                         */
/*        FreeArea.c                          */
/*                                            */
/*          Written with                      */
/*        Manx C for Amiga                    */
/*                                            */
/*        Copyright 1986                      */
/*        Robert W. Albrecht                  */
/*        425 Bellevue Wy #22                 */
/*        Bellevue WA 98004                   */
/*                                            */
/**********************************************/

/* Will Probably work with Lettuce  (no int) */


#include <intuition/intuition.h>
#include <area.h>
#include <exec/memory.h>

#define ALLOC(X) ((X *)AllocMem((long)sizeof(X),(long)MEMF_CLEAR))
#define CALLOC(X,Y) ((X *)AllocMem((long)Y,(long)MEMF_CLEAR))
#define FREE(X,Y) (FreeMem(X,(long)Y))

extern unsigned char *AllocMem();
extern char *AllocRaster();
extern struct TmpRas *InitTmpRas();
extern void FreeMem();

void FreeArea(a)
struct AreaMem *a;
{
if( !a ) return;
if( a->BitPlane )
   FreeRaster(a->BitPlane, (long) a->Width, (long) a->Height);
if( a->tr )
   FREE(a->tr, sizeof(struct TmpRas) );
if( a->AreaBuffer )
   FREE(a->AreaBuffer, a->BuffSize );
if( a->Info )
   FREE(a->Info, sizeof(struct AreaInfo) );

FREE(a, sizeof(struct AreaMem) );
return;
}

struct AreaMem *AllocArea(rp, Width, Height, Count)
struct RastPort *rp;
unsigned short Width, Height, Count;
{
struct AreaMem *a;

if( !( a = ALLOC(struct AreaMem) ) ) return(a);
a->BuffSize = 5 * Count;

if( !( a->Info = ALLOC(struct AreaInfo) ) )
   goto abort;
if( !( a->AreaBuffer = CALLOC(WORD, a->BuffSize) ) )
   goto abort;
if( !( a->tr = ALLOC(struct TmpRas) ) )
   goto abort;
if( !( a->BitPlane = AllocRaster((long) Width, (long) Height) ) )
   goto abort;

a->Width = Width;
a->Height = Height;

InitArea(a->Info, a->AreaBuffer, (long) Count );
rp->AreaInfo = a->Info;
rp->TmpRas = a->tr =
   InitTmpRas(a->tr, a->BitPlane, (long) RASSIZE(Width, Height) );
return(a);

abort:
FreeArea(a);
return(0L);
}



void DrawArea(rp, area, LeftOffset, TopOffset)
struct RastPort *rp;
struct Area *area;
short LeftOffset, TopOffset;
{
register short i;
BYTE FgPen, BgPen, AOlPen, DrawMode;
USHORT Flags;

FgPen = rp->FgPen;
BgPen = rp->BgPen;
AOlPen = rp->AOlPen;
DrawMode = rp->DrawMode;
Flags = rp->Flags;

while( area )
   {
   SetAPen(rp, (long) area->FrontPen);
   SetBPen(rp, (long) area->BackPen);
   SetDrMd(rp, (long) area->DrawMode);
   if( area->Outline == (unsigned char)NO_OUTLINE )
      rp->Flags &= ~AREAOUTLINE;
   else
      {
      rp->Flags |= AREAOUTLINE;
      rp->AOlPen = area->Outline;
      }

   AreaMove(rp, (long) (area->Points[0] + area->LeftEdge + LeftOffset),
                (long) (area->Points[1] + area->TopEdge + TopOffset) );

   for(i = 2; i < (area->Count * 2); i += 2)
      AreaDraw(rp, (long) (area->Points[i] + area->LeftEdge + LeftOffset),
                   (long) (area->Points[i+1] + area->TopEdge + TopOffset) );

   AreaEnd(rp);
   area = area->next;
   }

SetAPen(rp, (long) FgPen);
SetBPen(rp, (long) BgPen);
SetDrMd(rp, (long) DrawMode);
rp->AOlPen = AOlPen;
rp->Flags = Flags;
return;
}
SHAR_EOF
echo extracting AllocArea.doc
cat <<SHAR_EOF >AllocArea.doc
NAME
      AllocArea -- Allocate area fill stuff and attach it to the RastPort

SYNOPSIS
      AllocArea(rp, Width, Height, Count)

FUNCTION
      Allocates memory for:
      AreaMem structure,
      AreaInfo structure and it's AreaBuffer,
      TmpRas structure and it's bit plane.

      Calls InitArea() and InitTmpRas().

      Attaches AreaInfo and TmpRas structures to your RastPort.

INPUTS
      rp    pointer to your valid RastPort structure.
            ( Can be obtained by rp = Window->RPort; )

      Width    (unsigned short) The maximum width of your area fill.
               I suggest that you make this the same size as your
               RastPort, unless you are low on RAM.

      Height   (unsigned short) The maximum hieght of your area fill.
               I suggest that you make this the same size as your
               RastPort, unless you are low on RAM.

      Count    (unsigned short) The maximum number of verticies you will
               use in your area fill.

RESULTS
      A pointer to an AreaMem structure. Returns 0L if not enough memory
      is available.

BUGS
      Hope Not!

SEE ALSO
      DrawArea()
      FreeArea()
      area.h

AUTHOR
      Copyright (c) 1986 Robert W. Albrecht.  All Rights Reserved.
      425 Bellevue Way, #22
      Bellevue, WA 98004
SHAR_EOF
echo extracting FreeArea.doc
cat <<SHAR_EOF >FreeArea.doc
NAME
      FreeArea - Free memory allocated by AllocArea

SYNOPSIS
      FreeArea(area_mem)

FUNCTION
      Frees all of the memory allocated by AllocArea()
      This function is also used by AllocArea() in case of an abortion.

INPUTS
      area_mem    A pointer to an AreaMem structure obtained from
                  AllocArea().

RESULTS
      memory returned to memory manager

BUGS
      Hope Not!

SEE ALSO
      AllocArea()
      DrawArea()
      area.h

AUTHOR
      Copyright (c) 1986 Robert W. Albrecht.  All Rights Reserved.
      425 Bellevue Way, #22
      Bellevue, WA 98004
SHAR_EOF
echo extracting DrawArea.doc
cat <<SHAR_EOF >DrawArea.doc
NAME
      DrawArea  - Draws one or more area drawings

SYNOPSIS
      DrawArea(rp, area, Left_Offset, Top_Offset)

FUNCTION
      Draws your area drawing whith a left offset and a top offset.

INPUTS
      rp             a pointer to your valid RastPort structure.
                     (can be obtained from rp = Window->RPort; )

      area           a pointer to your filled in Area structure.

      Left_Offset    (short) the left offset to your drawing.

      Top_Offset     (short) the top offset to your drawing.

RESULTS
      If you have done everything properly you should be able to see
      the drawing.

BUGS
      Hope Not!

SEE ALSO
      AllocArea()
      FreeArea()
      area.h

AUTHOR
      Copyright (c) 1986 Robert W. Albrecht.  All Rights Reserved.
      425 Bellevue Way, #22
      Bellevue, WA 98004
SHAR_EOF
echo extracting area.h
cat <<SHAR_EOF >area.h
/**********************************************/
/*                                            */
/*        AREA.H                              */
/*                                            */
/*        C header file for Amiga.            */
/*                                            */
/*        Copyright 1986                      */
/*        Robert W. Albrecht                  */
/*        425 Bellevue Wy #22                 */
/*        Bellevue WA 98004                   */
/*                                            */
/**********************************************/

/* Will Probably work with Lettuce  (no int) */


#ifndef AREA

struct Area
{
short LeftEdge, TopEdge;
unsigned char Outline, FrontPen, BackPen, DrawMode;
unsigned short Count;
short *Points;
struct Area *next;
};


struct AreaMem
{
char *BitPlane;
unsigned short Width;
unsigned short Height;
short *AreaBuffer;
unsigned short BuffSize;
struct AreaInfo *Info;
struct TmpRas *tr;
};

#define NO_OUTLINE ((unsigned char)100)
#define AREA

#endif
SHAR_EOF
exit(0)