home *** CD-ROM | disk | FTP | other *** search
- //
-
- //+----------------------------------------------------------------------+
-
- //+ Program STRANGE.CPP - By Fausto A. A. Barbuto, +
-
- //+ E-Mail: BJ06@C53000.PETROBRAS.ANRJ.BR, barbuto@ax.ibase.org.br +
-
- //+ and Michael E. Sargent, msargent@moose.uvm.edu +
-
- //+ +
-
- //+ Uses Michael E. Sargent's graphics functions and Robert Munafo's +
-
- //+ formulae for Period 1 (Main Cardiod) and Period 2 (Main Circle) +
-
- //+ detection. +
-
- //+ +
-
- //+ Plots strange Mandelbrot Sets with decomposed outer layers (similar +
-
- //+ to binary decomposition, but quite different at a first sight). +
-
- //+ Periods 1 & 2 are also decomposed in colourful levels. +
-
- //+ +
-
- //+ Press the '+' key at anytime to rotate palettes; any other key +
-
- //+ will fade the screen out. +
-
- //+----------------------------------------------------------------------+
-
- //
-
- #include <stdio.h>
-
- #include <stdlib.h>
-
- #include <conio.h>
-
- #include <math.h>
-
- #include <complex.h>
-
- #include <dos.h>
-
-
-
- int initvesa(void);
-
- void SetMode(int mode);
-
- void plot(int i, int j, int color);
-
- int selectmode(void);
-
- void floatscreen(int y1, int y2, int foreground, int shadow);
-
- void quit(void);
-
- void setVGAreg(int, int, int, int);
-
- void GetPalette(void);
-
- void cycle(void);
-
- void fade(void);
-
-
-
- union REGS reg;
-
- struct SREGS seg;
-
-
-
- int xres, yres, mode, colors, vesaflag, activebank, bankshift,
-
- locationshift, memoryblocks, (*winfuncptr)();
-
- unsigned int modetable[12];
-
- long int banksize, linetable[1024];
-
- char masktable[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
-
- char palette[256][3];
-
-
-
- void main()
-
- {
-
- double pmin=-2.25, pmax=0.75, qmin=-1.125, qmax=1.125;
-
- double ypy, x, y, p, q, p1, q1, ya, xkp1, ykp1, r;
-
- double deltap, deltaq, r1=8.9138e-3, r2=5.88e-2;
-
- double test1, test2, test3, test4;
-
- register int kk, k, np, nq, npy, ipen;
-
- unsigned long maxiter=512;
-
- int initc, iopt, mistake;
-
- complex c;
-
- char ch, choicekey;
-
-
-
- clrscr();
-
- _setcursortype(_NOCURSOR);
-
- printf("\n Program STRANGE\n");
-
- printf("\n By Fausto A. A. Barbuto, BJ06@C53000.PETROBRAS.ANRJ.BR");
-
- printf("\n barbuto@ax.ibase.org.br");
-
- printf("\n\n Graphics routines by Michael E. Sargent, ");
-
- printf("msargent@moose.uvm.edu");
-
- printf("\n\n INSTRUCTIONS: hit ESC to fade the screen out and quit;");
-
- printf("\n or press '+' to rotate palettes.");
-
- printf("\n\n\n Select an option:");
-
- printf("\n\n 1 - Study in Blue ");
-
- printf("\n 2 - Study in Red ");
-
- printf("\n 3 - Study in Green ");
-
- printf("\n 4 - Study in Gray ");
-
- printf("\n 5 - Graphite ");
-
- do
-
- {
-
- mistake = 0; // Reset the mistake flag
-
- choicekey = getch();
-
- iopt = ("%d", choicekey) - 48;
-
- if (iopt < 1 || iopt > 5) // Check for valid choices
-
- {
-
- printf("%c%c",0x07,0x07); // Sound some warning beeps
-
- mistake = 1;
-
- }
-
- } while (mistake !=0); // Repeat until valid selection
-
-
-
- textcolor(YELLOW + BLINK); // Indicate the choice
-
- gotoxy(2, iopt + 14);
-
- cprintf("%c", choicekey);
-
- textcolor(LIGHTGRAY);
-
- delay(1000);
-
-
-
- vesaflag = initvesa();
-
- if (selectmode()) quit();
-
-
-
- clrscr();
-
- printf("\n Wait a few seconds, please...");
-
- printf("\n Espere um pouco, por favor...");
-
- delay(950);
-
-
-
- SetMode(mode);
-
-
-
- initc = 28;
-
-
-
- if (iopt == 1)
-
- {
-
- for (kk=1;kk<64;kk++) setVGAreg(kk,0,0,kk);
-
- for (kk=64;kk<127;kk++) setVGAreg(kk,0,0,127-kk);
-
- }
-
- if (iopt == 2)
-
- {
-
- for (kk=1;kk<64;kk++) setVGAreg(kk,kk,0,0);
-
- for (kk=64;kk<127;kk++) setVGAreg(kk,127-kk,0,0);
-
- }
-
- if (iopt == 3)
-
- {
-
- for (kk=1;kk<64;kk++) setVGAreg(kk,0,kk,0);
-
- for (kk=64;kk<127;kk++) setVGAreg(kk,0,127-kk,0);
-
- }
-
- if (iopt == 4)
-
- {
-
- for (kk=1;kk<64;kk++) setVGAreg(kk,0,kk,kk);
-
- for (kk=64;kk<127;kk++) setVGAreg(kk,0,127-kk,127-kk);
-
- }
-
- if (iopt == 5)
-
- {
-
- for (kk=1;kk<64;kk++) setVGAreg(kk,0,kk,kk);
-
- for (kk=64;kk<127;kk++) setVGAreg(kk,0,127-kk,127-kk);
-
- initc = 14;
-
- }
-
- setVGAreg(127,0,0,32); // use attribute #127 for blue instead of #1
-
-
-
- ypy = (double)yres - 0.5;
-
- deltap = (pmax-pmin)/(xres-1);
-
- deltaq = (qmax-qmin)/(yres-1);
-
-
-
- if(qmin==-qmax)
-
- npy = yres/2;
-
- else
-
- npy = yres;
-
-
-
- for (np=0; np<=xres-1; np++) {
-
- p = pmin + (double)np*deltap;
-
- for (nq=0; nq<=npy-1; nq++) {
-
- q = qmin + (double)nq*deltaq;
-
- k = 0;
-
- x = 0.0;
-
- y = 0.0;
-
- c = complex(p,q);
-
- //
-
- //-------Checks limits for Period 1.
-
- //
-
- test1 = 2.0;
-
- if ((p >= -7.55e-1) && (p <= 4.0e-1)) {
-
- if (fabs(q) <= 6.6e-1)
-
- test1 = abs(1.0 - sqrt(1.0-4.0*c));
-
- }
-
- //
-
- //-------Checks limits for Period 2.
-
- //
-
- test2 = 2.0;
-
- if ((p >= -1.255e0) && (p <= -7.45e-1)) {
-
- if (fabs(q) <= 2.55e-1) test2 = 4.0*sqrt((p+1.0)*(p+1.0) + q*q);
-
- }
-
- //
-
- //-------Checks limits for Period Bud 3.
-
- //
-
- test3 = 2.0;
-
- if ((p >= -2.4e-1) && (p <= 0.0e0)) {
-
- if (fabs(q) <= 8.5e-1) {
-
- p1 = p + 1.2486e-1;
-
- q1 = fabs(q) - 7.4396e-1;
-
- test3 = p1*p1 + q1*q1;
-
- }
-
- }
-
- //
-
- //-------Checks limits for Period 4.
-
- //
-
- test4 = 2.0;
-
- if ((p >= -1.37e0) && (p <= -1.245e0)) {
-
- if (fabs(q) <= 6.1e-2) test4 = sqrt((p+1.309)*(p+1.309) + q*q);
-
- }
-
- //
-
- if((test1<=1.0) || (test2<=1.0) || (test3<=r1) || (test4<=r2)) {
-
- if (test3<=r1) ipen = 0;
-
- if (test4<=r2) ipen = 0;
-
- if (test1<=1.0) ipen = 42 - (int)(35.0*test1);
-
- if (test2<=1.0) ipen = 42 - (int)(31.0*test2);
-
-
-
- if (qmin == -qmax) {
-
- plot(np,nq,ipen);
-
- plot(np,(int)(yres-nq-1.0),ipen);
-
- }
-
- else
-
- plot(np,nq,ipen);
-
- }
-
- else {
-
- do {
-
- xkp1 = (x+y)*(x-y) + p;
-
- ya = x*y;
-
- ykp1 = ya + ya + q;
-
- asm {
-
- fld xkp1
-
- fld xkp1
-
- FMULP
-
- fld ykp1
-
- fld ykp1
-
- FMULP
-
- FADDP
-
- fstp r
-
- }
-
- k++;
-
- //
-
- // If R > M, points escape towards infinity.
-
- //
-
- if (r >= maxiter) {
-
- ipen = (int)(initc + 2.0*(log(xkp1*xkp1)-log(ykp1*ykp1)));
-
- if (ipen <= 4) ipen = 0;
-
- if (qmin == -qmax) {
-
- plot(np,nq,ipen);
-
- plot(np,(int)(yres-nq-1.0),ipen);
-
- }
-
- else
-
- plot(np,nq,ipen);
-
- }
-
- //
-
- // Points which do not belong to any period: Colour=0 (Black)
-
- //
-
- if (k == maxiter) {
-
- if (qmin == -qmax) {
-
- ypy = double(yres) - nq - 0.5;
-
- plot(np,(int)ypy,0);
-
- plot(np,nq,0);
-
- }
-
- else
-
- plot(np,nq,ipen);
-
- }
-
- //
-
- // Returns if no convergence is achieved on either escape or atraction.
-
- //
-
- x = xkp1;
-
- y = ykp1;
-
- } while (r <= maxiter && k<=maxiter);
-
- }
-
- }
-
- if(kbhit()) break;
-
- }
-
- ch = getch();
-
- if (ch == '+') { //* Rotate palettes *//
-
- GetPalette();
-
- cycle();
-
- }
-
- else fade();
-
- quit();
-
- }
-
- //===========================================================================
-
- // 1 - Initialize VESA for SVGA functions
-
- // Returns 1 if successful, or 0 if VESA BIOS not present.
-
- //===========================================================================
-
- int initvesa(void)
-
- {
-
- typedef struct
-
- {
-
- char vesasig[4];
-
- unsigned int version;
-
- char *oemstring;
-
- char capabilities[4];
-
- unsigned int *videomode;
-
- unsigned int memory;
-
- char reserved[242];
-
- } VESABLOCK;
-
- VESABLOCK vb;
-
- typedef struct
-
- {
-
- unsigned int attrib;
-
- char wina_attrib;
-
- char winb_attrib;
-
- unsigned int wingran;
-
- unsigned int winsize;
-
- unsigned int wina_seg;
-
- unsigned int winb_seg;
-
- int (*winfuncptr)();
-
- int moreints[3];
-
- char morechars[8];
-
- } VESAMODE;
-
- VESAMODE vm;
-
- int ratio, count=0, modenumber;
-
-
-
- reg.x.ax = 0x4F00;
-
- reg.x.di = FP_OFF((char *)&vb);
-
- seg.es = FP_SEG((char *)&vb);
-
- int86x(0x10,®,®,&seg);
-
- if (reg.x.ax != 0x004F) /* Returns 4FH if VESA present */
-
- {
-
- return(0);
-
- }
-
-
-
- memoryblocks = vb.memory; /* Size of video memory in 64K blocks */
-
- while (*vb.videomode != 0xFFFF) /* Make table of all supported modes */
-
- { /* using pointer to VESA BIOS list */
-
- modenumber = *vb.videomode;
-
- if (modenumber > 0x99 && modenumber < 0x10A)
-
- {
-
- modetable[count] = modenumber;
-
- count++;
-
- }
-
- (vb.videomode)++;
-
- }
-
- modetable[count] = 0xFFFF;
-
-
-
- reg.x.ax = 0x4f01;
-
- reg.x.cx = 0x101;
-
- seg.es = FP_SEG((char *)&vm);
-
- reg.x.di = FP_OFF((char *)&vm);
-
- int86x(0x10,®,®,&seg); /* Now get additional information */
-
-
-
- winfuncptr = vm.winfuncptr; /* Pointer to bank-switching function */
-
- banksize = (long)vm.winsize << 10; /* Get bank size in bytes */
-
- switch (banksize)
-
- { /* In case banks are < 64K */
-
- case 65536L:
-
- locationshift = 16;
-
- break;
-
- case 16384L:
-
- locationshift = 14;
-
- break;
-
- case 4096L:
-
- locationshift = 12;
-
- }
-
-
-
- ratio = vm.winsize / vm.wingran; /* Set shift factor if necessary */
-
- switch (ratio)
-
- {
-
- case 0x40:
-
- bankshift = 0x06;
-
- break;
-
- case 0x20:
-
- bankshift = 0x05;
-
- break;
-
- case 0x10:
-
- bankshift = 0x04;
-
- break;
-
- case 0x08:
-
- bankshift = 0x03;
-
- break;
-
- case 0x04:
-
- bankshift = 0x02;
-
- break;
-
- case 0x02:
-
- bankshift = 0x01;
-
- break;
-
- case 0x01:
-
- bankshift = 0x00;
-
- }
-
- return(1);
-
- }
-
- //===========================================================================
-
- // 2 - Set video mode; set linetable[] array
-
- //===========================================================================
-
- void SetMode(int mode)
-
- {
-
- int i;
-
-
-
- if (mode <= 0x13) /* VGA modes */
-
- reg.x.ax = mode;
-
- else
-
- {
-
- reg.x.ax = 0x4F02; /* VESA SVGA modes */
-
- reg.x.bx = mode;
-
- activebank = -1; /* For switching banks for plotting */
-
- }
-
- int86(0x10,®,®);
-
-
-
- colors = 256;
-
- switch(mode) /* Set the flags */
-
- {
-
- case 0x03:
-
- return;
-
- case 0x13:
-
- xres = 320;
-
- yres = 200;
-
- break;
-
- case 0x101:
-
- xres = 640;
-
- yres = 480;
-
- break;
-
- case 0x103:
-
- xres = 800;
-
- yres = 600;
-
- break;
-
- case 0x105:
-
- xres = 1024;
-
- yres = 768;
-
- break;
-
- case 0x107:
-
- xres = 1280;
-
- yres = 1024;
-
- }
-
-
-
- for (i=0;i<yres;i++)
-
- linetable[i] = (long)i * (long)xres;
-
- }
-
- //===========================================================================
-
- // 3 - Plot a point in 256-color modes
-
- //===========================================================================
-
- void plot(int i, int j, int color)
-
- {
-
- char far *address;
-
- long int location, offset;
-
- int bank;
-
-
-
- if (mode == 0x13) offset = linetable[j] + (long)i;
-
- else
-
- {
-
- location = linetable[j] + (long)i;
-
- bank = location >> locationshift;
-
- offset = location - ((long)bank << locationshift);
-
- if (bank != activebank)
-
- {
-
- activebank = bank;
-
- bank = bank << bankshift;
-
- asm mov dx,[bank];
-
- asm mov bx,0000h;
-
- asm call dword ptr [winfuncptr];
-
- }
-
- }
-
- address = (char far *)(0xA0000000L + offset);
-
- *address = color;
-
- }
-
- //===========================================================================
-
- // 4 - Choose 256-color video mode; check for support for chosen mode.
-
- // Returns 1 to signal quit request.
-
- //===========================================================================
-
- int selectmode(void)
-
- {
-
- char choicekey;
-
- int mistake, count;
-
-
-
- if (!vesaflag)
-
- {
-
- mode = 0x13;
-
- return(0);
-
- }
-
-
-
- SetMode(0x03);
-
- floatscreen(7,19,LIGHTBLUE,BLUE);
-
- do /* Select graphics mode */
-
- {
-
- mistake = 0;
-
- textcolor(BLUE);
-
- textbackground(LIGHTGRAY);
-
- _setcursortype(_NOCURSOR);
-
- gotoxy(13,7);
-
- cprintf(" ╔════════════════════════╡¥╞═════════════════════════╗ ");
-
- gotoxy(13,8);
-
- cprintf(" ║ SELECT GRAPHICS MODE: (Esc to quit program) ║ ");
-
- gotoxy(13,9);
-
- cprintf(" ╟────────────────────────────────────────────────────╢ ");
-
- gotoxy(13,10);
-
- cprintf(" ║ Make sure your monitor supports selected mode! ║ ");
-
- gotoxy(13,11);
-
- cprintf(" ╠════════════════════════════════════════════════════╣ ");
-
- gotoxy(13,12);
-
- cprintf(" ║ a: VGA 13H ( 320 x 200 x 256) ║ ");
-
- gotoxy(13,13);
-
- cprintf(" ║ b: SVGA VESA 101H ( 640 x 480 x 256) ║ ");
-
- gotoxy(13,14);
-
- cprintf(" ║ c: SVGA VESA 103H ( 800 x 600 x 256) ║ ");
-
- gotoxy(13,15);
-
- cprintf(" ║ d: SVGA VESA 105H (1024 x 768 x 256) ║ ");
-
- gotoxy(13,16);
-
- cprintf(" ║ e: SVGA VESA 107H (1280 x 1024 x 256) ║ ");
-
- gotoxy(13,17);
-
- cprintf(" ╟────────────────────────────────────────────────────╢ ");
-
- gotoxy(13,18);
-
- cprintf(" ║ ║ ");
-
- gotoxy(13,19);
-
- cprintf(" ╚════════════════════════════════════════════════════╝ ");
-
- do
-
- {
-
- mistake = 0; /* Reset the mistake flag */
-
- choicekey = getch();
-
- if (choicekey > 64 && choicekey < 70) choicekey += 32; /* Caps */
-
- if (choicekey==0x1B) return(1); /* Esc to quit */
-
- mode = ("%d", choicekey) - 96;
-
- if (mode < 1 || mode > 5) /* Check for valid choices */
-
- {
-
- printf("%c%c",0x07,0x07); /* Sound some warning beeps */
-
- mistake = 1;
-
- }
-
- }
-
- while (mistake !=0); /* Repeat until valid selection */
-
-
-
- textcolor(YELLOW + BLINK); /* Indicate the choice */
-
- gotoxy(21, mode + 11);
-
- cprintf("%c", choicekey);
-
- textcolor(BLUE);
-
- delay(1000);
-
- switch(mode) /* Set the actual flag */
-
- {
-
- case 1:
-
- mode = 0x13;
-
- break;
-
- case 2:
-
- mode = 0x101;
-
- break;
-
- case 3:
-
- mode = 0x103;
-
- break;
-
- case 4:
-
- mode = 0x105;
-
- break;
-
- case 5:
-
- mode = 0x107;
-
- }
-
-
-
- if (mode >= 0x100) /* Check for mode/memory support */
-
- {
-
- count = 0;
-
- while (modetable[count] != 0xFFFF)
-
- {
-
- if (modetable[count] == mode) break;
-
- count++;
-
- }
-
- if (modetable[count] == 0xFFFF) /* Won't get to FFFFH if supported */
-
- {
-
- gotoxy(21,18);
-
- cprintf("Mode %XH is not supported :-(", mode);
-
- delay(2000);
-
- mistake = 1;
-
- }
-
- if ((mode>0x100&&memoryblocks<8) || (mode==0x105&&memoryblocks<12) || (mode==0x107&&memoryblocks<20))
-
- {
-
- gotoxy(21,18);
-
- cprintf("Not enough video memory for mode %XH", mode);
-
- delay(2000);
-
- mistake = 1;
-
- }
-
- }
-
- }
-
- while (mistake !=0); /* Repeat until valid selection */
-
- textbackground(BLACK);
-
- return(0);
-
- }
-
- //===========================================================================
-
- // 5 - Display floating input screen with ASCII block texture
-
- //===========================================================================
-
- void floatscreen(int y1, int y2, int foreground, int shadow)
-
- {
-
- int step;
-
-
-
- textcolor(foreground);
-
- textbackground(BLACK);
-
- _setcursortype(_NOCURSOR);
-
- clrscr();
-
- for (step=1;step<26;step++)
-
- {
-
- gotoxy(2,step);
-
- cprintf("░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓");
-
- cprintf("▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░");
-
- }
-
- textcolor(shadow);
-
- for (step=y1+1;step<y2+1;step++)
-
- {
-
- gotoxy(69,step);
-
- cprintf("░░");
-
- }
-
- gotoxy(15,y2+1);
-
- cprintf("░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░");
-
- }
-
- //===========================================================================
-
- // Quit.
-
- //===========================================================================
-
- void quit(void)
-
- {
-
- SetMode(0x03);
-
- textcolor(LIGHTGRAY); /* Restore standard conditions */
-
- textbackground(BLACK);
-
- _setcursortype(_NORMALCURSOR);
-
- clrscr();
-
- exit(0);
-
- }
-
- //===========================================================================
-
- // 13 - Set individual palette register
-
- //===========================================================================
-
- void setVGAreg(int reg_no, int red, int green, int blue)
-
- {
-
- outportb(0x3c8, reg_no);
-
- outportb(0x3c9, red);
-
- outportb(0x3c9, green);
-
- outportb(0x3c9, blue);
-
- }
-
- //+======================+
-
- // Color-cycling routine +
-
- //+======================+
-
- void cycle(void)
-
- {
-
- int x=0, y, z;
-
-
-
- do
-
- {
-
- while ((inportb(0x3da) & 0x08)); // Wait for vertical retrace
-
- while (!(inportb(0x3da) & 0x08));
-
- for (z=1; z<127; z++)
-
- {
-
- y=z+x;
-
- if (y > 126)
-
- y -= 126;
-
- outportb(0x3C8, z);
-
- outportb(0x3C9, palette[y][0]);
-
- outportb(0x3C9, palette[y][1]);
-
- outportb(0x3C9, palette[y][2]);
-
- }
-
- x += 1;
-
- if (x==126)
-
- x=0;
-
- delay(100); //* Originally, delay(50) *//
-
- }
-
- while (kbhit() == 0);
-
- getch(); getch(); fade();
-
- }
-
- //+=================+
-
- // Fade-out routine +
-
- //==================+
-
- void fade(void)
-
- {
-
- int a, b, p1, p2, p3;
-
-
-
- for (a=0; a<64; a++)
-
- {
-
- while ((inportb(0x3da) & 0x08)); // Wait for vertical retrace
-
- while (!(inportb(0x3da) & 0x08));
-
- for (b=0; b<256; b++)
-
- {
-
- outportb(0x3C7, b);
-
- p1 = inportb(0x3C9);
-
- p2 = inportb(0x3C9);
-
- p3 = inportb(0x3C9);
-
- outportb (0x3C8, b);
-
- if (p1 > 0) outportb(0x3C9, p1 - 1);
-
- else outportb(0x3C9, 0);
-
- if (p2 > 0) outportb(0x3C9, p2 - 1);
-
- else outportb(0x3C9, 0);
-
- if (p3 > 0) outportb(0x3C9, p3 - 1);
-
- else outportb(0x3C9, 0);
-
- }
-
- delay(85);
-
- }
-
- }
-
- //+============================================+
-
- // Function to obtain current palette in array +
-
- //+============================================+
-
- void GetPalette(void)
-
- {
-
- int p, a, b;
-
-
-
- for (a=0; a<256; a++)
-
- {
-
- outportb(0x3C7, a);
-
- for (b=0; b<3; b++)
-
- {
-
- p = inportb(0x3C9);
-
- palette[a][b] = p;
-
- }
-
- }
-
- }
-
-