/* sprite.c
 * convert an ILBM record to a sprite.
 * Written by David N. Junod
 *
 */

#include <exec/types.h>
#include <exec/libraries.h>
#include <exec/memory.h>
#include <iff/ilbm.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfx.h>
#include <graphics/displayinfo.h>
#include <graphics/sprite.h>
#include <libraries/prefs.h>
#include <clib/macros.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <pragmas/exec.h>
#include <pragmas/intuition.h>
#include <pragmas/graphics.h>
#include <string.h>

extern struct Library *GfxBase, *IntuitionBase;

ILBM *ReadILBM (BPTR drawer, STRPTR name, struct TagItem * attrs);
VOID FreeILBM (ILBM * ilbm);

/* extra memory (in bytes ) allocated for control info and terminator	*/
#define SPMEM_EXTRA		( 2 * sizeof (short int) + 2 *  sizeof (short int))
#define SPMEM_BYTES( height )	(SPMEM_EXTRA+2*sizeof (short int) *(height))

/* word index to reserved at bottom	*/
#define SPMEM_RSRVD( height ) 	(2 + 2 * (height))
#define	SPRF_FORCED	(1)

struct PointerPref *MakePointer (ILBM * ilbm)
{
    struct PointerPref *pp = NULL;
    struct RastPort *srp = &(ilbm->ir_RPort);

    /* Allocate the preference structure */
    if (pp = (struct PointerPref *) AllocVec (sizeof (*pp), MEMF_CLEAR))
    {
	/* Setup the dimension information */
	pp->pp_Height = ilbm->ir_Height;
	pp->pp_Width = 16;	/* ilbm->ir_Width; */
	pp->pp_XOffset = -(ilbm->ir_Grab.x);
	pp->pp_YOffset = -(ilbm->ir_Grab.y);

	/* Calculate size of sprite data */
	pp->pp_DSize = (LONG) SPMEM_BYTES (pp->pp_Height);

	/* Allocate sprite data */
	if (pp->pp_PData = (UWORD *) AllocVec (pp->pp_DSize, MEMF_CLEAR | MEMF_CHIP))
	{
	    /* Lotsa stack */
	    struct BitMap spr_BMap = {NULL};
	    struct RastPort spr_RPort = {NULL};
	    struct RastPort *drp = &spr_RPort;
	    struct BitMap *dbm = &spr_BMap;

	    /* Setup position control terminator */
	    pp->pp_PData[SPMEM_RSRVD (pp->pp_Height)] = 0;
	    pp->pp_PData[SPMEM_RSRVD (pp->pp_Height) + 1] = 0;

	    /* Initialize the bitmap */
	    InitBitMap (dbm, 2L, 32L, (LONG) pp->pp_Height);

	    /* Do weird magic with the planes */
	    dbm->Planes[0] = (PLANEPTR) (pp->pp_PData + 2);
	    dbm->Planes[1] = (PLANEPTR) (pp->pp_PData + 3);

	    /* Initialize the RastPort */
	    InitRastPort (drp);
	    drp->BitMap = dbm;
	    SetRast (drp, 0);

	    /* Copy the ILBM into the sprite */
	    ClipBlit (srp, 0, 0, drp, 0, 0, pp->pp_Width, pp->pp_Height, 0xC0);
	}
	else
	{
	    FreeVec ((APTR) pp);
	    pp = NULL;
	}
    }

    return (pp);
}

VOID FreePointer (struct PointerPref * pp)
{

    if (pp)
    {
	if (pp->pp_PData)
	{
	    FreeVec (pp->pp_PData);
	}

	FreeVec (pp);
    }
}
