mandint.c

//============================
// MANDINT.C -- Mandelbrot set program
//============================
#include "mandint.h"
#include "keydefs.h"
#include "initgr.h"

#include <graphics.h>
#include <complex.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <values.h>

int maxit,Xctr,Yctr;
double asp,dx,dy,xmin,ymin,xmax,ymax;

main() {
int output,ret,flag=1;
float scale=0;
double cr,ci;
char ch;

clrscr();
puts("\n-- * MANDELBROT SET GENERATOR * --\n");
window(15,8,66,12);
cputs("\nMaximum Iteration: "); cscanf("%d",&maxit);
cputs("\nScale (Range: 1-10): ");
do {
gotoxy(22,3); clreol();
scale=get_float();
if(scale>=1.0 && scale<=6.0) flag=0;
} while(flag);
cputs("\n(J)ulia set or (M)andelbrot set: ");
ch=getans('j','m');
if(ch=='j') {
cputs("\r\nC real: "); cr=get_float();
cputs("\nC imaginary: "); ci=get_float();
}
textcolor(WHITE);
setmode(0x13);
initPal();
asp=getAspect(maxX,maxY);
mx/=scale; my/=scale;
mx*=asp;
Xctr=(maxX>>1); Yctr=(maxY>>1);

switch(ch) {
case 'j':
ret=juliaint(complex(cr,ci));
break;
case 'm':
ret=mandint();
break;
default:
error(-3,"Incorrect character.");
}
beep();
if(!ret) getch();
rotatePal();
beep();
// setmode(0x03);
return(0);
} /* END MAIN */

int mandint() {
int col,j,k,colour,flag,old_colour,Xoffset,Yoffset;
double cr,ci,jmax,x,y,xsq,ysq,distsq,xold,yold,delta;

xmin=-2.0; xmax=0.8; ymin=-1.3; ymax=1.3;
Xoffset=Xctr-(mx>>1);
Yoffset=Yctr-(my>>1);
dx=(xmax-xmin)/(mx-1);
dy=(ymax-ymin)/(my-1);
jmax=(my>>1);
delta=((dx < dy ? dx : dy) / 2.0);
for(j=0; j<=jmax; j++) {
for(k=0; k<=mx; k++) {
x=cr=xmin+k*dx;
y=ci=ymin+j*dy;
xsq=ysq=0.0;
colour=0;
xold=yold=0.0;

if(kbhit())
if(getch()==ESC)
return(1);

while((colour < maxit) && (xsq+ysq < 4.0)) {
xsq=x*x; ysq=y*y;
y=2*x*y+ci;
x=xsq-ysq+cr;
if(old_colour == maxit)
{
if((colour & 15) == 0)
{
xold=x;
yold=y;
} else
if((fabs(xold-x)+fabs(yold-y)
< delta))
colour=maxit-1;
}
colour++;
}
if(colour < maxit)
col=colour%255;
else
col=(((int)((xsq+ysq)*255)%255)+1);
plot(Xoffset+k,Yoffset+j,col);
plot(Xoffset+k,maxY-(Yoffset+j),col);
old_colour=colour;
}
}
return(0);
}

int juliaint(complex c) {
int col,j,k,maxj,xs,ys,tlx,tly,brx,bry;
complex z;
RET r;

xmin=-1.5; xmax=1.5; ymin=-1.5; ymax=1.5;
dx=(xmax-xmin)/mx; dy=(ymax-ymin)/my;
tlx=Xctr-(mx>>1); tly=Yctr-(my>>1);
brx=tlx+mx; bry=tly+my;
maxj=(my>>1);

for(j=0; j<=maxj; j++) {
for(k=0; k<=mx; k++) {
z=complex(xmin+k*dx,ymin+j*dy);
if(kbhit())
if(getch()==ESC)
return(1);
r=julia(z,c,maxit);
if(norm(r.comp) > 4.0)
r.col=r.col%255;
else
r.col=((((int)norm(r.comp)*255)%255)+1);
plot(tlx+k,tly+j,r.col);
plot(brx-k,bry-j,r.col);
r.old_colour=r.col;
}
}
return(0);
}

