home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
NEWS
/
676
/
ORBWHIRL
/
ORBWHIRL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-07
|
12KB
|
356 lines
//ORBWHIRL v1.0 by Marc Coram, compiled with Turbo C
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <math.h>
#include <dos.h>
#include "svga256.h"
//A little annotation wouldn't kill me.
#define KCURVE -2. //Defaults set here
#define KPOINTS 100
#define KTLENGTH 8
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
#define TEXT 0
#define BIF 1
#define HIDDEN 2
#define UNMAP(x) ((double)(x)/(double)(size>>2)-2.) //changes a screencoord (int) to its literal position
#define MAP(x) (((x)+2.)*(size>>2)) //changes a literal position (double) to its screencoord
#define f(x) ((x)*(x)+CURVE) //the main iterative function
//I know... so I got a little out of control with defined macro functions
#define LEFTORRIGHT(); if (*destp>*xp) *dirp=RIGHT; else *dirp=LEFT;
#define UPORDOWN(); if (*destp>*yp) *dirp=DOWN; else *dirp=UP;
#define CLEARMAIN(); setviewport(0, 0, size, getmaxy(), 1);clearviewport();setviewport(0,0,getmaxx(),getmaxy(),1);
#define CLEARPANEL(); setviewport(size, 0, getmaxx(), getmaxy(), 1);clearviewport();setviewport(0,0,getmaxx(),getmaxy(),1);
#define FREEMEM(); if (direction!=NULL) {free(direction);free(xcoordinate);free(ycoordinate);free(destination);free(nextx);if (trailx!=NULL) {farfree(trailx);farfree(traily);trailx=NULL;}} direction=NULL;
int huge svgasetmode4(){return SVGA1024x768;}
int huge svgasetmode3(){return SVGA800x600;}
int huge svgasetmode2(){return SVGA640x480;}
int huge svgasetmode1(){return SVGA640x400;}
int huge svgasetmode0(){return VGA320x200;}
int huge (*svgamodep)();
void main(int argc,char *argv[])
{
unsigned char far *direction, far *dirp;
int far *xcoordinate, far *xp;
int far *ycoordinate, far *yp;
int far *destination, far *destp;
double far *nextx, far *nxp;
int huge *trailx=NULL, huge *tx, huge *txmax;
int huge *traily, huge *ty;
int size;
int i,c=1;
double x,dx;
double CURVE=KCURVE;
int POINTS=KPOINTS;
int TLENGTH=KTLENGTH;
int arg=0;
int shift=0;
int panel=TEXT;
int obif=-1;
//Setup Video
int gdriver, gmode, errorcode;
svgamodep=svgasetmode0;
if (argc>=2) switch(argv[1][0]) {
case 'A': case 'a': argc--;arg++;break; //Choose Video
case 'B': case 'b': svgamodep=svgasetmode1;argc--;arg++;break;
case 'C': case 'c': svgamodep=svgasetmode2;argc--;arg++;break;
case 'D': case 'd': svgamodep=svgasetmode3;argc--;arg++;break;
case 'E': case 'e': svgamodep=svgasetmode4;argc--;arg++;break;
}
//Load command line arguments
if (argc>4) {printf("\nInvalid command line\n");getch();goto exit;}
if (argc>=2) CURVE=atof(argv[1+arg]);
if (argc>=3) POINTS=atoi(argv[2+arg]);
if (argc==4) TLENGTH=atoi(argv[3+arg]);
reinstall:
installuserdriver("svga256",*svgamodep);
gdriver=DETECT;
initgraph(&gdriver, &gmode, "");
errorcode = graphresult();
if (errorcode != grOk)
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
goto exit;
}
size=(getmaxy()>>2)<<2;
redraw:
{//Set the palette
double c,region,dc,top,pointct;
if (TLENGTH==0) pointct=253;else pointct=POINTS;
setrgbpalette(254,210,210,210);
setrgbpalette(255,255,255,255);
setcolor(255);
settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy((int)(getmaxx()>>1),size>>1,"Setting Palette");
region=(pointct+1)/6.;if ((int)region) dc=63./(int)region;else dc=63.;top=region;
for (i=1,c=0;i<top; i++,c+=dc) setrgbpalette(i,63 ,0 ,c );top+=region;
for ( ;i<top; i++,c-=dc) setrgbpalette(i,c ,0 ,63 );top+=region;
for ( c=0;i<top; i++,c+=dc) setrgbpalette(i,0 ,c ,63 );top+=region;
for ( ;i<top; i++,c-=dc) setrgbpalette(i,0 ,63 ,c );top+=region;
for ( c=0;i<top; i++,c+=dc) setrgbpalette(i,c ,63 ,0 );top+=region;
for ( ;i<=pointct;i++,c-=dc) setrgbpalette(i,63 ,c ,0 );
cleardevice();
}
reinit:
//farmalloc room
direction=malloc(POINTS*sizeof(unsigned char));
xcoordinate=malloc(POINTS*sizeof(int));
ycoordinate=malloc(POINTS*sizeof(int));
destination=malloc(POINTS*sizeof(int));
nextx=malloc(POINTS*sizeof(double));
if (TLENGTH) {
trailx=farmalloc((long)POINTS*TLENGTH*sizeof(int));
traily=farmalloc((long)POINTS*TLENGTH*sizeof(int));
}
if ((xcoordinate==NULL)||(ycoordinate==NULL)||(destination==NULL)||(nextx==NULL)||(TLENGTH&&((trailx==NULL)||(traily==NULL))))
{closegraph();printf("\nMemory error: try reducing POINTS or TLENGTH\n");getch();goto exit;}
//set-up initial position
x=-(1+sqrt(1.-4.*CURVE))/2;
dx=-2.*x/(POINTS+1);x+=dx;
dirp=direction;xp=xcoordinate;yp=ycoordinate;destp=destination;nxp=nextx;
for (i=0;i<POINTS;i++,dirp++,xp++,yp++,destp++,nxp++,x+=dx) {
*xp=MAP(x); *yp=-1;
*nxp=f(x);
*destp=size-MAP(*nxp);
UPORDOWN();
}
/*Init trails: the pointer method I use is rather memory hungry,
but its fast and, most of the time, for me anyway, the memory
hasn't been a problem.*/
if (TLENGTH) {
txmax=trailx+(long)POINTS*TLENGTH-1;
for (tx=trailx,ty=traily;tx<=txmax;tx=tx+1,ty=tx+1) {*tx=-1;*ty=-1;}
tx=trailx;ty=traily;
}
replot:
setwritemode(COPY_PUT);
//DRAW LINES
setcolor(254);
line(0,size>>1,size,size>>1);
line(size>>1,0,size>>1,size);
line(0,size,size,0);
//DRAW PARABOLA
setcolor(255);
i=0;
moveto(i,size-MAP(f(UNMAP(i))));
for (;i<size;i++)
lineto(i,size-MAP(f(UNMAP(i))));
repanel:
setwritemode(COPY_PUT);
//clear off the old panel
if (!(panel==BIF&&obif!=-1)) {CLEARPANEL();}
if (panel==TEXT) { //Draw the TEXT panel
unsigned char tstr[30];int col;
col=size+6;
settextjustify(LEFT_TEXT, CENTER_TEXT);
setcolor(254);
sprintf(tstr,"CURVE=%f",CURVE);outtextxy(col,(size>>1)-12,tstr);
sprintf(tstr,"POINTS=%i",POINTS);outtextxy(col,(size>>1),tstr);
sprintf(tstr,"TLENGTH=%i",TLENGTH);outtextxy(col,(size>>1)+12,tstr);
setcolor(255);
outtextxy(col,(size>>1)-94,"UP and DOWN");
outtextxy(col,(size>>1)-82," CURVE");
outtextxy(col,(size>>1)-66,"PGUP and PGDN");
outtextxy(col,(size>>1)-54," POINTS");
outtextxy(col,(size>>1)-38,"HOME and END");
outtextxy(col,(size>>1)-26," TLENGTH");
outtextxy(col,(size>>1)+26,"B=Bifurcation");
outtextxy(col,(size>>1)+40,"H=Hide Text");
outtextxy(col,(size>>1)+53,"T,S=Show Text");
outtextxy(col,(size>>1)+67,"C=Clear Trails");
outtextxy(col,(size>>1)+80,"P=Palette fix");
outtextxy(col,(size>>1)+94,"ALT-[A-E] VID");
}
if (panel==BIF) { // Bifurcation Panel
int maxx, y=12, wx, cx;
double x, c=0, dc, mx;
unsigned char tstr[30];
setcolor(254);
settextjustify(LEFT_TEXT, TOP_TEXT);
setviewport(size, 0, getmaxx(), 11, 1);clearviewport();setviewport(0,0,getmaxx(),getmaxy(),1);
sprintf(tstr,"CURVE=%f",CURVE);outtextxy(size+6,0,tstr);
if (obif==-1) {
maxx=getmaxx();wx=maxx-size-1;cx=size+(wx>>1)+1;mx=(double)wx/4;
dc=-1./(double)((size-12)>>1);
while (y<size) {
for (i=1,x=0;i<=253;i++) {x=x*x+c;putpixel(cx+x*mx,y,i);}
for (i=1;i<=8;i++) {x=x*x+c;putpixel(cx+x*mx,y,255);}
y++;c+=dc;
}
}
setwritemode(XOR_PUT);
setcolor(255);
if (obif!=-1) line(size+1,obif,maxx,obif);//erase old line if applicable
obif=12-CURVE*((size-12)>>1);
line(size,obif,maxx,obif); //plot new line
setwritemode(COPY_PUT);
}
cont:
if (TLENGTH) setwritemode(XOR_PUT);
while (!kbhit()) { //MAIN LOOP
dirp=direction;xp=xcoordinate;yp=ycoordinate;destp=destination;nxp=nextx;
for (i=0;i<POINTS;dirp++,xp++,yp++,destp++,nxp++) {//cycle through the points
switch(*dirp) {
case UP:
(*yp)--; //go up
if (*yp<=*destp) { //if we've reached our destination
*destp=MAP(*nxp); //set our new destination
LEFTORRIGHT(); //and figure out how to get there
}
break;
case DOWN:
(*yp)++;
if (*yp>=*destp) {
*destp=MAP(*nxp);
LEFTORRIGHT();
}
break;
case LEFT:
(*xp)--;
if (*xp<=*destp) {
*nxp=f(*nxp);
*destp=size-MAP(*nxp);
UPORDOWN();
}
break;
case RIGHT:
(*xp)++;
if (*xp>=*destp) {
*nxp=f(*nxp);
*destp=size-MAP(*nxp);
UPORDOWN();
}
break;
}
if (TLENGTH) {
putpixel(*xp,*yp,++i);
putpixel(*tx,*ty,i);
*tx=*xp;tx=tx+1;*ty=*yp;ty=ty+1;if (tx>txmax) {tx=trailx;ty=traily;}
}
else {
putpixel(*xp,*yp,(c+i)%253+1);i++;
}
}
if (++c>253) c=1;
}
skip:
shift=*(unsigned char far *) 0x00000417L;//Access the keyboard shifts
i=getch();
if (i==0) i=getch()+256;
switch(i) {
case 27: goto exit;
case 30+256: FREEMEM();obif=-1; cleardevice(); svgamodep=svgasetmode0;goto reinstall;//Alt- [A-E]
case 48+256: FREEMEM();obif=-1; cleardevice(); svgamodep=svgasetmode1;goto reinstall;
case 46+256: FREEMEM();obif=-1; cleardevice(); svgamodep=svgasetmode2;goto reinstall;
case 32+256: FREEMEM();obif=-1; cleardevice(); svgamodep=svgasetmode3;goto reinstall;
case 18+256: FREEMEM();obif=-1; cleardevice(); svgamodep=svgasetmode4;goto reinstall;
case '8': case 72+256: case 141+256:
if (shift&4) CURVE+=.001; else if (shift&3) CURVE+=.01; else CURVE+=.1;
if (CURVE>0) CURVE=0;
break;
case '2': case 80+256: case 145+256:
if (shift&4) CURVE-=.001; else if (shift&3) CURVE-=.01; else CURVE-=.1;
if (CURVE<-2.) CURVE=-2.;
break;
case '9': case 73+256: case 132+256:
if (shift&7) POINTS+=1; else POINTS+=10;
if (POINTS>253) POINTS=253;
break;
case '3': case 81+256: case 118+256:
if (shift&7) POINTS-=1; else POINTS-=10;
if (POINTS<1) POINTS=1;
break;
case '7': case 71+256: case 119+256:
if (shift&7) TLENGTH+=1; else TLENGTH+=10;
if (TLENGTH>253) TLENGTH=253;
break;
case '1': case 79+256: case 117+256:
if (shift&7) TLENGTH-=1; else TLENGTH-=10;
if (TLENGTH<0) TLENGTH=0;
break;
case 'p': case 'P': obif=-1;cleardevice();
FREEMEM();
goto redraw;
case 't': case 'T': case 's': case 'S': panel=TEXT; goto repanel;
case 'b': case 'B': obif=-1; panel=BIF; goto repanel;
case 'h': case 'H': panel=HIDDEN;goto repanel;
case 'c': case 'C':
if (TLENGTH==0) {
CLEARMAIN();
goto replot;
}
default: goto cont;
}
FREEMEM();
if (kbhit()) goto skip;
CLEARMAIN();
goto reinit;
exit:
closegraph();
printf("\
\n\
\t\t --==≡≡ O R B I T W H I R L ≡≡==--\n\
\tFreeWare by Marc Coram (thanks to Jordan Hargrave for SVGA256.BGI)\n\
--Based on the orbits of the Mandelbrot Set for real numbers (VGA REQUIRED)--\n\
\n\
Syntax: ORBWHIRL [VIDMODE ][CURVE [POINTS [TLENGTH]]]\n\
\tVIDMODE is a letter A-E which selects your video mode.\n\
\t\tA=320x200 B=640x400 C=640x480 D=800x600 E=1024x768\n\
\tCURVE is a floating point number between -2 and 0 It signifies C\n\
\t\tin the iterative formula nx=x*x+C, whose graph is the parabola.\n\
\t\tAs CURVE approaches 0, the parabola raises and the pattern\n\
\t\tbecomes regular. As CURVE approaches -2, the curve drops and\n\
\t\tthe pattern becomes chaotic.\n\
\tPOINTS is an integer which signifies how many individual tracing\n\
\t\tswirls will be produced ( <=253 ). Lower POINTS for speed.\n\
\tTLENGTH is an integer which signifies the length of the tracing swirls.\n\
\t\tIf zero, the trails will not clear.\n\
\n\
Default: \"ORBWHIRL A -2 100 8\"\n\
Also try: \"ORBWHIRL -1.4 25 1000\" OR \"ORBWHIRL -.72\" OR \"ORBWHIRL -1.7 60 50\"\n\
\t \"ORBWHIRL B -2 253 0\" OR \"ORBWHIRL D\" OR \"ORBWHIRL -1.75 2 0\"\n\
\n\
ENJOY!\tComments/Improvements(/Donations?) appreciated:\n\
\tMarc Coram / 15570 Knochaven Rd / Santa Clarita, CA 91350-2799\
");
}