#include	<exec/types.h>
#include        <exec/memory.h> /* soundprod */

#include	<graphics/gfx.h>
#include        <graphics/sprite.h> /* voor sprites */
#include	<intuition/intuition.h>
#include 	<stdio.h> /* ook voor soundprod */
#include 	"df1:iff/jiff.c"

#include "hardware/custom.h" /* soundprod */


#define FRAMES		6
#define SPRHEIGHT	16
#define WORDSPERSPR	(2 * SPRHEIGHT + 4)
#define MAXX		(XMAX-32)
#define MAXY		(YMAX-16)

extern UWORD	ballmask[], ball0[];
extern long	GetSprite();

UBYTE		idx[] = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4 };
struct SimpleSprite	spr[FRAMES];
UWORD		*sprbuf;
UWORD		*sprites[FRAMES];
int		vx[FRAMES], vy[FRAMES];



LONG filesize,s1,s2,per;
char *filename;
short *sndbuffer;


/*This should be in exec/libraries.h */
extern struct Library *OpenLibrary();

/*This should be in intuition/intuition.h */
extern struct Screen *OpenScreen();

/* These are the bases for the libraries you need to do any graphics
   much at all and still multi-task */
struct Library *GfxBase = NULL;
struct Library *LayersBase = NULL;
struct Library	*IntuitionBase = NULL;

/* Well the workbench Screen isn't 320x200x5 so...*/
struct Screen *PlopScreen = NULL;

/* Just one font for me... not static cause you might want it
   in your menu modules. */
struct TextAttr PlopFont =
    {
	"topaz.font",  /* I think this is the ROM font */
	8,
	0,
	0,
    };

/* a NewScreen - I don't know what half of this means either */
static
struct NewScreen PlopNewScreen =
	{
	0, 0, XMAX, YMAX, PLANES,
	0, 1,
	0,
	CUSTOMSCREEN,
	&PlopFont,
	"Plop on Top",
	NULL,
	NULL,
	};

/* To use clip blit need a RastPort.  Pretty useless, a BitMap should
   be enough I think ... or anyway something a little less massive */
struct RastPort PlopRastPort;
struct ViewPort *vp;

void
put_ea_cmap(cmap, colors)
unsigned char *cmap;
long colors;
{
long i;
unsigned long r, g, b;

if (colors > 32)	/*color clipping*/
	colors = 32;

/* This loop is modified to work with Aztec 3.4a 32bit by J. Van Houtven */
/* Modification Date : 20 July 1987 */

for (i=0; i<colors; i++)
	{
         r= *cmap++ >> 4;
         g= *cmap++ >> 4;
         b= *cmap++ >> 4;
         SetRGB4(&PlopScreen->ViewPort,i,(long)r,(long)g,(long)b);
	}
}


