           /**************************************************
            *                                                *
            *                    Turmite                     *
            *                    =======                     *
            *                                                *
            *  Autor:              Adresse:       Datum:     *
            *  ------              --------       ------     *
            *  Philipp Schäufele   Zunftstr. 17   17.5.1992  *
            *                      8013 Haar                 *
            *                                                *
            **************************************************/



#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>

#define  LEFT       1 
#define  UP         2
#define  RIGHT      3
#define  DOWN       4 

#define  GO_LEFT    3    
#define  GO_RIGHT   1
#define  GO_FORWARD 0
#define  GO_BACK    2

#define  SCHWARZ    0
#define  ROT        1
#define  ORANGE     2
#define  GELB       3
#define  GRUEN      4
#define  BLAUGRUEN  5
#define  BLAU       6
#define  VIOLETT    7

#define  HALT       255

struct TuringInfo
{
	UBYTE ReadColor;     
	UBYTE WriteColor;
	UBYTE NextDir;
	UBYTE NextPhase;
};

struct TuringInfo TI[][] = 
{
	{  /* Zustand 0 */  
		{ BLAU,  ROT,   GO_RIGHT, 0},
		{ ROT,   GELB,  GO_RIGHT, 0},
		{ GELB,  GRUEN, GO_LEFT,  0},
		{ GRUEN, BLAU,  GO_LEFT,  0}
	} 		
}; 					
/*
struct TuringInfo TI[][] =
{
	{    Zustand 0 
		{ GRUEN,   BLAU,    GO_RIGHT,   1},
		{ SCHWARZ, SCHWARZ, GO_LEFT,    1},
		{ BLAU,    GRUEN,   GO_FORWARD, 0}
	},
	{    Zustand 1 
		{	GRUEN,   SCHWARZ, GO_FORWARD, 0},
		{ SCHWARZ, BLAU,    GO_LEFT,    1},
		{ BLAU,    SCHWARZ, GO_BACK,    0}
	}
};	*/

/*struct TuringInfo TI[][] =
{
	{    Zustand 0  
		{ GRUEN,   BLAU,    GO_RIGHT,   1},
		{ SCHWARZ, ROT,     GO_FORWARD, 1},
		{ BLAU,    GRUEN,   GO_FORWARD, 0},
		{ ROT,     GELB,    GO_BACK,    0},
		{ GELB,    SCHWARZ, GO_BACK,    1}
	},
	{    Zustand 1 
		{	GRUEN,   SCHWARZ, GO_FORWARD, 0},
		{ SCHWARZ, BLAU,    GO_FORWARD, 0},
		{ BLAU,    SCHWARZ, GO_BACK,    1},
		{ ROT,     GRUEN,   GO_RIGHT,   1},
		{ GELB,    ROT,     GO_FORWARD, 1}
	}
};*/
		



#define STARTX    160
#define STARTY    128
#define COLORS    4
#define INITCOLOR BLAU

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Window *Window;
struct Screen *Screen;
struct RastPort *RP;
struct ViewPort *VP;
struct Message *msg;
struct NewScreen NewScreen =
{
	0,0,320,256,3,-1,-1,NULL,
	CUSTOMSCREEN,NULL,NULL,NULL,NULL
};

struct NewWindow NewWindow = 
{
	0,0,320,256,0,0,RAWKEY|MOUSEBUTTONS,
	ACTIVATE|NOCAREREFRESH|BORDERLESS,
	NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN
};

void Fehler(char *ErrStr)
{
	if (ErrStr)
		printf ("%s\n",ErrStr);
	
	if (Window)           CloseWindow (Window);
	if (Screen)           CloseScreen (Screen);
	if (GfxBase)          CloseLibrary(GfxBase);
	if (IntuitionBase)    CloseLibrary(IntuitionBase);
	
	exit(TRUE);
}

void OpenAll(void)
{
	if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",NULL)))
		Fehler ("Keine IntLib!");
	if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",NULL)))
		Fehler ("Keine GfxLib!");
	
	if (!(Screen = (struct Screen *) OpenScreen (&NewScreen)))
		Fehler ("Kann Screen nicht öffnen!");
	NewWindow.Screen = Screen;
	if (!(Window = (struct Window *) OpenWindow (&NewWindow)))
		Fehler ("Kann Window nicht öffnen!");
}

void InitVars(void)
{
	RP = Window->RPort;
	VP = &(Screen->ViewPort);
	
	SetRGB4 (VP,0,0,0,0);    /* schwarz */
	SetRGB4 (VP,1,15,0,0);   /* rot */
	SetRGB4 (VP,2,15,10,0);  /* orange */
	SetRGB4 (VP,3,15,15,0);  /* gelb */
	SetRGB4 (VP,4,0,15,0);   /* grün */
	SetRGB4 (VP,5,0,15,15);  /* blaugrün */
	SetRGB4 (VP,6,0,0,15);   /* blau */
	SetRGB4 (VP,7,15,0,15);  /* violett */
	
	SetRast (RP,INITCOLOR);          /* Screen leeren */
}

void PrintErr(char *ErrStr)
{
	Move (RP,0,200);
	SetAPen (RP,1);
	Text (RP,ErrStr,strlen(ErrStr));
}

void main(void)
{
	int x, y;
	UBYTE i, Direction, Phase;
	BYTE  CurrColor;
	BOOL  found;
	
	OpenAll();
	InitVars();
	
	Phase = 0; Direction = DOWN;  
	Move(RP,x=STARTX,y=STARTY);       /* Turmite in Startposition bringen */
	for(;;)
	{
		if (msg = (struct Message *) GetMsg(Window->UserPort)) 
			break;
		CurrColor = ReadPixel(RP,x,y);  /* Farbwert "unter" der Turmite lesen */
		found = FALSE;
		for (i=0; i<COLORS; i++)        /* Zuständige TuringInfo-Struktur suchen */
		{
			if (TI[Phase][i].ReadColor == CurrColor)		
			{
				found = TRUE;
				break;
			}
		}
		if (!found)
		{
			PrintErr("Farbwert unter T. nicht definiert!");
			break;
		}
		SetAPen (RP,TI[Phase][i].WriteColor);
		WritePixel (RP,x,y);            /* Punkt unter der Turmite umfärben */
		
		/* Neue Bewegunsrichtung, x und y-Koordinaten ausrechnen */
		Direction = Direction+TI[Phase][i].NextDir;
		if (Direction > 4) Direction-=4;
		switch (Direction)
		{
			case UP:      y--;  if (y<0)   y=255; break;
			case DOWN:    y++;  if (y>255) y=0;   break;
			case LEFT:    x--;  if (x<0)   x=319; break;
			case RIGHT:   x++;  if (x>319) x=0;   break;
		}

		if ((Phase = TI[Phase][i].NextPhase) == HALT)
		{
			PrintErr("Turmite gestoppt!");
			break;
		}
	}
	
	WaitPort(Window->UserPort);
	Fehler(NULL);
}
