home *** CD-ROM | disk | FTP | other *** search
/ The Best of Select: Games 4 / CD_1.iso / kids / spiro / gr.c < prev    next >
C/C++ Source or Header  |  2010-07-21  |  15KB  |  703 lines

  1. #include <bios.h>
  2. #include <conio.h>
  3. #include <graph.h>
  4. #include <math.h>
  5. #include <memory.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <time.h>
  10.  
  11. #define max_coord 450
  12.  
  13. // adjust aspect_factor so that round figures are round and sqaure figures
  14. // are square.    Larger values increase the width of the display.
  15. #define aspect_factor .72
  16.  
  17. long    current_palette[15];
  18. short   display_color;
  19. short   display_count;
  20. long    display_palette[16];
  21. short   display_rotate;
  22. long    display_timer;
  23. short   display_x1[max_coord];
  24. short   display_x2[max_coord];
  25. short   display_y1[max_coord];
  26. short   display_y2[max_coord];
  27. short   idx_color;
  28. short   line_color[max_coord];
  29. short   max_color;
  30. short   num_color;
  31. short    num_coord;
  32. double    pi;
  33. double    quarter_pi;
  34. double    two_pi;
  35. double  x[252];
  36. double  x_offset;
  37. double  x_size;
  38. double  xy_aspect;
  39. double  x1_coord[max_coord];
  40. double  x2_coord[max_coord];
  41. double  y[252];
  42. double  y_size;
  43. double  y1_coord[max_coord];
  44. double  y2_coord[max_coord];
  45.  
  46. void    graphics_init(void);
  47. void    draw_curve(void);
  48. void    draw_polygon(void);
  49. void    draw_spiral(void);
  50. void    draw_cardiod(void);
  51. void    draw_dual(void);
  52. void    draw_single(void);
  53. void    set_palette(short);
  54. short   plot_line(double*,double*,double*,double*);
  55. void    advance_color(void);
  56. void    display_graph(short);
  57.  
  58. void main(void)
  59.     {
  60.     srand((short)time(NULL));
  61.     quarter_pi=atan(1.0);
  62.     pi=4.0*quarter_pi;
  63.     two_pi=8.0*quarter_pi;
  64.     graphics_init();
  65.     while (1)
  66.         {
  67.         switch (rand()%6)
  68.             {
  69.             case 0:
  70.                 draw_curve();
  71.                 break;
  72.             case 1:
  73.                 draw_polygon();
  74.                 break;
  75.             case 2:
  76.                 draw_spiral();
  77.                 break;
  78.             case 3:
  79.                 draw_cardiod();
  80.                 break;
  81.             case 4:
  82.                 draw_single();
  83.                 break;
  84.             case 5:
  85.                 draw_dual();
  86.                 break;
  87.             }
  88.         }
  89.     }
  90.  
  91. void graphics_init()
  92.     {
  93.     struct videoconfig config;
  94.     _getvideoconfig(&config);
  95.     if (config.monitor&_ANALOG)
  96.         {
  97.         _setvideomode(_VRES16COLOR);
  98.         max_color=15;
  99.         }
  100.     else
  101.         {
  102.         if (config.monitor&_ENHCOLOR)
  103.             {
  104.             _setvideomode(_ERESCOLOR);
  105.             max_color=15;
  106.             }
  107.         else
  108.             {
  109.             if (config.monitor&_COLOR)
  110.                 {
  111.                 _setvideomode(_HRESBW);
  112.                 max_color=1;
  113.                 }
  114.             else
  115.                 exit(1);
  116.             }
  117.         }
  118.     _getvideoconfig(&config);
  119.     x_size=(double)config.numxpixels-1;
  120.     y_size=(double)config.numypixels-1;
  121.     xy_aspect=aspect_factor*x_size/y_size;
  122.     display_count=0;
  123.     num_coord=0;
  124.     }
  125.  
  126. void draw_curve()
  127.     {
  128.     register short i,j,k,l,m,n;
  129.     short number_sides,number_points;
  130.     short threads,rotate,tilt,total_points;
  131.     double r_number_sides,r_number_points;
  132.     double r,x1,y1,x2,y2,xd,yd;
  133.     number_sides=rand()%4+3;
  134.     number_points=rand()%(200/number_sides-2)+3;
  135.     if (rand()&1 && number_sides>4)
  136.         threads=2;
  137.     else
  138.         threads=1;
  139.     if (rand()&1)
  140.         {
  141.         set_palette(number_points);
  142.         rotate=1;
  143.         }
  144.     else
  145.         {
  146.         set_palette(number_sides);
  147.         rotate=0;
  148.         }
  149.     if (number_sides&1)
  150.         tilt=2;
  151.     else
  152.         if (number_sides&3)
  153.             tilt=0;
  154.         else
  155.             tilt=1;
  156.     k=0;
  157.     r_number_sides=(double)number_sides;
  158.     r_number_points=(double)number_points;
  159.     for (i=0;i<number_sides;i++)
  160.         {
  161.         r=quarter_pi*(8.0*(double)i/r_number_sides-tilt);
  162.         x1=cos(r);
  163.         y1=sin(r);
  164.         r=quarter_pi*(8.0*(double)(i+1)/r_number_sides-tilt);
  165.         x2=cos(r);
  166.         y2=sin(r);
  167.         xd=(x2-x1)/r_number_points;
  168.         yd=(y2-y1)/r_number_points;
  169.         for (j=0;j<number_points;j++)
  170.             {
  171.             x[k]=x1+(double)j*xd;
  172.             y[k]=y1+(double)j*yd;
  173.             k++;
  174.             }
  175.         }
  176.     total_points=number_sides*number_points;
  177.     if (rotate)
  178.         {
  179.         n=0;
  180.         for (i=0;i<number_points;i++)
  181.             {
  182.             for (j=i;j<total_points;j+=number_points)
  183.                 {
  184.                 k=j;
  185.                 for (m=0;m<threads;m++)
  186.                     {
  187.                     k+=number_points;
  188.                     if (k>=total_points)
  189.                         k-=total_points;
  190.                     if (plot_line(&x[j],&y[j],&x[k],&y[k]))
  191.                         return;
  192.                     }
  193.                 if (++n==number_sides)
  194.                     {
  195.                     n=0;
  196.                     advance_color();
  197.                     }
  198.                 }
  199.             }
  200.         }
  201.     else
  202.         {
  203.         k=0;
  204.         for (i=0;i<number_sides;i++)
  205.             {
  206.             for (j=0;j<number_points;j++)
  207.                 {
  208.                 l=k;
  209.                 for (m=0;m<threads;m++)
  210.                     {
  211.                     l+=number_points;
  212.                     if (l>=total_points)
  213.                         l-=total_points;
  214.                     if (plot_line(&x[k],&y[k],&x[l],&y[l]))
  215.                         return;
  216.                     }
  217.                 k++;
  218.                 }
  219.             advance_color();
  220.             }
  221.         }
  222.     display_graph(rotate);
  223.     }
  224.  
  225. void draw_polygon()
  226.     {
  227.     register short i,j,k,m,n;
  228.     double hp;
  229.     n=rand()%26+5;
  230.     if (n>6 && rand()&1)
  231.         {
  232.         set_palette(n);
  233.         m=num_color>2? 1:0;
  234.         }
  235.     else
  236.         {
  237.         set_palette(n/2);
  238.         m=0;
  239.         }
  240.     hp=8*atan(1.0)/n;
  241.     for (i=0;i<n;i++)
  242.         {
  243.         x[i]=sin(i*hp);
  244.         y[i]=cos(i*hp);
  245.         }
  246.     if (m)
  247.         {
  248.         for (i=0;i<n;i++)
  249.             {
  250.             for (j=i+1;j<=i+n/2;j++)
  251.                 {
  252.                 k=j>=n? j-n:j;
  253.                 if (plot_line(&x[i],&y[i],&x[k],&y[k]))
  254.                     return;
  255.                 }
  256.             advance_color();
  257.             }
  258.         }
  259.     else
  260.         {
  261.         for (i=1;i<=n/2;i++)
  262.             {
  263.             for (j=0;j<n;j++)
  264.                 {
  265.                 k=i+j;
  266.                 if (k>=n)
  267.                     k-=n;
  268.                 if (plot_line(&x[j],&y[j],&x[k],&y[k]))
  269.                     return;
  270.                 }
  271.             advance_color();
  272.             }
  273.         }
  274.     display_graph(m);
  275.     }
  276.  
  277. void draw_spiral()
  278.     {
  279.     short i,n;
  280.     double delta_angle,accum_angle,accum_dist,x1,y1,x2,y2;
  281.     do
  282.         {
  283.         n=rand()%240+60;
  284.         } while (n==180);
  285.     delta_angle=(double)n*pi/250;
  286.     accum_dist=0.0;
  287.     accum_angle=delta_angle;
  288.     x1=0.0;
  289.     y1=0.0;
  290.     n=max_coord/10*(rand()%9+2);
  291.     set_palette(n);
  292.     for (i=0;i<n;i++)
  293.         {
  294.         accum_dist++;
  295.         x2=x1+accum_dist*cos(accum_angle);
  296.         y2=y1+accum_dist*sin(accum_angle);
  297.         if (plot_line(&x1,&y1,&x2,&y2))
  298.             return;
  299.         accum_angle+=delta_angle;
  300.         if (accum_angle>two_pi)
  301.             {
  302.             accum_angle-=two_pi;
  303.             advance_color();
  304.             }
  305.         y1=y2;
  306.         x1=x2;
  307.         }
  308.     display_graph(1);
  309.     }
  310.  
  311. void draw_cardiod()
  312.     {
  313.     register short i,j,k,m,n;
  314.     double hp;
  315.     n=rand()%20+6;
  316.     set_palette(n);
  317.     n=10*n+1;
  318.     hp=8*atan(1.0)/n;
  319.     for (i=1;i<=n;i++)
  320.         {
  321.         x[i]=sin(i*hp);
  322.         y[i]=cos(i*hp);
  323.         }
  324.     k=0;
  325.     m=rand()%3+2;
  326.     while (1)
  327.         {
  328.         k++;
  329.         i=k;
  330.         j=m*k;
  331.         while (i>n)
  332.             i-=n;
  333.         while (j>n)
  334.             j-=n;
  335.         if (i==n && j==n)
  336.             break;
  337.         if (plot_line(&x[i],&y[i],&x[j],&y[j]))
  338.             return;
  339.         advance_color();
  340.         }
  341.     if (plot_line(&x[1],&y[1],&x[n-1],&y[n-1]))
  342.         return;
  343.     display_graph(1);
  344.     }
  345.  
  346. void draw_single()
  347.     {
  348.     register short i,n;
  349.     double max_angle;
  350.     double x1,y1,x2,y2,nx1,nx2;
  351.     n=(rand()%90+11);
  352.     set_palette(n);
  353.     max_angle=(double)(rand()%11+10)/5.0*atan(1.0);
  354.     y1=-cos(max_angle);
  355.     for (i=0;i<=n;i++)
  356.         {
  357.         x1=(double)i/(double)n;
  358.         x2=sin(x1*max_angle);
  359.         y2=-cos(x1*max_angle);
  360.         nx1=-x1;
  361.         nx2=-x2;
  362.         if (plot_line(&nx1,&y1,&x2,&y2))
  363.             return;
  364.         if (plot_line(&x1,&y1,&nx2,&y2))
  365.             return;
  366.         advance_color();
  367.         }
  368.     display_graph(1);
  369.     }
  370.  
  371. void draw_dual()
  372.     {
  373.     register short i,n;
  374.     double max_angle;
  375.     double x1,y1,x2,y2,nx1,nx2,ny2,zero;
  376.     n=(rand()%90+11);
  377.     set_palette(n);
  378.     max_angle=(double)(rand()%11+10)/5.0*atan(1.0);
  379.     y1=-cos(max_angle);
  380.     zero=0.0;
  381.     for (i=0;i<=n;i++)
  382.         {
  383.         x1=(double)i/(double)n;
  384.         x2=sin(x1*max_angle);
  385.         y2=-cos(x1*max_angle)-y1;
  386.         x1*=2;
  387.         nx1=-x1;
  388.         nx2=-x2;
  389.         ny2=-y2;
  390.         if (plot_line(&nx1,&zero,&x2,&y2))
  391.             return;
  392.         if (plot_line(&x1,&zero,&nx2,&y2))
  393.             return;
  394.         if (plot_line(&nx1,&zero,&x2,&ny2))
  395.             return;
  396.         if (plot_line(&x1,&zero,&nx2,&ny2))
  397.             return;
  398.         advance_color();
  399.         }
  400.     display_graph(1);
  401.     }
  402.  
  403. void set_palette(req_color)
  404. short req_color;
  405.     {
  406.     register short i;
  407.     short factor_1,factor_2,factor_3,index_1,index_2,index_3;
  408.     double base;
  409.     idx_color=0;
  410.     if (max_color==1)
  411.         {
  412.         current_palette[0]=15;
  413.         num_color=1;
  414.         return;
  415.         }
  416.     switch (rand()%2)
  417.         {
  418.         case 0:
  419.             do
  420.                 {
  421.                 num_color=rand()%((req_color<1 || req_color>max_color)? max_color:req_color)+1;
  422.                 } while (req_color%num_color);
  423.             break;
  424.         case 1:
  425.             for (num_color=15;num_color>0;num_color--)
  426.                 if (req_color%num_color==0)
  427.                     break;
  428.             break;
  429.         }
  430.     switch (rand()%5)
  431.         {
  432.         case 0:
  433.             base=pi*(double)(rand()%200)/100.0;
  434.             for (i=0;i<num_color;i++)
  435.                 {
  436.                 index_1=(short)max((short)(63.0*sin(two_pi*(double)i/(double)num_color+base)),0);
  437.                 index_2=(short)max((short)(63.0*sin(two_pi*(double)i/(double)num_color+two_pi/3+base)),0);
  438.                 index_3=(short)max((short)(63.0*sin(two_pi*(double)i/(double)num_color+4*pi/3+base)),0);
  439.                 current_palette[i]=(long)index_1+((long)index_2<<8)+((long)index_3<<16);
  440.                 }
  441.             break;
  442.         case 1:
  443.             base=pi*(double)(rand()%200)/100.0;
  444.             for (i=0;i<num_color;i++)
  445.                 {
  446.                 index_1=(short)(63.0*fabs(sin(two_pi*(double)i/(double)num_color+base)));
  447.                 index_2=(short)(63.0*fabs(sin(two_pi*(double)i/(double)num_color+two_pi/3+base)));
  448.                 index_3=(short)(63.0*fabs(sin(two_pi*(double)i/(double)num_color+4*pi/3+base)));
  449.                 current_palette[i]=(long)index_1+((long)index_2<<8)+((long)index_3<<16);
  450.                 }
  451.             break;
  452.         case 2:
  453.             do
  454.                 {
  455.                 factor_1=rand()%3;
  456.                 factor_2=rand()%3;
  457.                 } while (factor_1==factor_2);
  458.             factor_3=3-(factor_1|factor_2);
  459.             factor_1*=8;
  460.             factor_2*=8;
  461.             factor_3*=8;
  462.             index_3=rand()%64;
  463.             for (i=0;i<num_color;i++)
  464.                 {
  465.                 index_1=(short)(63.0*sin(pi*(double)i/(double)num_color));
  466.                 index_2=63-index_1;
  467.                 current_palette[i]=((long)index_1<<factor_1)+((long)index_2<<factor_2)+((long)index_3<<factor_3);
  468.                 }
  469.             break;
  470.         case 3:
  471.             for (i=0;i<num_color;i++)
  472.                 {
  473.                 do
  474.                     {
  475.                     index_1=rand()%64;
  476.                     index_2=rand()%64;
  477.                     index_3=rand()%64;
  478.                     } while (index_1<32 && index_2<32 && index_3<32);
  479.                 current_palette[i]=(long)index_1+((long)index_2<<8)+((long)index_3<<16);
  480.                 }
  481.             break;
  482.         case 4:
  483.             do
  484.                 {
  485.                 factor_1=rand()%3;
  486.                 factor_2=rand()%3;
  487.                 factor_3=rand()%3;
  488.                 } while (factor_1<2 && factor_2<2 && factor_3<2);
  489.             for (i=0;i<num_color;i++)
  490.                 {
  491.                 index_1=factor_1*(16*i/num_color+16);
  492.                 index_2=factor_2*(16*i/num_color+16);
  493.                 index_3=factor_3*(16*i/num_color+16);
  494.                 current_palette[i]=(long)index_1+((long)index_2<<8)+((long)index_3<<16);
  495.                 }
  496.             break;
  497.         }
  498.     }
  499.  
  500. void advance_color()
  501.     {
  502.     idx_color++;
  503.     if (idx_color==num_color)
  504.         idx_color=0;
  505.     }
  506.  
  507. short plot_line(x1,y1,x2,y2)
  508. double *x1,*y1,*x2,*y2;
  509.     {
  510.     if (num_coord==max_coord)
  511.         {
  512.         num_coord=0;
  513.         return(1);
  514.         }
  515.     x1_coord[num_coord]=*x1;
  516.     y1_coord[num_coord]=*y1;
  517.     x2_coord[num_coord]=*x2;
  518.     y2_coord[num_coord]=*y2;
  519.     line_color[num_coord]=idx_color;
  520.     num_coord++;
  521.     return(0);
  522.     }
  523.  
  524. void display_graph(req_rotate)
  525. short req_rotate;
  526.     {
  527.     register short i,j;
  528.     short rotate_direction;
  529.     long current_timer,ticks,delay_timer;
  530.     double dv;
  531.     if (num_coord==0)
  532.         return;
  533.     dv=1e38;
  534.     for (i=0;i<num_coord;i++)
  535.         if (x1_coord[i]<dv)
  536.             dv=x1_coord[i];
  537.     for (i=0;i<num_coord;i++)
  538.         if (x2_coord[i]<dv)
  539.             dv=x2_coord[i];
  540.     for (i=0;i<num_coord;i++)
  541.         x1_coord[i]-=dv;
  542.     for (i=0;i<num_coord;i++)
  543.         x2_coord[i]-=dv;
  544.     dv=1e38;
  545.     for (i=0;i<num_coord;i++)
  546.         if (y1_coord[i]<dv)
  547.             dv=y1_coord[i];
  548.     for (i=0;i<num_coord;i++)
  549.         if (y2_coord[i]<dv)
  550.             dv=y2_coord[i];
  551.     for (i=0;i<num_coord;i++)
  552.         y1_coord[i]-=dv;
  553.     for (i=0;i<num_coord;i++)
  554.         y2_coord[i]-=dv;
  555.     for (i=0;i<num_coord;i++)
  556.         x1_coord[i]/=x_size/y_size/xy_aspect;
  557.     for (i=0;i<num_coord;i++)
  558.         x2_coord[i]/=x_size/y_size/xy_aspect;
  559.     dv=0.0;
  560.     for (i=0;i<num_coord;i++)
  561.         if (x1_coord[i]>dv)
  562.             dv=x1_coord[i];
  563.     for (i=0;i<num_coord;i++)
  564.         if (x2_coord[i]>dv)
  565.             dv=x2_coord[i];
  566.     for (i=0;i<num_coord;i++)
  567.         if (y1_coord[i]>dv)
  568.             dv=y1_coord[i];
  569.     for (i=0;i<num_coord;i++)
  570.         if (y2_coord[i]>dv)
  571.             dv=y2_coord[i];
  572.     if (dv==0.0)
  573.         return;
  574.     for (i=0;i<num_coord;i++)
  575.         x1_coord[i]*=x_size/dv;
  576.     for (i=0;i<num_coord;i++)
  577.         x2_coord[i]*=x_size/dv;
  578.     for (i=0;i<num_coord;i++)
  579.         y1_coord[i]*=y_size/dv;
  580.     for (i=0;i<num_coord;i++)
  581.         y2_coord[i]*=y_size/dv;
  582.     dv=0.0;
  583.     for (i=0;i<num_coord;i++)
  584.         if (x1_coord[i]>dv)
  585.             dv=x1_coord[i];
  586.     for (i=0;i<num_coord;i++)
  587.         if (x2_coord[i]>dv)
  588.             dv=x2_coord[i];
  589.     dv=(x_size-dv)/2;
  590.     for (i=0;i<num_coord;i++)
  591.         x1_coord[i]+=dv;
  592.     for (i=0;i<num_coord;i++)
  593.         x2_coord[i]+=dv;
  594.     dv=0.0;
  595.     for (i=0;i<num_coord;i++)
  596.         if (y1_coord[i]>dv)
  597.             dv=y1_coord[i];
  598.     for (i=0;i<num_coord;i++)
  599.         if (y2_coord[i]>dv)
  600.             dv=y2_coord[i];
  601.     dv=(y_size-dv)/2;
  602.     for (i=0;i<num_coord;i++)
  603.         y1_coord[i]+=dv;
  604.     for (i=0;i<num_coord;i++)
  605.         y2_coord[i]+=dv;
  606.     if (display_count)
  607.         {
  608.         if (display_rotate && display_color>2)
  609.             rotate_direction=rand()%3;
  610.         else
  611.             rotate_direction=0;
  612.         while (1)
  613.             {
  614.             _bios_timeofday(_TIME_GETCLOCK,¤t_timer);
  615.             ticks=current_timer-display_timer;
  616.             if (ticks<0)
  617.                 ticks+=1573040;
  618.             if (kbhit())
  619.                 {
  620.                 while (kbhit())
  621.                     getch();
  622.                 _setvideomode(_DEFAULTMODE);
  623.                 exit(0);
  624.                 }
  625.             if (ticks>60)
  626.                 break;
  627.             if (ticks>36)
  628.                 {
  629.                 switch (rotate_direction)
  630.                     {
  631.                     case 0:
  632.                         break;
  633.                     case 1:
  634.                         display_palette[display_color]=display_palette[0];
  635.                         memmove(&display_palette[0],&display_palette[1],display_color*sizeof(display_palette[0]));
  636.                         for (i=0;i<display_color;i++)
  637.                             _remappalette(i+1,display_palette[i]);
  638.                         break;
  639.                     case 2:
  640.                         memmove(&display_palette[1],&display_palette[0],display_color*sizeof(display_palette[0]));
  641.                         display_palette[0]=display_palette[display_color];
  642.                         for (i=0;i<display_color;i++)
  643.                             _remappalette(i+1,display_palette[i]);
  644.                         break;
  645.                     }
  646.                 }
  647.             do
  648.                 {
  649.                 _bios_timeofday(_TIME_GETCLOCK,&delay_timer);
  650.                 } while (delay_timer==current_timer);
  651.             }
  652.         }
  653.     _setcolor(0);
  654.     switch (rand()%3)
  655.         {
  656.         case 0:
  657.             for (i=0;i<display_count;i++)
  658.                 {
  659.                 _moveto(display_x1[i],display_y1[i]);
  660.                 _lineto(display_x2[i],display_y2[i]);
  661.                 }
  662.             break;
  663.         case 1:
  664.             for (i=display_count-1;i>=0;i--)
  665.                 {
  666.                 _moveto(display_x1[i],display_y1[i]);
  667.                 _lineto(display_x2[i],display_y2[i]);
  668.                 }
  669.             break;
  670.         case 2:
  671.             for (i=display_count-1;i>=0;i--)
  672.                 {
  673.                 j=rand()%(i+1);
  674.                 _moveto(display_x1[j],display_y1[j]);
  675.                 _lineto(display_x2[j],display_y2[j]);
  676.                 display_x1[j]=display_x1[i];
  677.                 display_x2[j]=display_x2[i];
  678.                 display_y1[j]=display_y1[i];
  679.                 display_y2[j]=display_y2[i];
  680.                 }
  681.             break;
  682.         }
  683.     if (max_color>1)
  684.         for (i=0;i<num_color;i++)
  685.             _remappalette(i+1,current_palette[i]);
  686.     for (i=0;i<num_coord;i++)
  687.         {
  688.         display_x1[i]=(short)x1_coord[i];
  689.         display_x2[i]=(short)x2_coord[i];
  690.         display_y1[i]=(short)y1_coord[i];
  691.         display_y2[i]=(short)y2_coord[i];
  692.         _setcolor(line_color[i]+1);
  693.         _moveto(display_x1[i],display_y1[i]);
  694.         _lineto(display_x2[i],display_y2[i]);
  695.         }
  696.     _bios_timeofday(_TIME_GETCLOCK,&display_timer);
  697.     memcpy(display_palette,current_palette,sizeof(current_palette));
  698.     display_color=num_color;
  699.     display_count=num_coord;
  700.     display_rotate=req_rotate;
  701.     num_coord=0;
  702.     }
  703.