/*
 *  Copyright (c) 1995 Andreas Schmitz
 *  All rights reserved.
 *
 *  This is a blanker-module for Garshne-Blanker 3.6
 *
 *  Circles 38.1
 *
 */

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

#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>

#include <stdio.h>
#include <math.h>
#include <time.h>
#include <float.h>
#include <stdlib.h>

#include "/includes.h"

#include "liste.h"

#define NOCHANCE (-2)

#define WHEEL   0
#define SCRMODE 2

#define PUNKTE 25751

#include "Circles_rev.h"
STATIC const UBYTE VersTag[] = VERSTAG;

VOID Defaults( PrefObject *Prefs )
{
   Prefs[WHEEL].po_Active = 1;
	Prefs[SCRMODE].po_Depth = 4;
}

/* Kreis so gross wie es geht zeichnen (auf Farbe 0) */
int kreis_expand1(UBYTE *tabelle,struct RastPort *rp,int cx,int cy)
{
   int i,x,y,back;

   if (ReadPixel(rp,cx,cy)!=0) return(NOCHANCE);
   WritePixel(rp,cx,cy);

   for (i=0;i<PUNKTE;i++) {
      if (i%700==10) {
         back=ContinueBlanking();
         if (back!=OK) return(back);
      }
      x=tabelle[i*2];
      y=tabelle[i*2+1];
      if (y==0) {
         back=ReadPixel(rp,cx+x,cy)+ReadPixel(rp,cx-x,cy);
         if (back>0) break;
         back=ReadPixel(rp,cx,cy+x)+ReadPixel(rp,cx,cy-x);
         if (back>0) break;
         WritePixel(rp,cx+x,cy);
         WritePixel(rp,cx-x,cy);
         WritePixel(rp,cx,cy+x);
         WritePixel(rp,cx,cy-x);
         continue;
      }
      if (x==y) {
         back=ReadPixel(rp,cx+x,cy+y)+ReadPixel(rp,cx+x,cy-y);
         if (back>0) break;
         back=ReadPixel(rp,cx-x,cy+y)+ReadPixel(rp,cx-x,cy-y);
         if (back>0) break;
         WritePixel(rp,cx+x,cy+y);
         WritePixel(rp,cx+x,cy-y);
         WritePixel(rp,cx-x,cy+y);
         WritePixel(rp,cx-x,cy-y);
      }
      else {
         back=ReadPixel(rp,cx+x,cy+y)+ReadPixel(rp,cx+x,cy-y);
         if (back>0) break;
         back=ReadPixel(rp,cx-x,cy+y)+ReadPixel(rp,cx-x,cy-y);
         if (back>0) break;
         back=ReadPixel(rp,cx+y,cy+x)+ReadPixel(rp,cx+y,cy-x);
         if (back>0) break;
         back=ReadPixel(rp,cx-y,cy+x)+ReadPixel(rp,cx-y,cy-x);
         if (back>0) break;
         WritePixel(rp,cx+x,cy+y);
         WritePixel(rp,cx+x,cy-y);
         WritePixel(rp,cx-x,cy+y);
         WritePixel(rp,cx-x,cy-y);
         WritePixel(rp,cx+y,cy+x);
         WritePixel(rp,cx+y,cy-x);
         WritePixel(rp,cx-y,cy+x);
         WritePixel(rp,cx-y,cy-x);
      }
   }
   return(OK);
}

