/*  Demo on how to use SpriteWiz created data in C  -  By D. Visage
    Written with Aztec C 3.4, but should compile with Lattice.

    To compile with Aztec C :  cc +l SW_CDemo.c
    To link with Aztec C    :  ln SW_CDemo.o -lc32

    (c) 1988 Message Software
    James Messa and David A. Visage
    GET THE MESSAGE!                                  */

#include <stdio.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/sprite.h>
#include "Talker.h"

#define VERSION 0      /*  Any version of intuition is cool!  */

/*  Color registers used  */
#define COLOR00  0
#define COLOR01  1
#define COLOR02  2
#define COLOR21  21
#define COLOR22  22
#define COLOR23  23

/*  Define certain maximum values  */
#define MAX_INT     32767
#define MAX_DELAY   3
#define MAX_WIDTH   640
#define MAX_HEIGHT  200

/*  Sprite minimum and maximum (X,Y) coordinates  */
#define MIN_X   5
#define MAX_X   605
#define MIN_Y   10
#define MAX_Y   185

/*  Defines for sprite  */
#define SPRITE02    02
#define SPR_HEIGHT  16

/*  Define return values for all functions used  */
extern struct Window *OpenWindow();
extern struct Library *OpenLibrary();
extern struct Message *GetMsg();
extern struct ViewPort *ViewPortAddress();
extern ULONG GetSprite();
extern unsigned int rand();
extern int GetRand();

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

struct NewWindow MyWindow;
struct SimpleSprite MySprite;

/*  Pointers to various structures  */
struct RastPort *Rp;
struct ViewPort *Vp;
struct Window  *WindowPtr;
struct IntuiMessage *MessagePtr;

char *PromoStr = "Designing and animating sprites is easy with SpriteWiz!";

