/*-----------------------------------------------------------------------
 -       Demo-Programm zur Programmierung von animierten Sprites        -
 -									-
 - Dieses Programm soll verdeutlichen, wie man animierte Sprites, deren -
 - Daten durch den Movie-Maker Professional berechnet wurden, in C      -
 - programmieren kann.                                                  -
 - Das Programm kann mit dem Aztec-C-Compiler compiliert und dann aus   -
 - dem CLI durch Aufruf des Programmnamens gestartet werden.            -
 - Die Compiler-Anweisungen für Aztec-C lauten folgendermaßen:          -
 - cc Programm.c							-
 - ln +Cd +Fbp Programm.o -lc 	         			   	-
 ------------------------------------------------------------------------*/

#include <stdio.h>
#include <intuition/intuition.h>
#include <graphics/gfxmacros.h>
#include <graphics/sprite.h>

#define ever    (;;)
#define N       NULL

/* Variablen und Strukturen definieren */

struct IntuitionBase *IntuitionBase = N;
struct GfxBase       *GfxBase       = N;
VOID *OpenLibrary();
struct Screen  *scr = N, *OpenScreen();
struct Window  *win = N, *OpenWindow();
struct RastPort *rp;
struct ViewPort *vp;

char *LeftButton = (char *) 0xBFE001;    /* Für Abfrage der linken Maustaste */
long sprnr =0L;    /* Nummer der ersten Bewegungsphase */
long sprmax=7L;   /* Anzahl Bewegungsphasen -1 */
long nummer=2L;   /* Nummer des Sprites, das benutzt werden soll */

/* Daten für Screen und Windows */

struct NewScreen scrdef =           /* Aussehen des Screens definieren */
{ 0, 0, 320, 200, 5, 0, 1, N, CUSTOMSCREEN, N, N, N, N };

struct NewWindow windef =           /* Aussehen des Fensters definieren */
{ 0, 0, 320, 100, 0, 1, N, ACTIVATE, N, N,
  (UBYTE *)"Sprite-Demo", N, N, 0, 0, 0, 0, CUSTOMSCREEN };

/* Hier folgen nun die Sprite-Daten, wie sie vom Programm erzeugt wurden.
   Die Zahlen in der ersten Zeile haben folgende Bedeutung:
   A:BB:CC:DDD:DDD:DDD:DDD
   A   ist ein Flag, das nur vom Programm benutzt wird
   BB  entspricht der Anzahl der Bewegungsphasen
   CC  entspricht der Höhe der Sprites
   DDD sind die Rot-, Grün- und Blauanteile der 4 Farben in hexadezimaler
       Schreibweise, wobei die erste Farbe bei den Sprites immer
       durchsichtig ist, egal welche Werte hier stehen.
-------------------------------------------------------------------------*/

/* 1:08:24:000:F97:B20:0AF */

USHORT sprdat0[] =
{
 0, 0,
 0x0000, 0x03C0, 0x0000, 0x07E0, 0x0000, 0x07FC, 0x07A0, 0x0000,
 0x07F0, 0x0000, 0x06E0, 0x0000, 0x0700, 0x0000, 0x03C0, 0x0000,
 0x0180, 0x0000, 0x0000, 0x0180, 0x0000, 0x03C0, 0x0000, 0x03E0,
 0x0000, 0x07F0, 0x0000, 0x0FF8, 0x0000, 0x1FDC, 0x07C6, 0x3FC8,
 0x67C6, 0x17C0, 0x6780, 0x0780, 0x0740, 0x0740, 0x0680, 0x0680,
 0x0680, 0x0680, 0x0000, 0x0740, 0x0000, 0x07A0, 0x0000, 0x07A0,
 0, 0
};

struct SimpleSprite sprite0 = { sprdat0, 24, 0, 0, 2 };

USHORT sprdat1[] =
{
 0, 0,
 0x0000, 0x03C0, 0x0000, 0x07E0, 0x0000, 0x07FC, 0x07A0, 0x0000,
 0x07F0, 0x0000, 0x06E0, 0x0000, 0x0700, 0x0000, 0x03C0, 0x0000,
 0x0180, 0x0000, 0x0000, 0x0180, 0x0000, 0x03C0, 0x0000, 0x03E0,
 0x0000, 0x06E0, 0x0000, 0x0EF0, 0x0000, 0x0DF8, 0x13C4, 0x0BF8,
 0x1BEC, 0x03E0, 0x07B0, 0x07B0, 0x0F70, 0x0F70, 0x0E70, 0x0E70,
 0x1C00, 0x1C38, 0x0000, 0x383C, 0x0000, 0x3C3C, 0x0000, 0x3C00,
 0, 0
};

struct SimpleSprite sprite1 = { sprdat1, 24, 0, 0, 2 };