RET julia(complex z,complex c,int maxit) {
complex oldz;
double delta;
RET r;

delta=((dx < dy ? dx : dy) / 2.0);
r.col=0;
while((r.col < maxit) && (norm(z) < 4.0)) {
z=z*z+c;
if(r.old_colour == maxit) {
if((r.col % 2) == 0)
oldz=z;
else
if(abs(oldz-z)+abs(oldz-z) < delta)
break;
}
r.col++;
}
r.comp=z;
return(r);
}

void beep() {
sound(800);
delay(100);
nosound();
}

void initPal(void) {
int index;

Pal_Array[0][0]=0;
Pal_Array[0][1]=0;
Pal_Array[0][2]=0;
for(index=1; index<256; index++) {
Pal_Array[index][0]=index;
Pal_Array[index][1]=1;
Pal_Array[index][2]=index;
}
setVGApalette(Pal_Array[0]);
}

void rotatePal() {
int i,j,k,old_red,old_blue,old_green,new_red,new_blue,new_green,
last_step=32;
char ch;

for(;;) {
old_red=Pal_Array[255][0];
old_green=Pal_Array[255][1];
old_blue=Pal_Array[255][2];
new_red=rand()%63;
new_green=rand()%63;
new_blue=rand()%63;
for(j=1; j<last_step; j++) {
outportb(0x3C8,0);
for(i=1; i<255; i++) {
Pal_Array[i][0] = Pal_Array[i+1][0];
Pal_Array[i][1] = Pal_Array[i+1][1];
Pal_Array[i][2] = Pal_Array[i+1][2];
}
Pal_Array[255][0] = old_red+
((new_red-old_red)*j)/last_step;
Pal_Array[255][1] = old_green+
((new_green-old_green)*j)/last_step;
Pal_Array[255][2] = old_blue+
((new_blue-old_blue)*j)/last_step;
outportb(0x3C8,0);
if(kbhit()) {
ch=getch();
if(ch==ESC)
return;
else if((ch-'0'<=9) && (ch-'0'>0))
last_step=4*(int)(ch-'0');
getch();
}
for(k=0; k<256; k++) {
if(k%126 == 0) {
while((inportb(0x3DA) & 0x08)!=0);
while((inportb(0x3DA) & 0x08)==0);
}
outportb(0x3C9,Pal_Array[k][0]);
outportb(0x3C9,Pal_Array[k][1]);
outportb(0x3C9,Pal_Array[k][2]);
}
}
}
}

void setVGApalette(unsigned char *buffer) {
union REGS r;
struct SREGS inreg;

r.x.ax=0x1012;
segread(&inreg);
inreg.es=inreg.ds;
r.x.bx=0;
r.x.cx=256;
r.x.dx=(int)&buffer[0];
int86x(0x10,&r,&r,&inreg);
}

void plot(int x,int y,int color) {
unsigned int offset;
char far *address;

offset=320*y+x;
address=(char far *)(0xA0000000L+offset);
*address=color;
}

void setmode(int mode) {
union REGS r;

r.h.ah=0;
r.h.al=mode;
int86(0x10,&r,&r);
}

int readpixel(int x,int y) {
union REGS r;

r.h.ah=0x0D;
r.x.cx=x;
r.x.dx=y;
int86(0x10,&r,&r);
return(r.h.al);
}

void prnscr(int xlo,int xhi,int ylo,int yhi) {
int n1,n2,ncols,i,X,Y,val,lit,xasp,yasp;

xhi=xhi*1.4+1; yhi=(yhi/2.05)*1.4+1;
prchar(27); prchar('A'); prchar(7);
ncols=xhi-xlo+1;
n1=ncols%256; n2=ncols/256;
for(i=ylo; i<=yhi; i+=7) {
if(kbhit()) exit(-1);
prchar(27); prchar('L'); prchar(n1); prchar(n2);
for(X=xlo; X<=xhi; X++) {
val=0;
for(Y=i; Y<i+7; Y++) {
val<<=1;
lit=fmod((float)readpixel(X/1.4,(Y*2.05)/1.4),2.0);
val|=(Y>yhi) ? 0 : lit;
}
prchar(val);
}
prchar('\n');
}
prchar(27); prchar('@');
}