main()
{
LONG SprNum;
LONG SpriteX,SpriteY;
LONG TestX,TestY;
WORD SpriteDX,SpriteDY;
int cntr,DelayVal;

/*  Start main program  */
if ( ( IntuitionBase = (struct IntuitionBase *)
        OpenLibrary("intuition.library",VERSION) ) == NULL )
   {
   printf("Cannot find intuition library! \n");
   exit(1);
   };

if ( ( GfxBase = (struct GfxBase *)
        OpenLibrary("graphics.library",VERSION) ) == NULL )
   {
   printf("Cannot find graphics library! \n");
   exit(1);
   };

MyWindow.LeftEdge = 0;
MyWindow.TopEdge = 0;
MyWindow.Width = MAX_WIDTH;
MyWindow.Height = MAX_HEIGHT;
MyWindow.DetailPen = COLOR00;
MyWindow.BlockPen = COLOR01;
MyWindow.Flags = WINDOWCLOSE | SMART_REFRESH | ACTIVATE;
MyWindow.IDCMPFlags = CLOSEWINDOW;
MyWindow.Title = (UBYTE *) "Sprite Wizard C demo - By D. Visage ";
MyWindow.MinWidth = MyWindow.MinHeight = 0;
MyWindow.MaxWidth = MyWindow.MaxHeight = 0;
MyWindow.Type = WBENCHSCREEN;

if ( ( WindowPtr = OpenWindow(&MyWindow) ) == NULL )
   {
   printf("Cannot open your window! \n");
   exit(1);
   };

/*  Get needed ViewPort and RastPort  */
Vp = ViewPortAddress(WindowPtr);
Rp = WindowPtr->RPort;

SetRGB4(Vp,COLOR00,0x0,0x0,0x0);         /*  Background black  */
SetRGB4(Vp,COLOR01,0xf,0xf,0xf);         /*  Borders white     */
SetRGB4(Vp,COLOR02,0xf,0x0,0x0);         /*  All else is red   */

/*  Get Promo string up there  */
SetAPen(Rp,COLOR01);
Move(Rp,100,100);
Text(Rp,PromoStr,(LONG) strlen(PromoStr));

SetSeed();         /*  Seed random number generator  */

/*  Allocate a sprite to play with  */
if ( ( SprNum = GetSprite(&MySprite,SPRITE02) ) == - 1 )
   {
   printf("Could not allocate a sprite! \n");
   exit(1);
   };

/*  Initialize the sprite  */
MySprite.num = SprNum;
MySprite.height = SPR_HEIGHT;
MySprite.x = MIN_X + GetRand(MAX_X - MIN_X);
MySprite.y = MIN_Y + GetRand(MAX_Y - MIN_Y);

/*  Place holders for current (X,Y)  */
SpriteX = MySprite.x;
SpriteY = MySprite.y;

/*  Get random DX direction  */
if ( GetRand(2) == 0 )
   SpriteDX = 1;
else
   SpriteDX = - 1;

/*  Get random DY direction  */
if ( GetRand(2) == 0 )
   SpriteDY = 1;
else
   SpriteDY = - 1;

cntr = NUM_SPRITES - 1;
DelayVal = 0;
while ( TRUE )
  {
  MessagePtr = (struct IntuiMessage *) GetMsg(WindowPtr->UserPort);
  if ( MessagePtr != NULL )
     {
     ReplyMsg(MessagePtr);
     if ( MessagePtr->Class == CLOSEWINDOW )
        {
        FreeSprite(SprNum);
        CloseWindow(WindowPtr);
        exit(0);
        };
     };

  /*  Next (X,Y) position is current (X,Y) + current DX,DY  */
  TestX = SpriteX + SpriteDX;
  TestY = SpriteY + SpriteDY;

  /*  Check if sprite is within bounds  */
  if ( TestX <= MIN_X || TestX >= MAX_X )
     SpriteDX = - (SpriteDX);
  if ( TestY <= MIN_Y || TestY >= MAX_Y )
     SpriteDY = - (SpriteDY);

  /*  Add DX,DY to current sprite (X,Y)  */
  SpriteX += SpriteDX;
  SpriteY += SpriteDY;

  /*  Move that puppy  */
  MoveSprite(Vp,&MySprite,SpriteX,SpriteY);
  Delay(1);

  /*  Pause a bit before flipping images  */
  if ( DelayVal == 0 )
     {
     DelayVal = MAX_DELAY;
     if ( cntr == (NUM_SPRITES - 1) )      /*  Max sprites reached?  */
        cntr = 0;
     else
        cntr++;

     /*  Change colors of current sprite image  */
     SetPackedRGB(Vp,MySprInfo[cntr].SprColor1,COLOR21);
     SetPackedRGB(Vp,MySprInfo[cntr].SprColor2,COLOR22);
     SetPackedRGB(Vp,MySprInfo[cntr].SprColor3,COLOR23);

     /*  Change sprite imagry to next in animation sequence  */
     ChangeSprite(Vp,&MySprite,&MySprInfo[cntr].SpriteData[0]);
     }
  else
     DelayVal--; 
  };                     /*  while (TRUE)  */
}


/*  Set a ViewPort color register from a Packed UWORD  */
SetPackedRGB(VPortPtr,ColorVal,ColorReg)
struct ViewPort *VPortPtr;
UWORD ColorVal;
ULONG ColorReg;
{
ULONG RedBits,GreenBits,BlueBits;

RedBits = (ColorVal >> 8) & 0xf;
GreenBits = (ColorVal >> 4) & 0xf;
BlueBits = ColorVal & 0xf;
SetRGB4(VPortPtr,ColorReg,RedBits,GreenBits,BlueBits);
}


/*  Get a random number between 0 and (MaxRange - 1)  */
GetRand(MaxRange)
int MaxRange;
{
int Divisor,Value;

Divisor = MAX_INT/MaxRange;
Value = rand()/Divisor;
return(Value);
}


/*  Seed random number generator based on the current time  */
SetSeed()
{
ULONG Seconds,MicroSeconds;
unsigned int IntSeconds;

CurrentTime(&Seconds,&MicroSeconds);
IntSeconds = (unsigned int) Seconds;
srand(IntSeconds);
}