main(argc, argv)
int argc;
char *argv[];
{
int i,j,x,y,offset = 0, flag = 0, speed;
struct ILBM_info *info;

/* aanroep van sound routine */

custom.dmacon = 0x0003;
per = 280;
filename = "TAON_1";
filesize = 42676;
MakeSound();


if ((GfxBase =  OpenLibrary("graphics.library", (long)0)) == NULL)
        return(-1);

if ((LayersBase =  OpenLibrary("layers.library", (long)0)) == NULL)
	{
	plop_cleanup();
	return(-2);
	}

if ((IntuitionBase =  OpenLibrary("intuition.library",(long) 0)) == NULL)
	{
	plop_cleanup();
	return(-3);
	}

if ( (PlopScreen = OpenScreen(&PlopNewScreen) ) == NULL)
	{
	plop_cleanup();
	return(-4);
	}
vp = &(PlopScreen->ViewPort);

InitRastPort(&PlopRastPort);
PlopRastPort.Mask = (1<<PLANES)-1;
/*just play it safe in case someone tries to load 6 bit planes...*/

setupsprites ();


for (x=1; x<argc; x++)
{
 if ( (info = read_iff(argv[x], 0) ) != NULL)
 {
  put_ea_cmap(&info->cmap, (1 << info->bitmap.Depth));
  PlopRastPort.BitMap = &info->bitmap;
  ClipBlit( &PlopRastPort, (long)0, (long)0,
           &PlopScreen->RastPort, (long)info->header.x, (long)info->header.y,
	   (long)info->header.w, (long)info->header.h, (long)COPY_MINTERM);

 for (i=0; i<FRAMES; i++)
 {
	if (GetSprite (&spr[i], (long) i+2) < 0)
			plop_cleanup();
	spr[i].x = 16*i;
	spr[i].y = 16*i;
	spr[i].height = SPRHEIGHT;
	ChangeSprite (vp, &spr[i], sprites[i]);
 }
 speed = 4;

 for (i=0; i<FRAMES; i++)
 {
  vx[i]= vy[i]=speed;
 }

 --speed;

 for(j=0;j<1000;j++)
 {
  WaitTOF ();
  for (i=0; i<FRAMES; i++)
  {
   if((spr[i].x += vx[i]) >= MAXX-speed || spr[i].x <= speed)
   {
    vx[i] = -vx[i];
   }

   if((spr[i].y += vy[i]) >= MAXY-speed || spr[i].y <= speed)
   { 
    vy[i] = -vy[i];
   }
  }

  /* Hey !!! ChangeSprite also MOVES the sprites !!!! */
  for (i=0; i<FRAMES; i++) ChangeSprite (vp, &spr[i], sprites[idx[i+offset]]);

   /*  Rotate balls every other loop  */
  if (flag = !flag) offset = (offset + 1) % 6;

 }

  /* scherm schuin */

  y = YMAX-1;
  for(j=0;j<80;j++)
  {
   i=j<<2;
   ScrollRaster(&PlopScreen->RastPort,0L,j-40L,i,0L,i+3L,y);
  }

 for(j=0;j<1000;j++)
 {
  WaitTOF ();
  for (i=0; i<FRAMES; i++)
  {
   if((spr[i].x += vx[i]) >= MAXX-speed || spr[i].x <= speed)
   {
    vx[i] = -vx[i];
   }

   if((spr[i].y += vy[i]) >= MAXY-speed || spr[i].y <= speed)
   { 
    vy[i] = -vy[i];
   }
  }

  /* Hey !!! ChangeSprite also MOVES the sprites !!!! */
  for (i=0; i<FRAMES; i++) ChangeSprite (vp, &spr[i], sprites[idx[i+offset]]);

   /*  Rotate balls every other loop  */
  if (flag = !flag) offset = (offset + 1) % 6;

 }
   /* cleanup sprites */
  
  for (i=0; i<FRAMES; i++)
    if (spr[i].num) FreeSprite ((long) spr[i].num);



  SetAPen(&PlopScreen->RastPort,0);
  for(j=0;j<100;j++)
  {
   Move(&PlopScreen->RastPort,0,j);Draw(&PlopScreen->RastPort,XMAX-1,j);
   Move(&PlopScreen->RastPort,0,YMAX-1-j);Draw(&PlopScreen->RastPort,XMAX-1,YMAX-1-j);
  }

  free_planes(&info->bitmap);
  }
 }
plop_cleanup();
}
/* ====== end of main ======= */

plop_cleanup()
{
register int i;

custom.dmacon = 0x0003;
if(sndbuffer)
        FreeMem(sndbuffer,filesize);

for (i=0; i<FRAMES; i++)
  if (spr[i].num) FreeSprite ((long) spr[i].num);

if (sprbuf)
	FreeMem (sprbuf, 2L * WORDSPERSPR * FRAMES);
if (PlopScreen != NULL)
	CloseScreen(PlopScreen);
if (IntuitionBase != NULL)
	CloseLibrary(IntuitionBase);
if (LayersBase != NULL)
	CloseLibrary(LayersBase);
if (GfxBase != NULL)
	CloseLibrary(GfxBase);
}


MakeSound()
{
LoadSound();
PlaySong();
}  

LoadSound()
{
FILE *fopen(), *fp;
SHORT *ptr;
LONG i;

sndbuffer = AllocMem(filesize,MEMF_CHIP);
ptr = sndbuffer;

custom . dmacon = 0x0003;
fp = fopen(filename,"r");
if (fp == NULL) return(0);

s1 = 0; s2 =filesize;
for (i=0; i<s1; i++)
	getc(fp);

for (i=s1/2; i<s2/2; i++)
	{
	*ptr++ = getc(fp)*256 + getc(fp);
	}

fclose (fp);
}

PlaySong()
{
custom . aud[0].ac_ptr = (UWORD *)sndbuffer;
custom . aud[0].ac_len = s2/2-s1/2;
custom . aud[0].ac_per = per;
custom . aud[0].ac_vol = 64;

custom . aud[1].ac_ptr = (UWORD *)sndbuffer;
custom . aud[1].ac_len = s2/2-s1/2;
custom . aud[1].ac_per = per;
custom . aud[1].ac_vol = 64;

custom . dmacon = 0x8203;
}