/* Kreis so gross wie es geht zeichnen */
int kreis_expand2(UBYTE *tabelle,struct RastPort *rp,int cx,int cy)
{
   int i,x,y,back,farbe;

   farbe=ReadPixel(rp,cx,cy);
   WritePixel(rp,cx,cy);

   for (i=0;i<PUNKTE;i++) {
      if (i%700==10) {
         back=ContinueBlanking();
         if (back!=OK) return(back);
      }
      x=tabelle[i*2];
      y=tabelle[i*2+1];
      if (y==0) {
         back=ReadPixel(rp,cx+x,cy);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx-x,cy);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx,cy+x);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx,cy-x);
         if (back!=farbe) break;
         WritePixel(rp,cx+x,cy);
         WritePixel(rp,cx-x,cy);
         WritePixel(rp,cx,cy+x);
         WritePixel(rp,cx,cy-x);
         continue;
      }
      if (x==y) {
         back=ReadPixel(rp,cx+x,cy+y);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx+x,cy-y);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx-x,cy+y);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx-x,cy-y);
         if (back!=farbe) break;
         WritePixel(rp,cx+x,cy+y);
         WritePixel(rp,cx+x,cy-y);
         WritePixel(rp,cx-x,cy+y);
         WritePixel(rp,cx-x,cy-y);
      }
      else {
         back=ReadPixel(rp,cx+x,cy+y);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx+x,cy-y);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx-x,cy+y);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx-x,cy-y);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx+y,cy+x);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx+y,cy-x);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx-y,cy+x);
         if (back!=farbe) break;
         back=ReadPixel(rp,cx-y,cy-x);
         if (back!=farbe) break;
         WritePixel(rp,cx+x,cy+y);
         WritePixel(rp,cx+x,cy-y);
         WritePixel(rp,cx-x,cy+y);
         WritePixel(rp,cx-x,cy-y);
         WritePixel(rp,cx+y,cy+x);
         WritePixel(rp,cx+y,cy-x);
         WritePixel(rp,cx-y,cy+x);
         WritePixel(rp,cx-y,cy-x);
      }
   }
   if (i==0) return(NOCHANCE);
   return(OK);
}

/* This is the blanker */
LONG Kreise( struct Screen *Scr, SHORT breit, SHORT hoch, UBYTE *tabelle,char whinawh)
{
	struct RastPort *RP = &( Scr->RastPort );
   struct ViewPort *VP = &( Scr->ViewPort );

   int   x,y,colors,
         zeit,
         back,count;

   srand((unsigned)clock());

   colors = (1L << RP->BitMap->Depth);
   SetRGB4( VP, 0, 0, 0, 0 );
	SetRGB4( VP, 1, 0, 0, 0 );
   for (x=2;x<colors;x++) SetRGB4(VP,x,rand()%16,rand()%16,rand()%16);
   colors=colors-2;

   SetOPen(RP,1);
   SetAPen(RP,0);
   RectFill(RP,0,0,breit-1,hoch-1);

	ScreenToFront( Scr );

   zeit=clock()+10;

	while(1) {

   	x=1+rand()%(breit-2);
      y=1+rand()%(hoch-2);

	   SetAPen(RP,2+rand()%colors);

      if (whinawh==0) {
         back=kreis_expand1(tabelle,RP,x,y);
      }
      else {
         back=kreis_expand2(tabelle,RP,x,y);
      }
      if (back==NOCHANCE) {
         count++;
         if (count>breit*hoch/700) return(OK);
      }
      else {
         if (back!=OK) return(back);
         count=0;
      }

      if (clock()>zeit) {
         back=ContinueBlanking();
         if (back!=OK) return(back);
         ScreenToFront( Scr );
         zeit=clock()+10;
      }
	}

	return 0;
}

LONG Blank( PrefObject *Prefs )
{
	struct Screen *Scr;
	struct Window *Wnd;
   UBYTE *tabelle;
	LONG RetVal;
   char depth;
	
   tabelle=(UBYTE *)liste;

   depth=Prefs[SCRMODE].po_Depth;
   if (depth==1) depth=2;

	if( Scr = OpenScreenTags( NULL, SA_Depth, depth,
							 SA_Quiet, TRUE, SA_DisplayID, Prefs[SCRMODE].po_ModeID,
							 SA_Behind, TRUE, SA_Overscan, OSCAN_STANDARD,
							 TAG_DONE ))
	{

      SetRGB4( &( Scr->ViewPort ),0,0,0,0);
		Wnd = BlankMousePointer( Scr );
   	ScreenToFront( Scr );

		do
			RetVal=Kreise(Scr,Scr->Width,Scr->Height,tabelle,(char)Prefs[WHEEL].po_Active);
		while( RetVal == OK );
		
		UnblankMousePointer( Wnd );
		CloseScreen( Scr );
	}
	else RetVal = FAILED;

	return RetVal;
}
