/**********************************************************************
 * AniMaus: Ein kleines nicht einmal trickreiches Programm zum
 * Animieren des Mauszeigers während der Arbeit auf dem Amiga.
 * Das Programm muss gestartet werden mit: RUN AniMaus weil es endlos
 * läuft. Es stört keine anderen Tasks, ausser solche, die den Mauszeiger
 * benutzen (also fast alle !? ).
 * Versuche eigene Images zu entwerfen mit einem Sprite-Maker oder
 * benutzen den transparent Modus.
 *
 * Der Aztec-C-3.4 Compileraufruf sieht folgendermaßen aus:
 * cc AniMaus.c -Iinclude/ +L
 * ln AniMaus.o -Llib/c +CD  Die Sprite-Daten muessen ins CHIP-memory
 *
 * Benutzt man Lattice-C darf nicht vergessen werden mit ATOM -CD die
 * Daten ins CHIP-Memory zu legen und erst danach den Linker aufzurufen.
 *
 * Autor:Bernhard Emese
 * Das Programm ist sehr klein und läuft im Hintergrund. Man kann
 * es auch problemlos zweimal starten.
 **********************************************************************/

#include <exec/types.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>
#include <functions.h>

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

#define POINTER_WIDTH 15      /* nicht 16 da hot spot mittig sein soll */
#define POINTER_HEIGHT 15     /* dasselbe wie oben */
#define POINTER_XOFFSET -8    /* Definition des hot spot in der Mitte 
                                 des Zeigers */
#define POINTER_YOFFSET -7
#define NUMBER_OF_FRAMES 10   /* Anzahl der Bilder */

#define TRANSPARENT FALSE     /* setze TRANSPARENT TRUE für 
                                 Transparent Modus */

/* Das unsichtbare Bild wird im Transparent Modus in jedem zweiten
   Bildschirmbild benutzt, so erscheint
   der Mauszeiger durchsichtig, allerdings ein wenig flackernd wie
   ein interlaced Bild */

UWORD UnvisibleImage[POINTER_HEIGHT*2+4] = {
 0,0,
 0x0000,0x0000, 0x0000,0x0000, 0x0000,0x0000,
 0x0000,0x0000, 0x0000,0x0000, 0x0000,0x0000,
 0x0000,0x0000, 0x0000,0x0000, 0x0000,0x0000,
 0x0000,0x0000, 0x0000,0x0000, 0x0000,0x0000,
 0x0000,0x0000, 0x0000,0x0000, 0x0000,0x0000,
 0,0,
};

/* Hier sind die einzelnen Phasen des Bewegungsablaufs gespeichert */

