home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / extra18 / bars / bar.c next >
Encoding:
C/C++ Source or Header  |  1991-12-06  |  9.4 KB  |  324 lines

  1. /* ------------------------------------------------- */
  2. /*                       BAR.C                       */
  3. /*        (C) 1991 Georg Pohl & DMV-Verlag           */
  4. /*   Modul zum Zeichnen eines Fortschritts-Graphen   */
  5. /*         Sprache: Turbo C(++), Borland C++         */
  6. /* ------------------------------------------------- */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <dos.h>
  11. #include <conio.h>
  12. #include <string.h>
  13.  
  14.  
  15. #define XY(x, y)   ((y) - 1) * 160 + ((x) - 1) * 2
  16. #define WX         (18)
  17. #define WY         (8)
  18. #define WWIDE      (46)
  19. #define WHIGHT     (6)
  20. #define WCOLOR     (BLUE + (CYAN << 4))
  21. #define BCOLOR     (DARKGRAY + (BLACK << 4))
  22. #define SHADOW     (DARKGRAY + (BLACK << 4))
  23. #define TIME_DIFF  (5)
  24.  
  25. typedef struct
  26. {
  27.   short initialized;      /* Flag: "Grafik zeichnen" */
  28.   long  max,              /* Max. Anzahl Schritte    */
  29.         last_delta;       /* Rechenfeld              */
  30.   char  *buffer,          /* Buffer für Bildschirm   */
  31.         *title,           /* Titel-Zeile             */
  32.         *line1,           /* 1. Textzeile            */
  33.         *line2;           /* 2. Textzeile            */
  34.   short restore;          /* ursprüngliche Werte     */
  35.                           /* wieder herstellen       */
  36. } BAR;
  37.  
  38. /* ------------------------------------------------- */
  39. /* Die hier vereinbarten Konstanten können extern    */
  40. /* geändert werden (!)                               */
  41.  
  42. int  wx        = 18,
  43.      wy        = 8,
  44.      wwide     = 46,
  45.      whight    = 6,
  46.      wcolor    = BLUE + (CYAN << 4),
  47.      bcolor    = CYAN + (BLUE << 4),
  48.      shadow    = DARKGRAY + (BLACK << 4);
  49. long time_diff = 5;
  50.  
  51. long far *sys_ticks = (long far *)0x0040006CL;
  52. char far *scr_mode  = (char far *)0x00400049L;
  53. char far *scr       = NULL;
  54.  
  55. static   barwide    = 0;
  56.  
  57. /* ------------------------------------------------- */
  58. /* Ein Fortschritts-Graph wird initialisiert. Dabei  */
  59. /* werden die übergebenen Werte in die neue Struktur */
  60. /* kopiert.                                          */
  61. /* Es wird noch keine Aktion ausgeführt. Der Bild-   */
  62. /* schirm bleibt unverändert.                        */
  63. /* ------------------------------------------------- */
  64. BAR * init(const char *title,
  65.            const char *line1,
  66.            const char *line2,
  67.            const long max,
  68.            short      restore)
  69. {
  70.   BAR * tmp;
  71.   int   size;
  72.  
  73.         /* Pointer auf den Bildschirmspeicher setzen */
  74.   if (*scr_mode == 7)
  75.     scr = (char *) MK_FP(0xB000, 0);
  76.   else
  77.     scr = (char *) MK_FP(0xB800, 0);
  78.  
  79.   size = (wx * (whight + 1) * (wwide + 2)) << 1;
  80.   if ((tmp = (BAR *)malloc(sizeof(BAR))) == NULL)
  81.     return(NULL);
  82.  
  83.   tmp->buffer = (char *) malloc(size);
  84.   if (tmp->buffer == NULL)
  85.   {
  86.     free(tmp);
  87.     return(NULL);
  88.   }
  89.  
  90.   tmp->title = strdup(title);
  91.   if (strlen(tmp->title) > wwide - 2)
  92.     tmp->title[wwide - 3] = 0;
  93.  
  94.   tmp->line1 = strdup(line1);
  95.   if (strlen(tmp->line1) > wwide - 2)
  96.     tmp->line1[wwide - 3] = 0;
  97.  
  98.   tmp->line2 = strdup(line2);
  99.   if (strlen(tmp->line2) > wwide - 2)
  100.     tmp->line2[wwide - 3] = 0;
  101.  
  102.   tmp->max = max;
  103.   tmp->last_delta = (max == 0L ? 0L : -1L);
  104.   tmp->initialized = 0;
  105.   tmp->restore = restore;
  106.   barwide = (wwide - 2);
  107.  
  108.   return(tmp);
  109. }
  110.  
  111. /* ------------------------------------------------- */
  112. /* Ein Bereich des Bildschirm soll gelöscht werden.  */
  113. /* Um keine bestehenden Windows zu zerstören oder    */
  114. /* Cursorposition und Farbe zu ändern, wird mit      */
  115. /* Interrupt 0x10, Funktion 6 gearbeitet.            */
  116. /* ------------------------------------------------- */
  117. void clear_window(int x1,
  118.                   int y1,
  119.                   int x2,
  120.                   int y2,
  121.                   int color)
  122. {
  123.   union REGS regs;
  124.  
  125.   regs.x.ax = 0x0600;
  126.   regs.h.bh = color;
  127.   regs.x.cx = ((y1 - 1) << 8) + (x1 - 1);
  128.   regs.x.dx = ((y2 - 1) << 8) + (x2 - 1);
  129.   int86(0x10, ®s, ®s);
  130. }
  131.  
  132.  
  133. /* ------------------------------------------------- */
  134. /* Ein String wird ab der Koordinate (x/y) direkt in */
  135. /* den Bildschirmspeicher geschrieben.               */
  136. /* ------------------------------------------------- */
  137. void draw_string(int x, int y, char *s)
  138. {
  139.   for (;*s; s++,x++)
  140.     *(scr + XY(x, y)) = *s;
  141. }
  142.  
  143.  
  144. /* ------------------------------------------------- */
  145. /* Mit dieser Funktion wird beim ersten Aufruf von   */
  146. /* show_bar(...) das Fenster erstellt, in dem der    */
  147. /* Graph gezeigt wird. Dabei werden die Werte wx, wy,*/
  148. /* wwide und whight verwendet, die auch extern geän- */
  149. /* dert werden können. Aus Geschwindigkeitsgründen   */
  150. /* wird auf eine Überprüfung dieser Daten verzichtet.*/
  151. /* ------------------------------------------------- */
  152. BAR *draw_bar_ground(BAR *bar)
  153. {
  154.   register int n, middle;
  155.  
  156.                            /* Bildschirm sichern ... */
  157.   gettext(wx, wy, wx + wwide + 2,
  158.           wy + whight + 1, bar->buffer);
  159.  
  160.                 /* Fenster unter dem Bar löschen ... */
  161.   clear_window(wx, wy, wx + wwide,
  162.                wy + whight, wcolor);
  163.  
  164.               /* Box zeichen: horizontale Linien ... */
  165.   for (n = wx + 1; n < wx + wwide; n++)
  166.   {
  167.     *(scr + XY(n, wy))   = 0xC4;
  168.     *(scr + XY(n, wy + whight)) = 0xC4;
  169.   }
  170.  
  171.                /* Box zeichnen: vertikale Linien ... */
  172.   for (n = wy+1; n < wy + whight; n++)
  173.   {
  174.     *(scr + XY(wx, n))   = 0xB3;
  175.     *(scr + XY(wx + wwide, n)) = 0xB3;
  176.   }
  177.  
  178.                      /* Box zeichnen: Alle Ecken ... */
  179.   *(scr + XY(wx, wy)) = 0xDA;
  180.   *(scr + XY(wx+wwide, wy)) = 0xBF;
  181.   *(scr + XY(wx, wy + whight)) = 0xC0;
  182.   *(scr + XY(wx+wwide, wy + whight)) = 0xD9;
  183.  
  184.                     /* Box mit Schatten versehen ... */
  185.   if (*scr_mode == 7)
  186.   {
  187.     /* Monochrom-Karte */
  188.     for (n = wx + 2; n <= wx + wwide + 2; n++)
  189.     {
  190.       *(scr + XY(n, wy + whight + 1)) = 0xB0;
  191.       *(scr + XY(n, wy + whight + 1) +1) = wcolor;
  192.     }
  193.     for (n = wy + 1; n <= wy + whight; n++)
  194.     {
  195.       *(scr + XY(wx + wwide + 1, n)) = 0xB0;
  196.       *(scr + XY(wx + wwide + 1, n) +1) = wcolor;
  197.       *(scr + XY(wx + wwide + 2, n)) = 0xB0;
  198.       *(scr + XY(wx + wwide + 2, n) +1) = wcolor;
  199.     }
  200.   }
  201.   else
  202.   {
  203.     for (n = wx + 2; n <= wx + wwide + 2; n++)
  204.       *(scr + XY(n, wy + whight + 1) + 1)=shadow;
  205.     for (n = wy + 1; n <= wy + whight; n++)
  206.     {
  207.       *(scr + XY(wx + wwide + 1, n) + 1) = shadow;
  208.       *(scr + XY(wx + wwide + 2, n) + 1) = shadow;
  209.     }
  210.   }
  211.  
  212.                    /* Zeichnen der "Bar-Legende" ... */
  213.   for (n = 1; n < wwide; n++)
  214.     if (n % 5)
  215.       *(scr + XY(wx + n, wy + 5)) = 0xFA;
  216.     else
  217.       *(scr + XY(wx + n, wy + 5)) = 0x07;
  218.  
  219.   middle = wx + ((wwide - strlen(bar->title)+1) >> 1);
  220.   draw_string(middle, wy, bar->title);
  221.   middle = wx + ((wwide - strlen(bar->line1)+1) >> 1);
  222.   draw_string(middle, wy + 2, bar->line1);
  223.   middle = wx + ((wwide - strlen(bar->line2)+1) >> 1);
  224.   draw_string(middle, wy + 3, bar->line2);
  225.  
  226.   return(bar);
  227. }
  228.  
  229.  
  230. /* ------------------------------------------------- */
  231. /* Diese Funktion wird immer aufgerufen, wenn eine   */
  232. /* Veränderung der Anzeige gewünscht wird.           */
  233. /* ------------------------------------------------- */
  234. void show_bar(BAR * bar, long count)
  235. {
  236.   long        delta,            /* Rechenfeld   */
  237.               n;                /* Schleifenz.  */
  238.   static long last_shown;
  239.  
  240.   if (*scr_mode == 7)
  241.   {
  242.     bcolor = BLACK + (LIGHTGRAY << 4);
  243.     wcolor = WHITE + (BLACK << 4);
  244.   }
  245.  
  246.                    /* Fenster schon gezeichnet ? ... */
  247.   if (!bar ->initialized)
  248.   {
  249.     bar = draw_bar_ground(bar);
  250.     bar->initialized = 1;
  251.     last_shown = 0L;
  252.   }
  253.  
  254.        /* Man wußte nicht, wieviel zu bearbeiten war */
  255.   if (bar->max == 0L)
  256.   {
  257.     if (*sys_ticks - last_shown >= time_diff)
  258.     {
  259.       if (bar->last_delta == 0L)
  260.         bar -> last_delta = wx + 1;
  261.       else
  262.         *(scr + XY((int)bar -> last_delta++, wy+5)+1) =
  263.          wcolor;
  264.       if (bar->last_delta == wx + wwide)
  265.         bar->last_delta = wx + 1;
  266.       *(scr + XY((int)bar -> last_delta, wy + 5) + 1) =
  267.         bcolor;
  268.       last_shown = *sys_ticks;
  269.     }
  270.   return;
  271.   }
  272.                               /* Delta berechnen ... */
  273.   delta = count * barwide / bar -> max;
  274.   if (delta > bar->max)       /* ggf. verkürzen      */
  275.     delta = bar->max;
  276.  
  277.   if (delta == bar->last_delta)
  278.     return;
  279.   else
  280.     bar->last_delta = delta;     /* Wert speichern   */
  281.  
  282.     /* in einer Schleife den Graphen zeichnen ...    */
  283.   for (n = delta + 1;n; n--)
  284.     *(scr + XY(wx + (int)n, wy + 5) + 1) =
  285.       bcolor;
  286. }
  287.  
  288. /* ------------------------------------------------- */
  289. /* Diese Funktion ist aufzurufen, wenn der Prozeß,   */
  290. /* der den Graphen brauchte, beendet ist. Der alte   */
  291. /* Bildschirm wird restauriert und der Speicher, der */
  292. /* von der BAR * Variablen belegt wurde, wird wieder */
  293. /* freigegeben.                                      */
  294. /* ------------------------------------------------- */
  295. BAR *done(BAR *bar)
  296. {
  297.   puttext(wx, wy,
  298.           wx + wwide + 2, wy + whight + 1,
  299.           bar->buffer);
  300.  
  301.   if (bar->restore)
  302.   {
  303.     wx        = WX;
  304.     wy        = WY;
  305.     wwide     = WWIDE;
  306.     whight    = WHIGHT;
  307.     wcolor    = WCOLOR;
  308.     bcolor    = BCOLOR;
  309.     shadow    = SHADOW;
  310.     time_diff = TIME_DIFF;
  311.   }
  312.  
  313.   free(bar->buffer);
  314.   free(bar->title);
  315.   free(bar->line1);
  316.   free(bar->line2);
  317.   free(bar);
  318.   return(NULL);
  319. }
  320.  
  321.  
  322. /* ------------------------------------------------- */
  323. /*                   Ende von BAR.C                  */
  324.