setupsprites ()
{
	UWORD *cw;	/* current position in buffer of sprite images */
	UWORD *maskp;	/* current position in ballmask             */
	UWORD *ballp;	/* current position in ball0 data           */
	int frame, scan;

	if (!(sprbuf = AllocMem (2L * WORDSPERSPR * FRAMES, MEMF_CHIP)))
		plop_cleanup();

	cw = sprbuf;	/* current position at top of buffer */
	ballp = ball0;	/* ... top of data to be interleaved */

	for (frame=0; frame<FRAMES; frame++) {
		maskp = ballmask;	/* one mask for all frames */
		sprites[frame] = cw;
		*cw++ = 0;		/* poscntl */
		*cw++ = 0;

		/* one word from ball0, one word from ballmask */
		for (scan=0; scan<SPRHEIGHT; scan++) {
			*cw++ = *maskp++;
			*cw++ = *ballp++;
		}
		*cw++ = 0;	/* termination */
		*cw++ = 0;
	}
}

#asm
*:ts=8 bk=0
_ballmask:
	public	_ballmask

	dc.w	%0000011111100000
	dc.w	%0001111111111000
	dc.w	%0011111111111100
	dc.w	%0111111111111110
	dc.w	%0111111111111110
	dc.w	%1111111111111111
	dc.w	%1111111111111111
	dc.w	%1111111111111111
	dc.w	%1111111111111111
	dc.w	%1111111111111111
	dc.w	%1111111111111111
	dc.w	%0111111111111110
	dc.w	%0111111111111110
	dc.w	%0011111111111100
	dc.w	%0001111111111000
	dc.w	%0000011111100000


_ball0:
	public	_ball0

	dc.w	%0000011001100000
	dc.w	%0001100110011000
	dc.w	%0011001111001100
	dc.w	%0001110000111000
	dc.w	%0011110000111100
	dc.w	%0011100000011100
	dc.w	%1100011111100011
	dc.w	%1000011111100001
	dc.w	%1000011111100001
	dc.w	%1100011111100011
	dc.w	%0011100000011100
	dc.w	%0011110000111100
	dc.w	%0001110000111000
	dc.w	%0011001111001100
	dc.w	%0001100110011000
	dc.w	%0000011001100000


_ball1:
	public	_ball1

	dc.w	%0000010011000000
	dc.w	%0001001100110000
	dc.w	%0010011100011000
	dc.w	%0001100001110010
	dc.w	%0011100001111010
	dc.w	%0111000001111001
	dc.w	%1000111110000111
	dc.w	%1000111110000011
	dc.w	%1000111110000011
	dc.w	%1000111110000111
	dc.w	%0111000001111001
	dc.w	%0011100001111010
	dc.w	%0001100001110010
	dc.w	%0010011100011000
	dc.w	%0001001100110000
	dc.w	%0000010011000000


_ball2:
	public	_ball2

	dc.w	%0000010011000000
	dc.w	%0001001100110000
	dc.w	%0000011000011000
	dc.w	%0011000111100110
	dc.w	%0010000111100010
	dc.w	%0110000111110001
	dc.w	%0001111000001110
	dc.w	%0011111000001110
	dc.w	%0011111000001110
	dc.w	%0001111000001110
	dc.w	%0110000111110001
	dc.w	%0010000111100010
	dc.w	%0011000111100110
	dc.w	%0000011000011000
	dc.w	%0001001100110000
	dc.w	%0000010011000000


_ball3:
	public	_ball3

	dc.w	%0000000110000000
	dc.w	%0000011001100000
	dc.w	%0000110000110000
	dc.w	%0110001111000110
	dc.w	%0110001111000110
	dc.w	%1100011111100011
	dc.w	%0011100000011100
	dc.w	%0111100000011110
	dc.w	%0111100000011110
	dc.w	%0011100000011100
	dc.w	%1100011111100011
	dc.w	%0100001111000010
	dc.w	%0110001111000110
	dc.w	%0000110000110000
	dc.w	%0000011001100000
	dc.w	%0000000110000000


_ball4:		; Batter takes first base
	public	_ball4

	dc.w	%0000001100100000
	dc.w	%0000110011001000
	dc.w	%0001100001100000
	dc.w	%0110011110001100
	dc.w	%0100011110000100
	dc.w	%1000111110000110
	dc.w	%0111000001111000
	dc.w	%0111000001111100
	dc.w	%0111000001111100
	dc.w	%0111000001111000
	dc.w	%1000111110000110
	dc.w	%0100011110000100
	dc.w	%0110011110001100
	dc.w	%0001100001100000
	dc.w	%0000110011001000
	dc.w	%0000001100100000


_ball5:
	public	_ball5

	dc.w	%0000001100100000
	dc.w	%0000110011001000
	dc.w	%0001100011100100
	dc.w	%0100111000011000
	dc.w	%0101111000011100
	dc.w	%1001111000001110
	dc.w	%1110000111110001
	dc.w	%1100000111110001
	dc.w	%1100000111110001
	dc.w	%1110000111110001
	dc.w	%1001111000001110
	dc.w	%0101111000011100
	dc.w	%0101111000011000
	dc.w	%0001100011100100
	dc.w	%0000110011001000
	dc.w	%0000001100100000

#endasm