void prchar(char ch) {
union REGS regs;

regs.x.dx=0;
regs.h.ah=0;
regs.h.al=ch;
int86(0x17,&regs,&regs);
}

float getAspect(int pixX,int pixY) {
float height=7.25,length=10.25,x,y;

x=(float)length/pixX;
y=(float)height/pixY;
return(x/y);
}

char getans(char a,char b) {
union REGS out,in;
int flag=1;

while(flag) {
in.h.ah=0x08;
intdos(&in,&out);
if(out.h.al==a || out.h.al==b)
break;
}
return(out.h.al);
}

float get_float() {
int n[20],i=0,j,pointcnt=0,pointflag=0,ans1=0,ans2=0,bad=0,minusflag;
int flag=1;
char c;
long t;
float a,b,ret;

do {
if(i!=0 && bad==0)
put_char(c);
bad=0;

if(i==19)
goto label1;
switch(c=get_char()) {
case '0': n[i]=0; i++; continue;
case '1': n[i]=1; i++; continue;
case '2': n[i]=2; i++; continue;
case '3': n[i]=3; i++; continue;
case '4': n[i]=4; i++; continue;
case '5': n[i]=5; i++; continue;
case '6': n[i]=6; i++; continue;
case '7': n[i]=7; i++; continue;
case '8': n[i]=8; i++; continue;
case '9': n[i]=9; i++; continue;
case '-':
if(i>0) continue;
n[i]='-';
i++;
continue;
case '.':
if(pointflag>0) continue;
pointflag++;
n[i]='.'; i++;
continue;
case '\r':
if(i==0) continue;
n[i]='\r';
putch('\r');
i++;
break;
default:
bad=1;
continue;
}
flag=0;
} while(flag);
label1:
pointcnt=pointflag=0; flag=1;
minusflag=(n[0] == '-') ? 1 : 0;
i=(minusflag) ? 1 : 0;
while(flag) {
switch(n[i]) {
case '.': // DECIMAL POINT
pointflag=1;
i++;
continue;
case '\r': // ENTER
flag=0;
continue;
default: // NUMBER 1 - 9
switch(pointflag) {
case 0:
if(add(ans1,n[i]))
pointflag=1;
i++;
break;
case 1:
if(add(ans2,n[i])) {
flag=0;
i++;
break;
}
pointcnt++; // Number of decimal places
i++;
break;
}
continue;
}
i++;
}
if(pointcnt > 32767)
error(-2,"Number out of range: get_float().");
t=1;
for(j=0; j<pointcnt; j++)
t*=10;
ret=(float)ans1+((float)ans2/(float)t);
if(minusflag && pointflag)
ret*=-1;
return(ret);
}

int add(int &a,int n) {
if(a>10000)
return(1);
a*=10;
a+=n;
return(0);
}

void error(int err,char *s) {
setmode(3);
printf("INPUT ERROR (%d): %s",err,s);
puts("\r\n\nMANDINT 1.0 -- (c) 1993 Adam King.");
exit(err);
}

void put_char(char c) {
union REGS r;
int att;

r.h.ah=0xA; // Request display
r.h.al=c; // Character
r.h.bh=0; // Page
r.x.cx=1; // Repititions
int86(0x10,&r,&r); // Call BIOS
r.h.ah=0x03;
r.h.bh=0;
int86(0x10,&r,&r); // Read cursor position
r.h.ah=2;
r.h.al=0;
r.h.dl++;
int86(0x10,&r,&r);
}

char get_char() {
union REGS r;

r.h.ah=0x08;
intdos(&r,&r);
return(r.h.al);
}

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.