USHORT sprdat2[] =
{
 0, 0,
 0x0000, 0x03C0, 0x0000, 0x07E0, 0x0000, 0x07FC, 0x07A0, 0x0000,
 0x07F0, 0x0000, 0x06E0, 0x0000, 0x0700, 0x0000, 0x03C0, 0x0000,
 0x0180, 0x0000, 0x0000, 0x0180, 0x0000, 0x03C0, 0x0000, 0x05A0,
 0x0000, 0x05A0, 0x0000, 0x05A0, 0x0000, 0x05A0, 0x0420, 0x05A0,
 0x07E0, 0x0660, 0x0FF0, 0x0E70, 0x1E78, 0x1E7B, 0x3830, 0x383F,
 0x1000, 0x701E, 0x0000, 0x700C, 0x0000, 0x3800, 0x0000, 0x1800,
 0, 0
};

struct SimpleSprite sprite2 = { sprdat2, 24, 0, 0, 2 };

USHORT sprdat3[] =
{
 0, 0,
 0x0000, 0x03C0, 0x0000, 0x07E0, 0x0000, 0x07FC, 0x07A0, 0x0000,
 0x07F0, 0x0000, 0x06E0, 0x0000, 0x0700, 0x0000, 0x03C0, 0x0000,
 0x0180, 0x0000, 0x0000, 0x0180, 0x0000, 0x03C0, 0x0000, 0x03E0,
 0x0000, 0x0760, 0x0000, 0x0FB0, 0x0000, 0x0FD8, 0x07E4, 0x1FF8,
 0x37EC, 0x0FE0, 0x37B0, 0x07B0, 0x0F70, 0x0F70, 0x0E70, 0x0E70,
 0x1C00, 0x1C38, 0x0000, 0x383C, 0x0000, 0x3C3C, 0x0000, 0x3C00,
 0, 0
};

struct SimpleSprite sprite3 = { sprdat3, 24, 0, 0, 2 };

USHORT sprdat4[] =
{
 0, 0,
 0x0000, 0x03C0, 0x0000, 0x07E0, 0x0000, 0x07FC, 0x07A0, 0x0000,
 0x07F0, 0x0000, 0x06E0, 0x0000, 0x0700, 0x0000, 0x03C0, 0x0000,
 0x0180, 0x0000, 0x0000, 0x0180, 0x0000, 0x03C0, 0x0000, 0x03E0,
 0x0000, 0x07F0, 0x0000, 0x0FF8, 0x0000, 0x1FDC, 0x07C6, 0x3FC8,
 0x67C6, 0x17C0, 0x6780, 0x0780, 0x0740, 0x0740, 0x0680, 0x0680,
 0x0680, 0x0680, 0x0000, 0x0740, 0x0000, 0x07A0, 0x0000, 0x07A0,
 0, 0
};

struct SimpleSprite sprite4 = { sprdat4, 24, 0, 0, 2 };

USHORT sprdat5[] =
{
 0, 0,
 0x0000, 0x03C0, 0x0000, 0x07E0, 0x0000, 0x07FC, 0x07A0, 0x0000,
 0x07F0, 0x0000, 0x06E0, 0x0000, 0x0700, 0x0000, 0x03C0, 0x0000,
 0x0180, 0x0000, 0x0000, 0x0180, 0x0000, 0x03C0, 0x0000, 0x03E0,
 0x0000, 0x0760, 0x0000, 0x0FB0, 0x0000, 0x0FD8, 0x07C4, 0x1FD8,
 0x35EC, 0x0DE0, 0x36F0, 0x06F0, 0x0F70, 0x0F70, 0x0E70, 0x0E70,
 0x1C00, 0x1C38, 0x0000, 0x383C, 0x0000, 0x3C3C, 0x0000, 0x3C00,
 0, 0
};

struct SimpleSprite sprite5 = { sprdat5, 24, 0, 0, 2 };

USHORT sprdat6[] =
{
 0, 0,
 0x0000, 0x03C0, 0x0000, 0x07E0, 0x0000, 0x07FC, 0x07A0, 0x0000,
 0x07F0, 0x0000, 0x06E0, 0x0000, 0x0700, 0x0000, 0x03C0, 0x0000,
 0x0180, 0x0000, 0x0000, 0x0180, 0x0000, 0x03C0, 0x0000, 0x05A0,
 0x0000, 0x05A0, 0x0000, 0x05A0, 0x0000, 0x05A0, 0x0420, 0x05A0,
 0x07E0, 0x0660, 0x0FF0, 0x0E70, 0x1E78, 0x1E7B, 0x3830, 0x383F,
 0x1000, 0x701E, 0x0000, 0x700C, 0x0000, 0x3800, 0x0000, 0x1800,
 0, 0
};

struct SimpleSprite sprite6 = { sprdat6, 24, 0, 0, 2 };

