home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / unix / emx / test / graph.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-02  |  12.3 KB  |  612 lines

  1. /* graph.c (emx+gcc) */
  2.  
  3. /* Test graphics library */
  4.  
  5. /* Usage: graph */
  6.  
  7. /* Keyboard control: */
  8.  
  9. /*   RETURN     Move to next test                               */
  10. /*   ESC        Quit                                            */
  11. /*   SPACE      Pause (type SPACE to continue or ESC to quit)   */
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <signal.h>
  17. #include <setjmp.h>
  18. #include <getopt.h>
  19. #include <limits.h>
  20. #include <conio.h>
  21. #include <graph.h>
  22.  
  23. #define FALSE 0
  24. #define TRUE  1
  25.  
  26. static int pal_mode;
  27. static int wait_flag;
  28.  
  29. static char pal_1[3*255*2];
  30. static int pal_1_idx;
  31.  
  32. static char pal_2[3*255];
  33. static int color_2[3];
  34. static int dir_2[3];
  35.  
  36. static char pal[3*256];
  37.  
  38. /* Return a random number between 0 and n-1.  If n is not a power of two, */
  39. /* the return value is slightly less random than expected at first sight. */
  40. /* Better results can be achieved by discarding values returned by rand() */
  41. /* which are greater than or equal to n * ((RAND_MAX+1) / n).  Of course, */
  42. /* this doesn't matter with this program.                                 */
  43.  
  44. #define RND(n) (rand () % (n))
  45.  
  46. #define SLEEP2_MIN 500
  47.  
  48. static unsigned loops_per_second;
  49. static unsigned loops;
  50. static unsigned volatile counter;
  51. static jmp_buf alarm_jmp;
  52.  
  53. static void alarm_handler (int sig)
  54. {
  55.   longjmp (alarm_jmp, 1);
  56. }
  57.  
  58. static void init_waste_time (void)
  59. {
  60.   loops_per_second = ULONG_MAX;
  61.   if (setjmp (alarm_jmp) != 0)
  62.     loops_per_second = counter;
  63.   else
  64.     {
  65.       counter = 0;
  66.       signal (SIGALRM, alarm_handler);
  67.       alarm (1);
  68.       for (counter = 0; counter < loops_per_second; ++counter)
  69.         ;
  70.     }
  71. }
  72.  
  73.  
  74. static void waste_time (unsigned millisec)
  75. {
  76.   if (millisec >= SLEEP2_MIN)
  77.     _sleep2 (millisec);
  78.   else
  79.     {
  80.       loops = (loops_per_second * millisec) / 1000;
  81.       for (counter = 0; counter < loops; ++counter)
  82.         ;
  83.     }
  84. }
  85.  
  86.  
  87. static void kchar (int c)
  88. {
  89.   if (c == 0x1b)
  90.     {
  91.       g_mode (G_MODE_OFF);
  92.       exit (0);
  93.     }
  94.   else if (c == ' ')
  95.     {
  96.       c = getch ();
  97.       if (c == 0x1b)
  98.         {
  99.           g_mode (G_MODE_OFF);
  100.           exit (0);
  101.         }
  102.     }
  103. }
  104.  
  105.  
  106. static void kwait (void)
  107. {
  108.   int c;
  109.  
  110.   do
  111.     {
  112.       c = getch ();
  113.       kchar (c);
  114.     } while (c == ' ');
  115. }
  116.  
  117.  
  118. static int khit_counter = 0;
  119.  
  120. static int khit (void)
  121. {
  122.   int c;
  123.  
  124.   ++khit_counter;
  125.   if (khit_counter < 8)
  126.     return (0);
  127.   khit_counter = 0;
  128.   c = _read_kbd (0, 0, 0);
  129.   if (c == -1)
  130.     return (0);
  131.   kchar (c);
  132.   return (c != ' ');
  133. }
  134.  
  135.  
  136. static void test_1 (void)
  137. {
  138.   int x, y;
  139.  
  140.   for (x = 0; x < g_xsize; ++x)
  141.     {
  142.       g_lock ();
  143.       for (y = 0; y < g_ysize; ++y)
  144.         g_set (x, y, x+y);
  145.       g_unlock ();
  146.     }
  147.   kwait ();
  148. }
  149.  
  150.  
  151. static void test_4 (void)
  152. {
  153.   int c1, c2, c3, c4;
  154.   int x, y;
  155.  
  156.   c1 = G_BLUE; c2 = G_GREEN; c3 = G_CYAN; c4 = G_RED;
  157.   g_clear (G_BLACK);
  158.   for (x = 0; x < g_xsize; x += 5)
  159.     g_line (x, 0, g_xsize/2, g_ysize/2, c1);
  160.   for (y = 0; y < g_ysize; y += 5)
  161.     g_line (g_xsize-1, y, g_xsize/2, g_ysize/2, c2);
  162.   for (x = g_xsize-1; x >= 0; x -= 5)
  163.     g_line (x, g_ysize-1, g_xsize/2, g_ysize/2, c3);
  164.   for (y = g_ysize-1; y >= 0; y -= 5)
  165.     g_line (0, y, g_xsize/2, g_ysize/2, c4);
  166.   kwait ();
  167. }
  168.  
  169.  
  170. static void test_5 (void)
  171. {
  172.   int x, y;
  173.  
  174.   g_clear (G_BLACK);
  175.   for (y = 0; y < g_ysize; ++y)
  176.     g_line (0, 0, g_xsize-1, y, y);
  177.   for (x = g_xsize-1; x >= 0; --x)
  178.     g_line (0, 0, x, g_ysize-1, x);
  179.   kwait ();
  180. }
  181.  
  182.  
  183. static void test_6 (void)
  184. {
  185.   g_clear (G_BLACK);
  186.   do
  187.     {
  188.       g_line (RND (g_xsize), RND (g_ysize), RND (g_xsize), RND (g_ysize),
  189.               RND (g_colors));
  190.     } while (!khit ());
  191. }
  192.  
  193.  
  194. static void test_7 (void)
  195. {
  196.   int y;
  197.  
  198.   g_clear (G_BLACK);
  199.   for (y = 0; y*3 < g_xsize && y < g_ysize; ++y)
  200.     g_hline (y, y, y*3, G_WHITE);
  201.   kwait ();
  202. }
  203.  
  204.  
  205. static void test_8 (void)
  206. {
  207.   int x;
  208.  
  209.   g_clear (G_BLACK);
  210.   for (x = 0; x*3 < g_ysize && x < g_xsize; ++x)
  211.     g_vline (x, x, x*3, G_WHITE);
  212.   kwait ();
  213. }
  214.  
  215.  
  216. static void test_10 (void)
  217. {
  218.   g_clear (G_BLACK);
  219.   do
  220.     {
  221.       g_box (RND (g_xsize), RND (g_ysize),
  222.              RND (g_xsize), RND (g_ysize),
  223.              RND (g_colors), G_OUTLINE);
  224.     } while (!khit ());
  225. }
  226.  
  227.  
  228. static void test_11 (void)
  229. {
  230.   g_clear (G_BLACK);
  231.   do
  232.     {
  233.       g_box (RND (g_xsize), RND (g_ysize),
  234.              RND (g_xsize), RND (g_ysize),
  235.              RND (g_colors), G_FILL);
  236.     } while (!khit ());
  237. }
  238.  
  239.  
  240. static void test_19 (void)
  241. {
  242.   int mx, my, rx, ry, fill, cn;
  243.  
  244.   for (fill = 0; fill <= 1; ++fill)
  245.     {
  246.       g_clear (G_BLACK);
  247.       if (fill == 0)
  248.         cn = g_colors-1;
  249.       else
  250.         cn = g_colors;
  251.       do
  252.         {
  253.           mx = RND (g_xsize);
  254.           my = RND (g_ysize);
  255.           rx = 20 + RND (g_xsize/2);
  256.           ry = 10 + RND (g_ysize/2);
  257.           if (mx+rx < g_xsize && mx-rx > 0 && my+ry < g_ysize && my-ry > 0)
  258.             g_ellipse (mx, my, rx, ry, 1 + RND (cn), fill);
  259.         } while (!khit ());
  260.     }
  261. }
  262.  
  263.  
  264. #define MAX_VERT 20
  265.  
  266. static void test_23 (void)
  267. {
  268.   int i, n, x[MAX_VERT], y[MAX_VERT];
  269.  
  270.   g_clear (G_BLACK);
  271.   do
  272.     {
  273.       n = 0;
  274.       for (i = 0; i < 2*(MAX_VERT-3); ++i)
  275.         n += RND (2);
  276.       n = 3 + abs (n - (MAX_VERT-3));
  277.       for (i = 0; i < n; ++i)
  278.         {
  279.           x[i] = RND (g_xsize);
  280.           y[i] = RND (g_ysize);
  281.         }
  282.       g_polygon (x, y, n, 1 + RND (g_colors-1), G_FILL);
  283.     } while (!khit ());
  284. }
  285.  
  286.  
  287. static void init_pal_1 (void)
  288. {
  289.   int i, j;
  290.   unsigned char func[255];
  291.  
  292.   for (j = 0; j <= 127; ++j)
  293.     {
  294.       func[j] = (char)(j/2);
  295.       func[254-j] = (char)(j/2);
  296.     }
  297.   for (i = 0; i < 255; ++i)
  298.     {
  299.       pal_1[3*i+0] = func[(i+0*85)%255];
  300.       pal_1[3*i+1] = func[(i+1*85)%255];
  301.       pal_1[3*i+2] = func[(i+2*85)%255];
  302.     }
  303.   memcpy (pal_1+3*255, pal_1, 3*255);
  304.   pal_1_idx = 1;
  305. }
  306.  
  307.  
  308. static void make_pal_1 (void)
  309. {
  310.   memcpy (pal+3, pal_1 + pal_1_idx * 3, 3*255);
  311.   ++pal_1_idx;
  312.   if (pal_1_idx > 254)
  313.     pal_1_idx -= 255;
  314. }
  315.  
  316.  
  317. static void init_pal_2 (void)
  318. {
  319.   int i;
  320.  
  321.   memset (pal_2, 0, 3*255);
  322.   for (i = 0; i < 3; ++i)
  323.     {
  324.       dir_2[i] = 1;
  325.       color_2[i] = 0;
  326.     }
  327. }
  328.  
  329.  
  330. static void make_pal_2 (void)
  331. {
  332.   int d, i;
  333.  
  334.   memcpy (pal+3, pal_2, 3*255);
  335.   memmove (pal_2, pal_2+3, 3*254);
  336.   d = 3 * 254;
  337.   pal_2[d+0] = (char)color_2[0];
  338.   pal_2[d+1] = (char)color_2[1];
  339.   pal_2[d+2] = (char)color_2[2];
  340.   for (i = 0; i < 3; ++i)
  341.     {
  342.       color_2[i] += dir_2[i];
  343.       if (color_2[i] < 0 || color_2[i] > 63)
  344.         {
  345.           dir_2[i] = -dir_2[i];
  346.           color_2[i] += dir_2[i];
  347.         }
  348.       else
  349.         break;
  350.     }
  351. }
  352.  
  353.  
  354. static void set_pal (void)
  355. {
  356.   g_vgapal (pal, 0, 256, wait_flag);
  357. }
  358.  
  359.  
  360. static void make_pal (void)
  361. {
  362.   switch (pal_mode)
  363.     {
  364.     case 1:
  365.       make_pal_1 ();
  366.       set_pal ();
  367.       break;
  368.     case 2:
  369.       make_pal_2 ();
  370.       set_pal ();
  371.       break;
  372.     }
  373. }
  374.  
  375.  
  376. static void pal_demo (unsigned millisec)
  377. {
  378.   while (!khit ())
  379.     {
  380.       make_pal ();
  381.       waste_time (millisec);
  382.     }
  383. }
  384.  
  385.  
  386. static void demo_1 (unsigned millisec)
  387. {
  388.   int a, color, h, k, m, n, r, s, w, x1, x2, xv1, xv2, y1, y2, yv1, yv2, z;
  389.  
  390.   w = g_xsize / 2;
  391.   h = g_ysize / 2;
  392.   if (g_ysize < w)
  393.     z = g_ysize;
  394.   else
  395.     z = w;
  396.   k = (z-10)/2;
  397.   r = z / 30;
  398.   s = r / 2;
  399.   m = 20;
  400.   for (;;)
  401.     {
  402.       g_clear (G_BLACK);
  403.       n = 3 * (g_ysize / 2 + RND (g_ysize));
  404.       x1 = 1 + RND (k-1);
  405.       y1 = 1 + RND (k-1);
  406.       x2 = 1 + RND (k-1);
  407.       y2 = 1 + RND (k-1);
  408.       a = 0;
  409.       for (;;)
  410.         {
  411.           if (khit ())
  412.             return;
  413.           if (a <= 0)
  414.             {
  415.               xv1 = RND (r) - s;
  416.               yv1 = RND (r) - s;
  417.               xv2 = RND (r) - s;
  418.               yv2 = RND (r) - s;
  419.               a = 1 + RND (m -1);
  420.               color = 1 + RND (g_colors - 1);
  421.             }
  422.           g_lock ();
  423.           g_line (w+2*x1, h-y1, w+2*x2, h-y2, color);
  424.           g_line (w-2*y1, h+x1, w-2*y2, h+x2, color);
  425.           g_line (w-2*x1, h-y1, w-2*x2, h-y2, color);
  426.           g_line (w-2*y1, h-x1, w-2*y2, h-x2, color);
  427.           g_line (w-2*x1, h+y1, w-2*x2, h+y2, color);
  428.           g_line (w+2*y1, h-x1, w+2*y2, h-x2, color);
  429.           g_line (w+2*x1, h+y1, w+2*x2, h+y2, color);
  430.           g_line (w+2*y1, h+x1, w+2*y2, h+x2, color);
  431.           g_unlock ();
  432.           if (n == 1)
  433.             break;
  434.           --a;
  435.           if (n > 0)
  436.             --n;
  437.           waste_time (millisec); /* This demo looks better when slowed down */
  438.           x1 = (x1+xv1) % k;
  439.           y1 = (y1+yv1) % k;
  440.           x2 = (x2+xv2) % k;
  441.           y2 = (y2+yv2) % k;
  442.         }
  443.     }
  444. }
  445.  
  446.  
  447. static void demo_2 (unsigned millisec)
  448. {
  449.   int i, x, y, c, d, k, n, m;
  450.   static int inc_x[4] = {1, 0, -1,  0};
  451.   static int inc_y[4] = {0, 1,  0, -1};
  452.  
  453.   c = 1; d = 0; n = 16; m = 1;
  454.   x = 0 - inc_x[d];
  455.   y = 0 - inc_y[d];
  456.   k = n;
  457.   for (i = 0; i < 255; ++i)
  458.     {
  459.       x += inc_x[d]; y += inc_y[d];
  460.       g_box (x*20, y*12, (x+1)*20-1, (y+1)*12-1, c, G_FILL);
  461.       if (k <= 1)
  462.         {
  463.           d = (d+1) % 4;
  464.           --m;
  465.           if (m == 0)
  466.             {
  467.               --n; m = 2;
  468.             }
  469.           k = n;
  470.         }
  471.       else
  472.         --k;
  473.       ++c;
  474.     }
  475.   pal_demo (millisec);
  476. }
  477.  
  478.  
  479. static void demo_3 (unsigned millisec)
  480. {
  481.   int i;
  482.  
  483.   for (i = 0; i < 256; ++i)
  484.     g_vline (i, 0, g_ysize-1, i);
  485.   pal_demo (millisec);
  486. }
  487.  
  488.  
  489. static void usage (void)
  490. {
  491.   fputs ("Usage: graph [-d#] [-p#] [-s#] [-w]\n\n", stderr);
  492.   fputs ("-d#    Select demo mode [0]:\n", stderr);
  493.   fputs ("         -d0  test mode\n", stderr);
  494.   fputs ("         -d1  kaleidoscope demo\n", stderr);
  495.   fputs ("         -d2  palette demo (spiral)\n", stderr);
  496.   fputs ("         -d3  palette demo (band)\n", stderr);
  497.   fputs ("-p#    Select palette [0]:\n", stderr);
  498.   fputs ("         -p0  default palette\n", stderr);
  499.   fputs ("         -p1  smooth sequence of hues\n", stderr);
  500.   fputs ("         -p2  smooth sequence of all colors\n", stderr);
  501.   fputs ("-s#    Set delay (# milliseconds) for demo modes [6]\n", stderr);
  502.   fputs ("-w     Wait for vertical retrace when modifying palette\n", stderr);
  503.   exit (1);
  504. }
  505.  
  506.  
  507. int main (int argc, char *argv[])
  508. {
  509.   int c, demo_mode, delay;
  510.   char *p;
  511.  
  512.   demo_mode = 0; pal_mode = 0; delay = 6; wait_flag = FALSE;
  513.   while ((c = getopt (argc, argv, "d:p:s:w")) != EOF)
  514.     switch (c)
  515.       {
  516.       case 'd':
  517.         errno = 0;
  518.         demo_mode = strtol (optarg, &p, 0);
  519.         if (errno != 0 || *p != 0 || demo_mode < 0 || demo_mode > 3)
  520.           usage ();
  521.         break;
  522.       case 'p':
  523.         errno = 0;
  524.         pal_mode = strtol (optarg, &p, 0);
  525.         if (errno != 0 || pal_mode < 1 || pal_mode > 2)
  526.           usage ();
  527.         break;
  528.       case 's':
  529.         errno = 0;
  530.         delay = strtol (optarg, &p, 0);
  531.         if (errno != 0 || *p != 0)
  532.           usage ();
  533.         break;
  534.       case 'w':
  535.         wait_flag = TRUE;
  536.         break;
  537.       default:
  538.         usage ();
  539.       }
  540.   if (optind < argc)
  541.     usage ();
  542.   memset (pal, 0, 3*256);
  543.   switch (pal_mode)
  544.     {
  545.     case 1:
  546.       init_pal_1 ();
  547.       break;
  548.     case 2:
  549.       switch (demo_mode)
  550.         {
  551.         case 0:
  552.           fputs ("-p2 should not be used with -d0\n", stderr);
  553.           exit (1);
  554.         }
  555.       init_pal_2 ();
  556.       break;
  557.     default:
  558.       switch (demo_mode)
  559.         {
  560.         case 2:
  561.         case 3:
  562.           fprintf (stderr, "-d%d should not be used with -p0\n", demo_mode);
  563.           exit (1);
  564.         }
  565.     }
  566.   switch (demo_mode)
  567.     {
  568.     case 1:
  569.     case 2:
  570.     case 3:
  571.       if (delay < SLEEP2_MIN)
  572.         {
  573.           puts ("Please wait..."); fflush (stdout);
  574.           init_waste_time ();
  575.         }
  576.       break;
  577.     }
  578.   if (!g_mode (G_MODE_VGA_L))
  579.     {
  580.       fputs ("Cannot switch to graphics mode\n", stderr);
  581.       return (1);
  582.     }
  583.   make_pal ();
  584.   switch (demo_mode)
  585.     {
  586.     case 0:
  587.       test_1 ();
  588.       test_4 ();
  589.       test_5 ();
  590.       test_6 ();
  591.       test_7 ();
  592.       test_8 ();
  593.       test_10 ();
  594.       test_11 ();
  595.       test_19 ();
  596.       test_23 ();
  597.       demo_1 (0);
  598.       break;
  599.     case 1:
  600.       demo_1 (delay);
  601.       break;
  602.     case 2:
  603.       demo_2 (delay);
  604.       break;
  605.     case 3:
  606.       demo_3 (delay);
  607.       break;
  608.     }
  609.   g_mode (G_MODE_OFF);
  610.   return (0);
  611. }
  612.