/*----------------------------------------------------------------------
 *			 TMS340 Graphics Library
 *       Copyright (c) 1988-1990 Texas Instruments Incorporated.
 *                         All Rights Reserved
 *----------------------------------------------------------------------
 * Demonstration Program
 *
 *   Use put_pixel function to draw fractal fern.  A pointillistic
 *   technique is employed to render the fern (the program draws a bunch
 *   of dots).	The fractal algorithm used is described in an article by
 *   M.F. Barnsley and A.C. Sloan entitled "A Better Way to Compress
 *   Images" (BYTE, Jan. 1988, pages 215-223.)  It turns out that this is
 *   not a better way to compress images, but it does draw a great fern.
 *----------------------------------------------------------------------
 * Revision History:
 *   09/02/88...Original version written...................J.R. Van Aken
 *   03/26/90...Modified for general portability...........J.R. Van Aken
 *----------------------------------------------------------------------
 */
#include <gsptypes.h>
#include "colors.h"

/* If MODE not defined at preprocessor command line, set to default. */
#ifndef  MODE
#define  MODE	  0	  /* default graphics mode */
#endif

#define M	  4	  /* no. of levels of detail in fern structure */
#define MAXRAND   32768.0   /* max. value returned by rand function */

static CONFIG cfg;

/* Fractal coefficients a, b, c, d, e, f and pk for M = 4 levels */
static double data[] = {
   .85, -.04, .04, .85, 1.6, 0, .85,
   .22, .23, -.26, .2, 1.6, 0, .07,
   .24, .26, .28, -.15, .44, 0, .07,
   .16, 0, 0, 0, 0, 0, .01,
};


main()
{
    double a[M+1], b[M+1], c[M+1], d[M+1], e[M+1], f[M+1], p[M+1];
    double *q, scale, pk, x, y, newx, newy;
    int hres, vres, i, j, k, n;
    unsigned long fcolor;

    /* Initialize graphics environment. */
    if (!set_config(MODE, 1))
	exit(1);		 /* invalid graphics mode number */
    clear_screen(-1);
    get_config(&cfg);
    hres = cfg.mode.disp_hres;	 /* horizontal resolution */
    vres = cfg.mode.disp_vres;	 /* vertical resolution */
    fcolor = get_nearest_color(0x00, 0xFF, 0x00, 0xFF);  /* green */
    set_draw_origin(0, vres/2);

    /* Copy a, b, c, d, e, f and p data for levels k = 1, 2, 3 and 4. */
    q = data;
    p[0] = 0;
    for (k = 1; k <= M; ++k) {
	a[k] = *q++;
	b[k] = *q++;
	c[k] = *q++;
	d[k] = *q++;
	e[k] = *q++;
	f[k] = *q++;
	p[k] = p[k-1] + *q++;
    }

    /* Each iteration of loop below draws a dot to the screen. */
    x = y = 0;
    scale = 0.092*hres;
    n = 10;
    for (;;) {
	/* Randomly select 1 of 4 levels of detail in fern structure. */
	pk = rand()/MAXRAND;
	if (pk <= p[1])
            k = 1;
	else if (pk <= p[2])
            k = 2;
	else if (pk <= p[3])
            k = 3;
        else
            k = 4;

	/* Rotate and translate x-y coordinates. */
	newx = a[k]*x + b[k]*y + e[k];
	newy = c[k]*x + d[k]*y + f[k];
        x = newx;
        y = newy;
	i = scale*x;
	j = scale*y;
	if (n)
	    n--;
	else
	    put_pixel(fcolor, i, -j);
    }
}

