/*

 FCDEMO.C - Filled Circle Drawing, Using horizontal, then vertical, lines

 Written by Phil Inch for Game Developers Magazine (issue 4).
 Contributed to the public domain.

 This program written and compiled with Borland C++ v3.1
 Compatibility with other compilers is not guaranteed.

 Usage of this program is subject to the disclaimer printed
 in the magazine.  You assume all risks associated with the use
 of this program.

*/


#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <dos.h>
#include <mem.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

const float PI = 3.1415927;
char far *screen=MK_FP(0xA000,0);

int   INTCosArray[360], INTSinArray[360];

void	SetGraphicsMode( void ) {
	asm {
		mov	ax,0x13
    int	0x10
	  }
}

void	SetTextMode( void ) {
	asm {
  	mov	ax,0x03
    int	0x10;
    }
}

/* Fast horizontal line drawing program - from issue #2! */
void fast_horizontal_line( int x1, int x2, int y, unsigned char colour ) {
	char far *screen_location;
	int xcount;

  /* "Clip" the co-ordinates */
  if (x1<0) x1=0;
  if (x1>319) x1=319;
  if (x2<0) x2=0;
  if (x2>319) x2=319;

	screen_location = MK_FP( 0xA000, ((int)y*320) + (int)x1 );
	for ( xcount = x1; xcount <= x2; xcount++ ) {
		*screen_location = colour;
		screen_location++;
		}
}

/* Fast vertical line drawing program - from issue #2! */
void fast_vertical_line( int x, int y1, int y2, unsigned char colour ) {
	char far *screen_location;
	int ycount;

  /* "Clip" the co-ordinates */
  if (y1<0) y1=0;
  if (y1>199) y1=199;
  if (y2<0) y2=0;
  if (y2>199) y2=199;

	screen_location = MK_FP( 0xA000, (int)x + ((int)y1*320) );
	for ( ycount = y1; ycount <= y2; ycount++ ) {
		*screen_location = colour;
		screen_location += 320;
		}
}

/* Set up the integer cos and sin arrays */
void LoadINTCosSinArrays(void) {
  int a;
  float radians;

  for ( a = 0; a < 360; a++ ) {
      radians = (float)a * PI / 180;
      INTCosArray[a] = (int)(cos(radians) * 100);
      INTSinArray[a] = (int)(sin(radians) * 100);
      }
}

/* Filled circle drawing routine using HORIZONTAL lines */
void FillHorizCircDraw(int xc, int yc, int r, int color) {
  int x1, x2, y, s;

  for ( s = 90; s < 270; s++ ) {
      x1 = xc + ( ( r * INTCosArray[s] ) / 100 );
      x2 = xc - ( ( r * INTCosArray[s] ) / 100 );
      y = yc + ( ( r * INTSinArray[s] ) / 100 );
      fast_horizontal_line( x1, x2, y, color );
      }
}

/* Filled circle drawing routine using VERTICAL lines */
void FillVertCircDraw(int xc, int yc, int r, int color) {
  int x, y1, y2, s;

  for ( s = 0; s < 180; s++ ) {
      x = xc + ( ( r * INTCosArray[s] ) / 100 );
      y1 = yc - ( ( r * INTSinArray[s] ) / 100 );
      y2 = yc + ( ( r * INTSinArray[s] ) / 100 );
      fast_vertical_line( x, y1, y2, color );
      }
}

void main( void ) {
  char input[64];
  int xc,yc,r,c,d,number_of_circles;

  /* Set up the integer cos and sin arrays */
  LoadINTCosSinArrays();

	clrscr();

	printf( "*** FILLED CIRCLE DRAWING DEMO ***\n\n" );
	printf( "Suggestions for number of circles:\n\n" );
	printf( "486/50:  2000\n" );
	printf( "486/33:  1000\n" );
	printf( "486/25:   750\n" );
	printf( "386/40:   100\n" );
	printf( "386/33:   100\n" );
	printf( "lower :    50\n\n" );

	printf( "Enter number of circles to draw: " );
	gets( input );

	number_of_circles = atol(input);
	if ( number_of_circles <= 0 ) {
		printf( "That's not a valid number!" );
		exit(1);
		}

  SetGraphicsMode();

  gotoxy( 12, 12 ); printf( "Horizontal Lines" ); delay(3000);
  for ( d = 0; d < number_of_circles; d++ ) {
      xc = rand()%320;
      yc = rand()%200;
      r = rand()%50;
      c = rand()%255;
      FillHorizCircDraw(xc,yc,r,c);
      }

  delay(1000);

  SetGraphicsMode(); /* Quick way of clearing the graphics screen */

  gotoxy( 13, 12 ); printf( "Vertical Lines" ); delay(3000);
  for ( d = 0; d < number_of_circles; d++ ) {
      xc = rand()%320;
      yc = rand()%200;
      r = rand()%50;
      c = rand()%255;
      FillVertCircDraw(xc,yc,r,c);
      }

  delay(1000);

  SetTextMode();
}