USHORT sprdat7[] =
{
 0, 0,
 0x0000, 0x03C0, 0x0000, 0x07E0, 0x0000, 0x07FC, 0x07A0, 0x0000,
 0x07F0, 0x0000, 0x06E0, 0x0000, 0x0700, 0x0000, 0x03C0, 0x0000,
 0x0180, 0x0000, 0x0000, 0x0180, 0x0000, 0x03C0, 0x0000, 0x03E0,
 0x0000, 0x06E0, 0x0000, 0x0EF0, 0x0000, 0x0DF8, 0x13C4, 0x0BF8,
 0x1AEC, 0x02E0, 0x06F0, 0x06F0, 0x0F70, 0x0F70, 0x0E70, 0x0E70,
 0x1C00, 0x1C38, 0x0000, 0x383C, 0x0000, 0x3C3C, 0x0000, 0x3C00,
 0, 0
};

struct SimpleSprite sprite7 = { sprdat7, 24, 0, 0, 2 };

/*-----> Hauptprogramm <-----*/

main()
{
 long x=10L, y=75L;  /* Start-Koordinaten des Sprites */
 long freg;          /* Farbregister */


 if (!(IntuitionBase = (struct IntuitionBase *)
  OpenLibrary ("intuition.library", 1L)))  /* Intuition-Bibliothek öffnen */
   { Ende(); exit(501L); }
 if (!(GfxBase = (struct GfxBase *)
  OpenLibrary ("graphics.library", 1L)))   /* Grafik-Bibliothek öffnen */
   { Ende(); exit(502L); }
 if (!(scr = OpenScreen (&scrdef)))        /* Neuen Screen öffnen */
  { Ende(); exit(503L); }
 windef.Screen = scr;
 if (!(win = OpenWindow (&windef)))        /* Fenster öffnen */
  { Ende(); exit(504L); }
 rp = &scr->RastPort;      /* Zeiger auf RastPort-Struktur */
 vp = &scr->ViewPort;      /* Zeiger auf ViewPort-Struktur */

 /* Farben des Sprites definieren: */

 freg=17+4*(nummer/2);
 SetRGB4(vp, freg,   0xFL, 0x9L, 0x7L); /* Die Werte für die RGB-Anteile    */
 SetRGB4(vp, freg+1, 0xBL, 0x2L, 0x0L); /* findet man in der ersten Zeile   */
 SetRGB4(vp, freg+2, 0x0L, 0xAL, 0xFL); /* der vom Programm erzeugten Daten */

 FreeSprite(nummer);                /* Sprite Nr.2 löschen falls schon belegt */
 GetSprite(&sprite0, nummer);       /* Sprite Nr.2 definieren */

 for ever                           /* Endlos-Schleife */
 {
  Anim();                           /* Animationsprogramm aufrufen */
  x=x+2;                            /* X-Koordinate erhöhen */
  MoveSprite(vp, &sprite0, x, y);   /* Sprite an neue Position bewegen */
  if (x>300) x=10L;                 /* Wieder von vorne beginnnen */
  Delay(8L);                        /* Zeit-Verzögerung */
  if (!(*LeftButton & 64)) break;   /* Abfrage der linken Maustaste */
 }
 Ende();
}                                   /* Programmende */

/* Screen, Fenster und Bibliotheken schließen */

Ende()
{
 FreeSprite(nummer);
 if (win) CloseWindow (win);
 if (scr) CloseScreen (scr);
 if (GfxBase) CloseLibrary (GfxBase);
 if (IntuitionBase) CloseLibrary (IntuitionBase);
}

/* Hier folgt das eigentliche Animations-Programm
   Arbeitsweise:
   Zuerst wird der Zähler sprnr erhöht. Überschreitet er den Wert von sprmax,
   so wird er auf 0 gesetzt. Abhängig vom Wert des Zählers (sprnr) wird nun
   das Aussehen des Sprites mit der Bibliotheks-Funktion "ChangeSprite"
   geändert. */

Anim()
{
 sprnr++;
 if (sprnr>sprmax) sprnr=0L;
 switch (sprnr)
 {
  case 0: ChangeSprite(vp, &sprite0, &sprdat0[0]);
          break;
  case 1: ChangeSprite(vp, &sprite0, &sprdat1[0]);
          break;
  case 2: ChangeSprite(vp, &sprite0, &sprdat2[0]);
          break;
  case 3: ChangeSprite(vp, &sprite0, &sprdat3[0]);
          break;
  case 4: ChangeSprite(vp, &sprite0, &sprdat4[0]);
          break;
  case 5: ChangeSprite(vp, &sprite0, &sprdat5[0]);
          break;
  case 6: ChangeSprite(vp, &sprite0, &sprdat6[0]);
          break;
  case 7: ChangeSprite(vp, &sprite0, &sprdat7[0]);
          break;
 }
}