UWORD PointerImage[NUMBER_OF_FRAMES][POINTER_HEIGHT*2+4] = {
{0,0,
 0x0100,0x0100, 0x0100,0x0100, 0x0100,0x0100,
 0x0100,0x0100, 0x0100,0x0100, 0x0000,0x0100,
 0x0000,0x0100, 0xf93f,0xFeff, 0x0000,0x0100,
 0x0000,0x0100, 0x0100,0x0100, 0x0100,0x0100,
 0x0100,0x0100, 0x0100,0x0100, 0x0100,0x0100,
 0,0,},
{0,0,
 0x0200,0x0200, 0x0200,0x0200, 0x0200,0x0200,
 0x0200,0x0200, 0x0100,0x0100, 0x0000,0x0100,
 0x001e,0x011e, 0x0920,0x0ee0, 0xf000,0xf100,
 0x0000,0x0100, 0x0100,0x0100, 0x0080,0x0080,
 0x0080,0x0080, 0x0080,0x0080, 0x0080,0x0080,
 0,0,},
{0,0,
 0x0400,0x0400, 0x0400,0x0400, 0x0400,0x0400,
 0x0200,0x0200, 0x0200,0x0200, 0x000e,0x010e,
 0x0030,0x0130, 0x0100,0x06c0, 0x1800,0x1900,
 0xe000,0xe100, 0x0080,0x0080, 0x0080,0x0080,
 0x0040,0x0040, 0x0040,0x0040, 0x0040,0x0040,
 0,0,},
{0,0,
 0x0000,0x0000, 0x0800,0x0800, 0x0400,0x0400,
 0x0400,0x0400, 0x0204,0x0204, 0x0018,0x0218,
 0x0020,0x0160, 0x0100,0x0280, 0x0800,0x0d00,
 0x3000,0x3080, 0x4080,0x4080, 0x0040,0x0040,
 0x0040,0x0040, 0x0020,0x0020, 0x0000,0x0000,
 0,0,},
{0,0,
 0x0000,0x0000, 0x1000,0x1000, 0x0800,0x0800,
 0x0804,0x0804, 0x0418,0x0418, 0x0020,0x0220,
 0x0000,0x02c0, 0x0100,0x0000, 0x0000,0x0680,
 0x0800,0x0880, 0x3040,0x3040, 0x4020,0x4020,
 0x0020,0x0020, 0x0010,0x0010, 0x0000,0x0000,
 0,0,},
{0,0,
 0x0000,0x0000, 0x0000,0x0000, 0x2008,0x2008,
 0x1010,0x1010, 0x0820,0x0820, 0x0000,0x0440,
 0x0000,0x0280, 0x0100,0x0000, 0x0000,0x0280,
 0x0000,0x0440, 0x0820,0x0820, 0x1010,0x1010,
 0x2008,0x2008, 0x0000,0x0000, 0x0000,0x0000,
 0,0,},
{0,0,
 0x0000,0x0000, 0x0010,0x0010, 0x0020,0x0020,
 0x4020,0x4020, 0x3040,0x3040, 0x0800,0x0880,
 0x0000,0x0680, 0x0100,0x0000, 0x0000,0x02c0,
 0x0020,0x0220, 0x0418,0x0418, 0x0804,0x0804,
 0x0800,0x0800, 0x1000,0x1000, 0x0000,0x0000,
 0,0,},
{0,0,
 0x0000,0x0000, 0x0020,0x0020, 0x0040,0x0040,
 0x0040,0x0040, 0x4080,0x4080, 0x3000,0x3080,
 0x0800,0x0d00, 0x0100,0x0280, 0x0020,0x0160,
 0x0018,0x0218, 0x0204,0x0204, 0x0400,0x0400,
 0x0400,0x0400, 0x0800,0x0800, 0x0000,0x0000,
 0,0,},
{0,0,
 0x0040,0x0040, 0x0040,0x0040, 0x0040,0x0040,
 0x0080,0x0080, 0x0080,0x0080, 0xe000,0xe100,
 0x1800,0x1900, 0x0100,0x06c0, 0x0030,0x0130,
 0x000e,0x010e, 0x0200,0x0200, 0x0200,0x0200,
 0x0400,0x0400, 0x0400,0x0400, 0x0400,0x0400,
 0,0,},
{0,0,
 0x0080,0x0080, 0x0080,0x0080, 0x0080,0x0080,
 0x0080,0x0080, 0x0100,0x0100, 0x0000,0x0100,
 0xf000,0xf100, 0x0920,0x0ee0, 0x001e,0x011e,
 0x0000,0x0100, 0x0100,0x0100, 0x0200,0x0200,
 0x0200,0x0200, 0x0200,0x0200, 0x0200,0x0200,
 0,0,},
};

/*********************  main **************************/

main()
{
int I;

  if ((IntuitionBase=(struct IntuitionBase *)
         OpenLibrary("intuition.library",LIBRARY_VERSION))==NULL)
    exit(10);
    /* sollte nie passieren - weil intuition.lib immer vorhanden ist */

  if ((GfxBase=(struct GfxBase *)
           OpenLibrary("graphics.library",LIBRARY_VERSION))==NULL)
    exit(10);
    /* kein Problem wie oben, wenn passende LIBRARY_VERSION 33 */

  FOREVER /*  Diese Endlos Schleife ist definiert als: for(;;) */
    for(I=0;I<NUMBER_OF_FRAMES;I++)
    {
     SetPointer(IntuitionBase->ActiveWindow,&PointerImage[I][0],
               POINTER_HEIGHT,POINTER_WIDTH,POINTER_XOFFSET,POINTER_YOFFSET);
/* Dieser Aufruf ändert den Mauszeiger im momentan aktiven Fenster */
      WaitTOF();
/* Ab jetzt schläft der Task für 20 ms, ohne CPU-Zeit zu verbrauchen
   bis zum nächsten Bildschirmbild */ 

/* Im Transparent Modus verschwindet der Mauszeiger jedes zweite Bild,
   auf diese Weise ist der Text darunter immer sichtbar  */
      if (TRANSPARENT)
      {
      SetPointer(IntuitionBase->ActiveWindow,&UnvisibleImage[0],
                POINTER_HEIGHT,POINTER_WIDTH,POINTER_XOFFSET,POINTER_YOFFSET);
        WaitTOF();
      }
    }

/* Die folgenden Zeilen sind nur noetig, wenn die Endlosschleife FOREVER
 * nicht benutzt wird und das Programm aufhören soll zu laufen.
 * Allerdings müßte der ClearPointer Aufruf in jedem Fenster erfolgen,
 * das einmal aktiv war, deshalb kann es passieren, wenn verschiedene
 * Fenster mit AniMaus angeklickt waren, daß dort der Mauszeiger
 * aus Speicherschmutz besteht. Die Fenster muessen geschlossen und
 * neu geöffnet werden. */

/*  ClearPointer(IntuitionBase->ActiveWindow); */
/*  setzt den Mauszeiger auf das Bild das in preferences gesetzt wurde */
/*  CloseLibrary(IntuitionBase); */
/*  CloseLibrary(GfxBase); */
}
