home *** CD-ROM | disk | FTP | other *** search
/ Rat's Nest 1 / ratsnest1.iso / prgmming / c / strange.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-19  |  18.9 KB  |  666 lines

  1. //
  2.  
  3. //+----------------------------------------------------------------------+
  4.  
  5. //+ Program STRANGE.CPP - By Fausto A. A. Barbuto,                       +
  6.  
  7. //+ E-Mail: BJ06@C53000.PETROBRAS.ANRJ.BR, barbuto@ax.ibase.org.br       +
  8.  
  9. //+ and Michael E. Sargent, msargent@moose.uvm.edu                       +
  10.  
  11. //+                                                                      +
  12.  
  13. //+ Uses Michael E. Sargent's graphics functions and Robert Munafo's     +
  14.  
  15. //+ formulae for Period 1 (Main Cardiod) and Period 2 (Main Circle)      +
  16.  
  17. //+ detection.                                                           +
  18.  
  19. //+                                                                      +
  20.  
  21. //+ Plots strange Mandelbrot Sets with decomposed outer layers (similar  +
  22.  
  23. //+ to binary decomposition, but quite different at a first sight).      +
  24.  
  25. //+ Periods 1 & 2 are also decomposed in colourful levels.               +
  26.  
  27. //+                                                                      +
  28.  
  29. //+ Press the '+' key at anytime to rotate palettes; any other key       +
  30.  
  31. //+ will fade the screen out.                                            +
  32.  
  33. //+----------------------------------------------------------------------+
  34.  
  35. //
  36.  
  37. #include <stdio.h>
  38.  
  39. #include <stdlib.h>
  40.  
  41. #include <conio.h>
  42.  
  43. #include <math.h>
  44.  
  45. #include <complex.h>
  46.  
  47. #include <dos.h>
  48.  
  49.  
  50.  
  51. int initvesa(void);
  52.  
  53. void SetMode(int mode);
  54.  
  55. void plot(int i, int j, int color);
  56.  
  57. int selectmode(void);
  58.  
  59. void floatscreen(int y1, int y2, int foreground, int shadow);
  60.  
  61. void quit(void);
  62.  
  63. void setVGAreg(int, int, int, int);
  64.  
  65. void GetPalette(void);
  66.  
  67. void cycle(void);
  68.  
  69. void fade(void);
  70.  
  71.  
  72.  
  73. union REGS reg;
  74.  
  75. struct SREGS seg;
  76.  
  77.  
  78.  
  79. int xres, yres, mode, colors, vesaflag, activebank, bankshift,
  80.  
  81.     locationshift, memoryblocks, (*winfuncptr)();
  82.  
  83. unsigned int modetable[12];
  84.  
  85. long int banksize, linetable[1024];
  86.  
  87. char masktable[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
  88.  
  89. char palette[256][3];
  90.  
  91.  
  92.  
  93. void main()
  94.  
  95. {
  96.  
  97.       double pmin=-2.25, pmax=0.75, qmin=-1.125, qmax=1.125;
  98.  
  99.       double ypy, x, y, p, q, p1, q1, ya, xkp1, ykp1, r;
  100.  
  101.       double deltap, deltaq, r1=8.9138e-3, r2=5.88e-2;
  102.  
  103.       double test1, test2, test3, test4;
  104.  
  105.       register int kk, k, np, nq, npy, ipen;
  106.  
  107.       unsigned long maxiter=512;
  108.  
  109.       int initc, iopt, mistake;
  110.  
  111.       complex c;
  112.  
  113.       char ch, choicekey;
  114.  
  115.  
  116.  
  117.       clrscr();
  118.  
  119.       _setcursortype(_NOCURSOR);
  120.  
  121.       printf("\n Program STRANGE\n");
  122.  
  123.       printf("\n By Fausto A. A. Barbuto, BJ06@C53000.PETROBRAS.ANRJ.BR");
  124.  
  125.       printf("\n                          barbuto@ax.ibase.org.br");
  126.  
  127.       printf("\n\n Graphics routines by Michael E. Sargent, ");
  128.  
  129.       printf("msargent@moose.uvm.edu");
  130.  
  131.       printf("\n\n INSTRUCTIONS: hit ESC to fade the screen out and quit;");
  132.  
  133.       printf("\n               or press '+' to rotate palettes.");
  134.  
  135.       printf("\n\n\n Select an option:");
  136.  
  137.       printf("\n\n 1 - Study in Blue ");
  138.  
  139.       printf("\n 2 - Study in Red ");
  140.  
  141.       printf("\n 3 - Study in Green ");
  142.  
  143.       printf("\n 4 - Study in Gray ");
  144.  
  145.       printf("\n 5 - Graphite ");
  146.  
  147.       do
  148.  
  149.       {
  150.  
  151.      mistake = 0;                       // Reset the mistake flag
  152.  
  153.      choicekey = getch();
  154.  
  155.      iopt = ("%d", choicekey) - 48;
  156.  
  157.      if (iopt < 1 || iopt > 5)          // Check for valid choices
  158.  
  159.      {
  160.  
  161.         printf("%c%c",0x07,0x07);       // Sound some warning beeps
  162.  
  163.         mistake = 1;
  164.  
  165.      }
  166.  
  167.       } while (mistake !=0);                // Repeat until valid selection
  168.  
  169.  
  170.  
  171.       textcolor(YELLOW + BLINK);            // Indicate the choice
  172.  
  173.       gotoxy(2, iopt + 14);
  174.  
  175.       cprintf("%c", choicekey);
  176.  
  177.       textcolor(LIGHTGRAY);
  178.  
  179.       delay(1000);
  180.  
  181.  
  182.  
  183.       vesaflag = initvesa();
  184.  
  185.       if (selectmode()) quit();
  186.  
  187.  
  188.  
  189.       clrscr();
  190.  
  191.       printf("\n Wait a few seconds, please...");
  192.  
  193.       printf("\n Espere um pouco, por favor...");
  194.  
  195.       delay(950);
  196.  
  197.  
  198.  
  199.       SetMode(mode);
  200.  
  201.  
  202.  
  203.       initc = 28;
  204.  
  205.  
  206.  
  207.       if (iopt == 1)
  208.  
  209.       {
  210.  
  211.      for (kk=1;kk<64;kk++) setVGAreg(kk,0,0,kk);
  212.  
  213.      for (kk=64;kk<127;kk++) setVGAreg(kk,0,0,127-kk);
  214.  
  215.       }
  216.  
  217.       if (iopt == 2)
  218.  
  219.       {
  220.  
  221.      for (kk=1;kk<64;kk++) setVGAreg(kk,kk,0,0);
  222.  
  223.      for (kk=64;kk<127;kk++) setVGAreg(kk,127-kk,0,0);
  224.  
  225.       }
  226.  
  227.       if (iopt == 3)
  228.  
  229.       {
  230.  
  231.      for (kk=1;kk<64;kk++) setVGAreg(kk,0,kk,0);
  232.  
  233.      for (kk=64;kk<127;kk++) setVGAreg(kk,0,127-kk,0);
  234.  
  235.       }
  236.  
  237.       if (iopt == 4)
  238.  
  239.       {
  240.  
  241.      for (kk=1;kk<64;kk++) setVGAreg(kk,0,kk,kk);
  242.  
  243.      for (kk=64;kk<127;kk++) setVGAreg(kk,0,127-kk,127-kk);
  244.  
  245.       }
  246.  
  247.       if (iopt == 5)
  248.  
  249.       {
  250.  
  251.      for (kk=1;kk<64;kk++) setVGAreg(kk,0,kk,kk);
  252.  
  253.      for (kk=64;kk<127;kk++) setVGAreg(kk,0,127-kk,127-kk);
  254.  
  255.      initc = 14;
  256.  
  257.       }
  258.  
  259.       setVGAreg(127,0,0,32); // use attribute #127 for blue instead of #1
  260.  
  261.  
  262.  
  263.       ypy = (double)yres - 0.5;
  264.  
  265.       deltap = (pmax-pmin)/(xres-1);
  266.  
  267.       deltaq = (qmax-qmin)/(yres-1);
  268.  
  269.  
  270.  
  271.       if(qmin==-qmax)
  272.  
  273.      npy = yres/2;
  274.  
  275.       else
  276.  
  277.      npy = yres;
  278.  
  279.  
  280.  
  281.      for (np=0; np<=xres-1; np++) {
  282.  
  283.        p = pmin + (double)np*deltap;
  284.  
  285.        for (nq=0; nq<=npy-1; nq++) {
  286.  
  287.      q = qmin + (double)nq*deltaq;
  288.  
  289.      k  = 0;
  290.  
  291.      x = 0.0;
  292.  
  293.      y = 0.0;
  294.  
  295.      c = complex(p,q);
  296.  
  297. //
  298.  
  299. //-------Checks limits for Period 1.
  300.  
  301. //
  302.  
  303.      test1 = 2.0;
  304.  
  305.      if ((p >= -7.55e-1) && (p <= 4.0e-1)) {
  306.  
  307.        if (fabs(q) <= 6.6e-1)
  308.  
  309.           test1 = abs(1.0 - sqrt(1.0-4.0*c));
  310.  
  311.      }
  312.  
  313. //
  314.  
  315. //-------Checks limits for Period 2.
  316.  
  317. //
  318.  
  319.      test2 = 2.0;
  320.  
  321.      if ((p >= -1.255e0) && (p <= -7.45e-1)) {
  322.  
  323.        if (fabs(q) <= 2.55e-1) test2 = 4.0*sqrt((p+1.0)*(p+1.0) + q*q);
  324.  
  325.      }
  326.  
  327. //
  328.  
  329. //-------Checks limits for Period Bud 3.
  330.  
  331. //
  332.  
  333.      test3 = 2.0;
  334.  
  335.      if ((p >= -2.4e-1) && (p <= 0.0e0)) {
  336.  
  337.        if (fabs(q) <= 8.5e-1) {
  338.  
  339.          p1 = p + 1.2486e-1;
  340.  
  341.          q1 = fabs(q) - 7.4396e-1;
  342.  
  343.          test3 = p1*p1 + q1*q1;
  344.  
  345.        }
  346.  
  347.      }
  348.  
  349. //
  350.  
  351. //-------Checks limits for Period 4.
  352.  
  353. //
  354.  
  355.      test4 = 2.0;
  356.  
  357.      if ((p >= -1.37e0) && (p <= -1.245e0)) {
  358.  
  359.        if (fabs(q) <= 6.1e-2) test4 = sqrt((p+1.309)*(p+1.309) + q*q);
  360.  
  361.      }
  362.  
  363. //
  364.  
  365.      if((test1<=1.0) || (test2<=1.0) || (test3<=r1) || (test4<=r2)) {
  366.  
  367.         if (test3<=r1)  ipen = 0;
  368.  
  369.         if (test4<=r2)  ipen = 0;
  370.  
  371.         if (test1<=1.0) ipen = 42 - (int)(35.0*test1);
  372.  
  373.         if (test2<=1.0) ipen = 42 - (int)(31.0*test2);
  374.  
  375.  
  376.  
  377.         if (qmin == -qmax) {
  378.  
  379.           plot(np,nq,ipen);
  380.  
  381.           plot(np,(int)(yres-nq-1.0),ipen);
  382.  
  383.         }
  384.  
  385.         else
  386.  
  387.           plot(np,nq,ipen);
  388.  
  389.         }
  390.  
  391.      else {
  392.  
  393.         do {
  394.  
  395.          xkp1 = (x+y)*(x-y) + p;
  396.  
  397.          ya   = x*y;
  398.  
  399.          ykp1 = ya + ya + q;
  400.  
  401.          asm {
  402.  
  403.            fld   xkp1
  404.  
  405.            fld   xkp1
  406.  
  407.            FMULP
  408.  
  409.            fld   ykp1
  410.  
  411.            fld   ykp1
  412.  
  413.            FMULP
  414.  
  415.            FADDP
  416.  
  417.            fstp  r
  418.  
  419.          }
  420.  
  421.          k++;
  422.  
  423. //
  424.  
  425. //    If R > M, points escape towards infinity.
  426.  
  427. //
  428.  
  429.          if (r >= maxiter) {
  430.  
  431.            ipen = (int)(initc + 2.0*(log(xkp1*xkp1)-log(ykp1*ykp1)));
  432.  
  433.            if (ipen <= 4) ipen = 0;
  434.  
  435.            if (qmin == -qmax) {
  436.  
  437.          plot(np,nq,ipen);
  438.  
  439.          plot(np,(int)(yres-nq-1.0),ipen);
  440.  
  441.            }
  442.  
  443.            else
  444.  
  445.          plot(np,nq,ipen);
  446.  
  447.          }
  448.  
  449. //
  450.  
  451. //    Points which do not belong to any period: Colour=0 (Black)
  452.  
  453. //
  454.  
  455.          if (k == maxiter) {
  456.  
  457.            if (qmin == -qmax) {
  458.  
  459.          ypy = double(yres) - nq - 0.5;
  460.  
  461.          plot(np,(int)ypy,0);
  462.  
  463.          plot(np,nq,0);
  464.  
  465.            }
  466.  
  467.            else
  468.  
  469.          plot(np,nq,ipen);
  470.  
  471.          }
  472.  
  473. //
  474.  
  475. //    Returns if no convergence is achieved on either escape or atraction.
  476.  
  477. //
  478.  
  479.          x = xkp1;
  480.  
  481.          y = ykp1;
  482.  
  483.        } while (r <= maxiter && k<=maxiter);
  484.  
  485.      }
  486.  
  487.        }
  488.  
  489.        if(kbhit()) break;
  490.  
  491.      }
  492.  
  493.      ch = getch();
  494.  
  495.      if (ch == '+') { //* Rotate palettes *//
  496.  
  497.       GetPalette();
  498.  
  499.       cycle();
  500.  
  501.      }
  502.  
  503.      else fade();
  504.  
  505.      quit();
  506.  
  507. }
  508.  
  509. //===========================================================================
  510.  
  511. // 1 - Initialize VESA for SVGA functions
  512.  
  513. // Returns 1 if successful, or 0 if VESA BIOS not present.
  514.  
  515. //===========================================================================
  516.  
  517. int initvesa(void)
  518.  
  519. {
  520.  
  521.    typedef struct
  522.  
  523.    {
  524.  
  525.       char vesasig[4];
  526.  
  527.       unsigned int version;
  528.  
  529.       char *oemstring;
  530.  
  531.       char capabilities[4];
  532.  
  533.       unsigned int *videomode;
  534.  
  535.       unsigned int memory;
  536.  
  537.       char reserved[242];
  538.  
  539.    } VESABLOCK;
  540.  
  541.    VESABLOCK vb;
  542.  
  543.    typedef struct
  544.  
  545.    {
  546.  
  547.       unsigned int attrib;
  548.  
  549.       char wina_attrib;
  550.  
  551.       char winb_attrib;
  552.  
  553.       unsigned int wingran;
  554.  
  555.       unsigned int winsize;
  556.  
  557.       unsigned int wina_seg;
  558.  
  559.       unsigned int winb_seg;
  560.  
  561.       int (*winfuncptr)();
  562.  
  563.       int moreints[3];
  564.  
  565.       char morechars[8];
  566.  
  567.     } VESAMODE;
  568.  
  569.    VESAMODE vm;
  570.  
  571.    int ratio, count=0, modenumber;
  572.  
  573.  
  574.  
  575.    reg.x.ax = 0x4F00;
  576.  
  577.    reg.x.di = FP_OFF((char *)&vb);
  578.  
  579.    seg.es = FP_SEG((char *)&vb);
  580.  
  581.    int86x(0x10,®,®,&seg);
  582.  
  583.    if (reg.x.ax != 0x004F)                /* Returns 4FH if VESA present */
  584.  
  585.    {
  586.  
  587.       return(0);
  588.  
  589.    }
  590.  
  591.  
  592.  
  593.    memoryblocks = vb.memory;       /* Size of video memory in 64K blocks */
  594.  
  595.    while (*vb.videomode != 0xFFFF) /* Make table of all supported modes  */
  596.  
  597.    {                               /* using pointer to VESA BIOS list    */
  598.  
  599.       modenumber = *vb.videomode;
  600.  
  601.       if (modenumber > 0x99 && modenumber < 0x10A)
  602.  
  603.       {
  604.  
  605.      modetable[count] = modenumber;
  606.  
  607.      count++;
  608.  
  609.       }
  610.  
  611.       (vb.videomode)++;
  612.  
  613.    }
  614.  
  615.    modetable[count] = 0xFFFF;
  616.  
  617.  
  618.  
  619.    reg.x.ax = 0x4f01;
  620.  
  621.    reg.x.cx = 0x101;
  622.  
  623.    seg.es = FP_SEG((char *)&vm);
  624.  
  625.    reg.x.di = FP_OFF((char *)&vm);
  626.  
  627.    int86x(0x10,®,®,&seg);      /* Now get additional information */
  628.  
  629.  
  630.  
  631.    winfuncptr = vm.winfuncptr;     /* Pointer to bank-switching function */
  632.  
  633.    banksize = (long)vm.winsize << 10;          /* Get bank size in bytes */
  634.  
  635.    switch (banksize)
  636.  
  637.    {                                          /* In case banks are < 64K */
  638.  
  639.       case 65536L:
  640.  
  641.      locationshift = 16;
  642.  
  643.      break;
  644.  
  645.       case 16384L:
  646.  
  647.      locationshift = 14;
  648.  
  649.      break;
  650.  
  651.       case 4096L:
  652.  
  653.      locationshift = 12;
  654.  
  655.    }
  656.  
  657.  
  658.  
  659.    ratio = vm.winsize / vm.wingran;     /* Set shift factor if necessary */
  660.  
  661.    switch (ratio)
  662.  
  663.    {
  664.  
  665.       case 0x40:
  666.  
  667.      bankshift = 0x06;
  668.  
  669.      break;
  670.  
  671.       case 0x20:
  672.  
  673.      bankshift = 0x05;
  674.  
  675.      break;
  676.  
  677.       case 0x10:
  678.  
  679.      bankshift = 0x04;
  680.  
  681.      break;
  682.  
  683.       case 0x08:
  684.  
  685.      bankshift = 0x03;
  686.  
  687.      break;
  688.  
  689.       case 0x04:
  690.  
  691.      bankshift = 0x02;
  692.  
  693.      break;
  694.  
  695.       case 0x02:
  696.  
  697.      bankshift = 0x01;
  698.  
  699.      break;
  700.  
  701.       case 0x01:
  702.  
  703.      bankshift = 0x00;
  704.  
  705.    }
  706.  
  707.    return(1);
  708.  
  709. }
  710.  
  711. //===========================================================================
  712.  
  713. // 2 - Set video mode; set linetable[] array
  714.  
  715. //===========================================================================
  716.  
  717. void SetMode(int mode)
  718.  
  719. {
  720.  
  721.    int i;
  722.  
  723.  
  724.  
  725.    if (mode <= 0x13)                   /* VGA modes */
  726.  
  727.       reg.x.ax = mode;
  728.  
  729.    else
  730.  
  731.    {
  732.  
  733.       reg.x.ax = 0x4F02;               /* VESA SVGA modes */
  734.  
  735.       reg.x.bx = mode;
  736.  
  737.       activebank = -1;                 /* For switching banks for plotting */
  738.  
  739.    }
  740.  
  741.    int86(0x10,®,®);
  742.  
  743.  
  744.  
  745.    colors = 256;
  746.  
  747.    switch(mode)                        /* Set the flags */
  748.  
  749.    {
  750.  
  751.       case 0x03:
  752.  
  753.      return;
  754.  
  755.       case 0x13:
  756.  
  757.      xres = 320;
  758.  
  759.      yres = 200;
  760.  
  761.      break;
  762.  
  763.       case 0x101:
  764.  
  765.      xres = 640;
  766.  
  767.      yres = 480;
  768.  
  769.      break;
  770.  
  771.       case 0x103:
  772.  
  773.      xres = 800;
  774.  
  775.      yres = 600;
  776.  
  777.      break;
  778.  
  779.       case 0x105:
  780.  
  781.      xres = 1024;
  782.  
  783.      yres = 768;
  784.  
  785.      break;
  786.  
  787.       case 0x107:
  788.  
  789.      xres = 1280;
  790.  
  791.      yres = 1024;
  792.  
  793.    }
  794.  
  795.  
  796.  
  797.    for (i=0;i<yres;i++)
  798.  
  799.       linetable[i] = (long)i * (long)xres;
  800.  
  801. }
  802.  
  803. //===========================================================================
  804.  
  805. // 3 - Plot a point in 256-color modes
  806.  
  807. //===========================================================================
  808.  
  809. void plot(int i, int j, int color)
  810.  
  811. {
  812.  
  813.    char far *address;
  814.  
  815.    long int location, offset;
  816.  
  817.    int bank;
  818.  
  819.  
  820.  
  821.    if (mode == 0x13) offset = linetable[j] + (long)i;
  822.  
  823.    else
  824.  
  825.    {
  826.  
  827.       location = linetable[j] + (long)i;
  828.  
  829.       bank = location >> locationshift;
  830.  
  831.       offset = location - ((long)bank << locationshift);
  832.  
  833.       if (bank != activebank)
  834.  
  835.       {
  836.  
  837.      activebank = bank;
  838.  
  839.      bank = bank << bankshift;
  840.  
  841.      asm mov dx,[bank];
  842.  
  843.      asm mov bx,0000h;
  844.  
  845.      asm call dword ptr [winfuncptr];
  846.  
  847.       }
  848.  
  849.    }
  850.  
  851.    address = (char far *)(0xA0000000L + offset);
  852.  
  853.    *address = color;
  854.  
  855. }
  856.  
  857. //===========================================================================
  858.  
  859. // 4 - Choose 256-color video mode; check for support for chosen mode.
  860.  
  861. // Returns 1 to signal quit request.
  862.  
  863. //===========================================================================
  864.  
  865. int selectmode(void)
  866.  
  867. {
  868.  
  869.  char choicekey;
  870.  
  871.  int mistake, count;
  872.  
  873.  
  874.  
  875.  if (!vesaflag)
  876.  
  877.  {
  878.  
  879.     mode = 0x13;
  880.  
  881.     return(0);
  882.  
  883.  }
  884.  
  885.  
  886.  
  887.  SetMode(0x03);
  888.  
  889.  floatscreen(7,19,LIGHTBLUE,BLUE);
  890.  
  891.  do                                         /* Select graphics mode */
  892.  
  893.  {
  894.  
  895.    mistake = 0;
  896.  
  897.    textcolor(BLUE);
  898.  
  899.    textbackground(LIGHTGRAY);
  900.  
  901.    _setcursortype(_NOCURSOR);
  902.  
  903.    gotoxy(13,7);
  904.  
  905.    cprintf(" ╔════════════════════════╡¥╞═════════════════════════╗ ");
  906.  
  907.    gotoxy(13,8);
  908.  
  909.    cprintf(" ║   SELECT GRAPHICS MODE:    (Esc to quit program)   ║ ");
  910.  
  911.    gotoxy(13,9);
  912.  
  913.    cprintf(" ╟────────────────────────────────────────────────────╢ ");
  914.  
  915.    gotoxy(13,10);
  916.  
  917.    cprintf(" ║   Make sure your monitor supports selected mode!   ║ ");
  918.  
  919.    gotoxy(13,11);
  920.  
  921.    cprintf(" ╠════════════════════════════════════════════════════╣ ");
  922.  
  923.    gotoxy(13,12);
  924.  
  925.    cprintf(" ║      a: VGA        13H    ( 320 x 200  x 256)      ║ ");
  926.  
  927.    gotoxy(13,13);
  928.  
  929.    cprintf(" ║      b: SVGA VESA 101H    ( 640 x 480  x 256)      ║ ");
  930.  
  931.    gotoxy(13,14);
  932.  
  933.    cprintf(" ║      c: SVGA VESA 103H    ( 800 x 600  x 256)      ║ ");
  934.  
  935.    gotoxy(13,15);
  936.  
  937.    cprintf(" ║      d: SVGA VESA 105H    (1024 x 768  x 256)      ║ ");
  938.  
  939.    gotoxy(13,16);
  940.  
  941.    cprintf(" ║      e: SVGA VESA 107H    (1280 x 1024 x 256)      ║ ");
  942.  
  943.    gotoxy(13,17);
  944.  
  945.    cprintf(" ╟────────────────────────────────────────────────────╢ ");
  946.  
  947.    gotoxy(13,18);
  948.  
  949.    cprintf(" ║                                                    ║ ");
  950.  
  951.    gotoxy(13,19);
  952.  
  953.    cprintf(" ╚════════════════════════════════════════════════════╝ ");
  954.  
  955.    do
  956.  
  957.    {
  958.  
  959.       mistake = 0;                          /* Reset the mistake flag */
  960.  
  961.       choicekey = getch();
  962.  
  963.       if (choicekey > 64 && choicekey < 70) choicekey += 32; /* Caps */
  964.  
  965.       if (choicekey==0x1B) return(1);       /* Esc to quit */
  966.  
  967.       mode = ("%d", choicekey) - 96;
  968.  
  969.       if (mode < 1 || mode > 5)             /* Check for valid choices */
  970.  
  971.       {
  972.  
  973.      printf("%c%c",0x07,0x07);          /* Sound some warning beeps */
  974.  
  975.      mistake = 1;
  976.  
  977.       }
  978.  
  979.    }
  980.  
  981.    while (mistake !=0);                     /* Repeat until valid selection */
  982.  
  983.  
  984.  
  985.    textcolor(YELLOW + BLINK);               /* Indicate the choice */
  986.  
  987.    gotoxy(21, mode + 11);
  988.  
  989.    cprintf("%c", choicekey);
  990.  
  991.    textcolor(BLUE);
  992.  
  993.    delay(1000);
  994.  
  995.    switch(mode)                             /* Set the actual flag */
  996.  
  997.    {
  998.  
  999.       case 1:
  1000.  
  1001.      mode = 0x13;
  1002.  
  1003.      break;
  1004.  
  1005.       case 2:
  1006.  
  1007.      mode = 0x101;
  1008.  
  1009.      break;
  1010.  
  1011.       case 3:
  1012.  
  1013.      mode = 0x103;
  1014.  
  1015.      break;
  1016.  
  1017.       case 4:
  1018.  
  1019.      mode = 0x105;
  1020.  
  1021.      break;
  1022.  
  1023.       case 5:
  1024.  
  1025.      mode = 0x107;
  1026.  
  1027.    }
  1028.  
  1029.  
  1030.  
  1031.    if (mode >= 0x100)                  /* Check for mode/memory support */
  1032.  
  1033.    {
  1034.  
  1035.       count = 0;
  1036.  
  1037.       while (modetable[count] != 0xFFFF)
  1038.  
  1039.       {
  1040.  
  1041.      if (modetable[count] == mode) break;
  1042.  
  1043.      count++;
  1044.  
  1045.       }
  1046.  
  1047.       if (modetable[count] == 0xFFFF)  /* Won't get to FFFFH if supported */
  1048.  
  1049.       {
  1050.  
  1051.      gotoxy(21,18);
  1052.  
  1053.      cprintf("Mode %XH is not supported :-(", mode);
  1054.  
  1055.      delay(2000);
  1056.  
  1057.      mistake = 1;
  1058.  
  1059.       }
  1060.  
  1061.       if ((mode>0x100&&memoryblocks<8) || (mode==0x105&&memoryblocks<12) || (mode==0x107&&memoryblocks<20))
  1062.  
  1063.       {
  1064.  
  1065.      gotoxy(21,18);
  1066.  
  1067.      cprintf("Not enough video memory for mode %XH", mode);
  1068.  
  1069.      delay(2000);
  1070.  
  1071.      mistake = 1;
  1072.  
  1073.       }
  1074.  
  1075.    }
  1076.  
  1077.  }
  1078.  
  1079.  while (mistake !=0);                  /* Repeat until valid selection */
  1080.  
  1081.  textbackground(BLACK);
  1082.  
  1083.  return(0);
  1084.  
  1085. }
  1086.  
  1087. //===========================================================================
  1088.  
  1089. // 5 - Display floating input screen with ASCII block texture
  1090.  
  1091. //===========================================================================
  1092.  
  1093. void floatscreen(int y1, int y2, int foreground, int shadow)
  1094.  
  1095. {
  1096.  
  1097.    int step;
  1098.  
  1099.  
  1100.  
  1101.    textcolor(foreground);
  1102.  
  1103.    textbackground(BLACK);
  1104.  
  1105.    _setcursortype(_NOCURSOR);
  1106.  
  1107.    clrscr();
  1108.  
  1109.    for (step=1;step<26;step++)
  1110.  
  1111.    {
  1112.  
  1113.       gotoxy(2,step);
  1114.  
  1115.       cprintf("░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓");
  1116.  
  1117.       cprintf("▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░");
  1118.  
  1119.    }
  1120.  
  1121.    textcolor(shadow);
  1122.  
  1123.    for (step=y1+1;step<y2+1;step++)
  1124.  
  1125.    {
  1126.  
  1127.       gotoxy(69,step);
  1128.  
  1129.       cprintf("░░");
  1130.  
  1131.    }
  1132.  
  1133.    gotoxy(15,y2+1);
  1134.  
  1135.    cprintf("░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░");
  1136.  
  1137. }
  1138.  
  1139. //===========================================================================
  1140.  
  1141. // Quit.
  1142.  
  1143. //===========================================================================
  1144.  
  1145. void quit(void)
  1146.  
  1147. {
  1148.  
  1149.    SetMode(0x03);
  1150.  
  1151.    textcolor(LIGHTGRAY);              /* Restore standard conditions */
  1152.  
  1153.    textbackground(BLACK);
  1154.  
  1155.    _setcursortype(_NORMALCURSOR);
  1156.  
  1157.    clrscr();
  1158.  
  1159.    exit(0);
  1160.  
  1161. }
  1162.  
  1163. //===========================================================================
  1164.  
  1165. // 13 - Set individual palette register
  1166.  
  1167. //===========================================================================
  1168.  
  1169. void setVGAreg(int reg_no, int red, int green, int blue)
  1170.  
  1171. {
  1172.  
  1173.       outportb(0x3c8, reg_no);
  1174.  
  1175.       outportb(0x3c9, red);
  1176.  
  1177.       outportb(0x3c9, green);
  1178.  
  1179.       outportb(0x3c9, blue);
  1180.  
  1181. }
  1182.  
  1183. //+======================+
  1184.  
  1185. // Color-cycling routine +
  1186.  
  1187. //+======================+
  1188.  
  1189. void cycle(void)
  1190.  
  1191. {
  1192.  
  1193.    int x=0, y, z;
  1194.  
  1195.  
  1196.  
  1197.    do
  1198.  
  1199.    {
  1200.  
  1201.       while ((inportb(0x3da) & 0x08));      // Wait for vertical retrace
  1202.  
  1203.       while (!(inportb(0x3da) & 0x08));
  1204.  
  1205.       for (z=1; z<127; z++)
  1206.  
  1207.       {
  1208.  
  1209.      y=z+x;
  1210.  
  1211.      if (y > 126)
  1212.  
  1213.         y -= 126;
  1214.  
  1215.      outportb(0x3C8, z);
  1216.  
  1217.      outportb(0x3C9, palette[y][0]);
  1218.  
  1219.      outportb(0x3C9, palette[y][1]);
  1220.  
  1221.      outportb(0x3C9, palette[y][2]);
  1222.  
  1223.       }
  1224.  
  1225.       x += 1;
  1226.  
  1227.       if (x==126)
  1228.  
  1229.      x=0;
  1230.  
  1231.       delay(100); //* Originally, delay(50) *//
  1232.  
  1233.    }
  1234.  
  1235.    while (kbhit() == 0);
  1236.  
  1237.    getch(); getch(); fade();
  1238.  
  1239. }
  1240.  
  1241. //+=================+
  1242.  
  1243. // Fade-out routine +
  1244.  
  1245. //==================+
  1246.  
  1247. void fade(void)
  1248.  
  1249. {
  1250.  
  1251.    int a, b, p1, p2, p3;
  1252.  
  1253.  
  1254.  
  1255.    for (a=0; a<64; a++)
  1256.  
  1257.    {
  1258.  
  1259.       while ((inportb(0x3da) & 0x08));      // Wait for vertical retrace
  1260.  
  1261.       while (!(inportb(0x3da) & 0x08));
  1262.  
  1263.       for (b=0; b<256; b++)
  1264.  
  1265.       {
  1266.  
  1267.      outportb(0x3C7, b);
  1268.  
  1269.      p1 = inportb(0x3C9);
  1270.  
  1271.      p2 = inportb(0x3C9);
  1272.  
  1273.      p3 = inportb(0x3C9);
  1274.  
  1275.      outportb (0x3C8, b);
  1276.  
  1277.      if (p1 > 0) outportb(0x3C9, p1 - 1);
  1278.  
  1279.         else outportb(0x3C9, 0);
  1280.  
  1281.      if (p2 > 0) outportb(0x3C9, p2 - 1);
  1282.  
  1283.         else outportb(0x3C9, 0);
  1284.  
  1285.      if (p3 > 0) outportb(0x3C9, p3 - 1);
  1286.  
  1287.         else outportb(0x3C9, 0);
  1288.  
  1289.       }
  1290.  
  1291.    delay(85);
  1292.  
  1293.    }
  1294.  
  1295. }
  1296.  
  1297. //+============================================+
  1298.  
  1299. // Function to obtain current palette in array +
  1300.  
  1301. //+============================================+
  1302.  
  1303. void GetPalette(void)
  1304.  
  1305. {
  1306.  
  1307.    int p, a, b;
  1308.  
  1309.  
  1310.  
  1311.    for (a=0; a<256; a++)
  1312.  
  1313.    {
  1314.  
  1315.       outportb(0x3C7, a);
  1316.  
  1317.       for (b=0; b<3; b++)
  1318.  
  1319.       {
  1320.  
  1321.       p = inportb(0x3C9);
  1322.  
  1323.       palette[a][b] = p;
  1324.  
  1325.       }
  1326.  
  1327.     }
  1328.  
  1329. }
  1330.  
  1331.