home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / fr386.zip / FR386.C next >
C/C++ Source or Header  |  1988-05-20  |  8KB  |  183 lines

  1.  
  2. /* fr386 -- 386-specific, fixed pt. mandelbrot generator for EGA or Herc */
  3. /* graphics ... this is working but not very pretty version ... */
  4.  
  5. int       switchpt, xhi, xlo, yhi, ylo, i, itermax, mcol, mrow, andit;  
  6. double    xmin, xmax, ymin, ymax, newdy, newdx, dx, dy, fabs(); 
  7. char      key;
  8. void      (*gm)(),(*tm)(),(*pt)(); /* pointers to funtions that turn on */
  9.           /* graphics mode, turn on text mode, and plot a pt */
  10. void      egapt(), hplotpt(), tmode(), gmode(), egatext(), mode16();
  11. int       its_ega(), is_ega(), is_herc(), mandel();
  12.  
  13. main()
  14. {
  15. if(!is_386()) puts("SORRY! Need Intel 386!\n"), exit(0);
  16.  
  17. if(is_herc()){
  18.      mcol = 720, mrow = 348, andit = 1;
  19.      pt = hplotpt, gm = gmode, tm = tmode;
  20.      }
  21. else if(is_ega() || its_ega()){
  22.      mcol = 640, mrow = 350, andit = 15;
  23.      pt = egapt, gm = mode16, tm = egatext;
  24.      }
  25. else {
  26.      puts("Did not detect EGA/VGA. Do you wish to try EGA/VGA anyway?\n");
  27.      puts("(detection scheme is not foolproof)\n\ny = YES, try EGA/VGA\n\n");
  28.      if(scr_ci()=='y'){
  29.           mcol = 640, mrow = 350, andit = 15;
  30.           pt = egapt, gm = mode16, tm = egatext;
  31.           }
  32.      else puts("SORRY! Need EGA 16 color or Hercules Graphics!\n"), exit(0);
  33.      }
  34.  
  35. puts("Need instructions? (y=yes)\n"), key = scr_ci();
  36. if(key=='y' || key=='Y'){
  37.      puts("80386 fixed pt Mandel zoom program.\n\n");
  38.      puts("Uses 386 32-bit instructions in real mode to simulate 1 megaflop\n");
  39.      puts("performance WITHOUT math coprocessor. To get 1st mandel screen, you\n");
  40.      puts("can use defaults or enter values from keyboard. After 1st screen is\n");
  41.      puts("drawn, hit a key to show box cursor. Hit 'q' to quit program. Move\n");
  42.      puts("box with cursor keys; shift with cursor keys moves box fast. Use PGUP,\n");
  43.      puts("PGDN, Home and End to alter box size and shape. Then hit <CR> (Enter)\n");
  44.      puts("to expand region in box to full screen. At low magnifications, a\n");
  45.      puts("switchpt of 30-40 removes some of the muddle in rapidly changing parts\n");
  46.      puts("of the image; for high magnifications use a switchpt > 70 to prevent\n");
  47.      puts("loss of detail.  GOOD LUCK!  H.W. Stockman...\n");
  48.      }
  49.  
  50. puts("Use defaults for first screen? (y=yes)\n"), key = scr_ci();
  51. if(key=='y' || key=='Y'){
  52.      xmin=-2.0, xmax=0.5, ymin=-1.25, ymax=1.25;
  53.      itermax=200, switchpt=40;  /* bug in DeSmet requires < 4 comma phrases */
  54.      puts("xmin= -2.0, xmax= 0.5\nymin= -1.25, ymax= 1.25\niter=200, switchpt=40\n");
  55.      puts("hit a key to draw 1st screen..."), scr_ci();
  56.      }
  57. else do   {
  58.           puts("ENTER xmin: "), scanf("%lf",&xmin);
  59.           puts("ENTER xmax: "), scanf("%lf",&xmax);
  60.           puts("ENTER ymin: "), scanf("%lf",&ymin);
  61.           puts("ENTER ymax: "), scanf("%lf",&ymax);
  62.           puts("ENTER switchpt (iteration to start log scale): "), 
  63.                scanf("%d",&switchpt);
  64.           puts("ENTER # iterations: "), scanf("%d",&itermax);
  65.           if(itermax < 50) itermax = 50;
  66.           if(itermax > 1000) itermax = 1000;
  67.           puts("ALL OK ? \n"), key = scr_ci();
  68.           if(xmax-xmin < 0.00001) key = 'n', puts("xmax-xmin too small or < 0\n");
  69.           if(ymax-ymin < 0.00001) key = 'n', puts("ymax-ymin too small or < 0\n");
  70.           if(fabs(xmin)>4.0 || fabs(xmax)>4.0 || fabs(ymax)>4.0 || fabs(ymin)>4.0)
  71.                key = 'n', puts("absolute vals of x's and y's must be < 4.0\n");
  72.           } while(key != 'y' && key != 'Y');
  73.  
  74. (*gm)();       /* TURN ON GRAPHICS MODE */
  75.  
  76. if('q'==mandel(xmin,xmax,ymin,ymax,switchpt,itermax,mcol,mrow,pt,andit)) 
  77.      (*tm)(), exit(0);
  78.  
  79. /* INITIALIZE CO-ORDS OF BOX CURSOR CORNERS */
  80. xlo = 90, xhi = 130, ylo = 90, yhi = 110;
  81.  
  82. /* DO-WHILE LOOP TO MOVE BOX CURSOR ABOUT SCREEN */
  83.  
  84. do   {
  85.      key = scr_ci();
  86.      /* DRAW INITIAL XOR BOX */
  87.      for(i=xlo; i<=xhi; ++i) (*pt)(i,ylo,-1), (*pt)(i,yhi,-1);
  88.      for(i=ylo+1;i<yhi; ++i) (*pt)(xlo,i,-1), (*pt)(xhi,i,-1);
  89.      /* ALLOW BOX TO BE REPOSITIONED AND ALTERED IN SHAPE, SIZE */
  90.      do   {
  91.           for(i=xlo; i<=xhi; ++i) (*pt)(i,ylo,-1), (*pt)(i,yhi,-1);
  92.           for(i=ylo+1; i<yhi; ++i) (*pt)(xlo,i,-1), (*pt)(xhi,i,-1);
  93.           if(key=='\034' && xhi<mcol-1) xhi++, xlo++;        /* RIGHT AND LEFT */
  94.           else if(key=='\035' && xlo>0) xhi--, xlo--;        /* CURSOR KEYS... */
  95.           else if(key=='\036' && ylo>0) yhi--, ylo--;        /* UP AND DOWN    */
  96.           else if(key=='\037' && yhi<mrow-1) yhi++, ylo++;   /* CURSOR KEYS... */
  97.           else if(key=='8' && ylo>9) yhi-=10, ylo-=10;       /* SHIFTED CURSOR */
  98.           else if(key=='2' && yhi<mrow-10) yhi+=10, ylo+=10; /* KEYS FOR FAST  */
  99.           else if(key=='4' && xlo>9) xhi-=10, xlo-=10;       /* BOX MOVES ...  */
  100.           else if(key=='6' && xhi<mcol-10) xhi+=10, xlo+=10;
  101.           else if(key=='\312' && ylo>0) ylo--;           /* PGUP | THESE KEYS  */
  102.           else if(key=='\313' && ylo<yhi-1) ylo++;       /* PGDN | CHANGE BOX  */
  103.           else if(key=='\310' && xhi>xlo+1) xhi--;       /* HOME | SIZE AND    */
  104.           else if(key=='\311' && xhi<mcol-2) xhi++;      /* END  | SHAPE ..... */
  105.           for(i=xlo; i<=xhi; ++i) (*pt)(i,ylo,-1), (*pt)(i,yhi,-1);
  106.           for(i=ylo+1; i<yhi; ++i) (*pt)(xlo,i,-1), (*pt)(xhi,i,-1);
  107.           } while((key=scr_ci()) != 'q' && key != '\015');
  108.      
  109.           /* IF RETURN KEY HIT, REDRAW REGION IN BOX */
  110.           if(key=='\015'){
  111.                dx = xmax-xmin, dy = ymax-ymin;
  112.                newdx = (xhi-xlo)*dx/(mcol-1);        
  113.                newdy = (yhi-ylo)*dy/(mrow-1);
  114.                if(fabs(newdy) > 0.00001 && fabs(newdx) > 0.00001){
  115.                     xmax = xmin + xhi*dx/(mcol-1);     /* dx,dy SHOULD AUTO */
  116.                     xmin += xlo*dx/(mcol-1);           /* COERCE THESE TO   */   
  117.                     ymax = ymin + yhi*dy/(mrow-1);     /* DOUBLE... */
  118.                     ymin += ylo*dy/(mrow-1);
  119.                     (*gm)();
  120.                     key = mandel(xmin,xmax,ymin,ymax,switchpt,itermax,mcol,mrow,pt,andit);
  121.                     }
  122.                }
  123.      }while(key != 'q');
  124.  
  125. (*tm)();       /* TURN TEXT MODE BACK ON */
  126. puts("LAST SCREEN:\n\n");
  127. printf("x= %.5f to %.5f\ny= %.5f to %.5f\nswitchpt= %d, iter= %d",
  128.       xmin,xmax,ymin,ymax,switchpt,itermax);
  129. }
  130.  
  131. /* mandel() IS ANALOGOUS TO L. FOGG'S VERSION IN DEC/JAN 87/88 MicroC ... */
  132. /* ncol AND nrow ARE THE NUMBER OF COLUMNS AND ROWS THAT CAN BE DISPLAYED */
  133. /* BY CHOSEN GRAPHICS ADAPTER/MODE; E.G., (ncol,nrow) = (720,348) FOR HERC, */
  134. /* (640,350) FOR EGA; endcolor IS ONE LESS THAN MAXIMUM # COLORS GRAPHICS */
  135. /* ADAPTER/MODE CAN DISPLAY; E.G., endcolor IS 1 FOR HERCULES, 15 FOR */
  136. /* MOST EGA's; ptptr IS POINTER TO PIXEL PLOTTING FUNCTION... nmax IS THE */ 
  137. /* MAXIMUM NUMBER OF ITERATIONS WE WILL ALLOW FOR MANDELBROT SERIES... */
  138. /* DeSmet FUNCTION scr_csts() READS KEYBOARD BUFFER, BUT DOES NOT WAIT IF NO KEY */
  139. /* WAS PRESSED ... SIMILAR TO Turbo C COMBINATION OF kbhit() AND getch()... */
  140.  
  141. mandel(Pmin, Pmax, Qmin, Qmax, switcher, maxiter, ncol, nrow, ptptr, endcolor)
  142. double    Pmin, Pmax, Qmin, Qmax;
  143. int       switcher,maxiter,ncol,nrow,endcolor;
  144. void      (*ptptr)();
  145. {
  146.      int       color,row,col,iter,mandwhile(),transform();
  147.      long      P,Q,P0,Q0,dP,dQ;
  148.      long      muldiv();
  149.  
  150.      dP = (Pmax-Pmin)*16777216 + 0.5;  /* 16777216 = 2 to the 24th */
  151.      dQ = (Qmax-Qmin)*16777216 + 0.5;
  152.      P0 = Pmin*16777216 + 0.5;
  153.      Q0 = Qmin*16777216 + 0.5;
  154.  
  155.      for(col=0; col<ncol; ++col){
  156.           for(row=0; row<nrow; ++row){
  157.                P = P0 + muldiv(dP,col,ncol-1);
  158.                Q = Q0 + muldiv(dQ,row,nrow-1);
  159.                iter = mandwhile(P,Q,maxiter) + 1;           /* "+1" DEPENDS ON HOW 1ST */
  160.                color = transform(iter,switchpt) & endcolor; /* ITERATION DEFINED ..... */
  161.                (*ptptr)(col,row,color);
  162.                }
  163.           if(scr_csts()=='q') return('q');
  164.           }
  165. }
  166.  
  167. /* STUPID FUNCTION TO CHECK FOR EGA BY ROM STRING SEARCH */
  168. its_ega()
  169. {
  170.      int  i;
  171.      char c[100];
  172.  
  173.      _lmove(100,0,0xC000,c,_showds());
  174.      for(i=0; i<98; ++i)
  175.           if((c[i]=='I' && c[i+1]=='B' && c[i+2]=='M') || (c[i]=='E' && c[i+1]=='G' && c[i+2]=='A'))
  176.                return(1);
  177.      return(0);
  178. }
  179.  
  180.  
  181.  
  182.