home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------------------- */
- /* BAR.C */
- /* (C) 1991 Georg Pohl & DMV-Verlag */
- /* Modul zum Zeichnen eines Fortschritts-Graphen */
- /* Sprache: Turbo C(++), Borland C++ */
- /* ------------------------------------------------- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <conio.h>
- #include <string.h>
-
-
- #define XY(x, y) ((y) - 1) * 160 + ((x) - 1) * 2
- #define WX (18)
- #define WY (8)
- #define WWIDE (46)
- #define WHIGHT (6)
- #define WCOLOR (BLUE + (CYAN << 4))
- #define BCOLOR (DARKGRAY + (BLACK << 4))
- #define SHADOW (DARKGRAY + (BLACK << 4))
- #define TIME_DIFF (5)
-
- typedef struct
- {
- short initialized; /* Flag: "Grafik zeichnen" */
- long max, /* Max. Anzahl Schritte */
- last_delta; /* Rechenfeld */
- char *buffer, /* Buffer für Bildschirm */
- *title, /* Titel-Zeile */
- *line1, /* 1. Textzeile */
- *line2; /* 2. Textzeile */
- short restore; /* ursprüngliche Werte */
- /* wieder herstellen */
- } BAR;
-
- /* ------------------------------------------------- */
- /* Die hier vereinbarten Konstanten können extern */
- /* geändert werden (!) */
-
- int wx = 18,
- wy = 8,
- wwide = 46,
- whight = 6,
- wcolor = BLUE + (CYAN << 4),
- bcolor = CYAN + (BLUE << 4),
- shadow = DARKGRAY + (BLACK << 4);
- long time_diff = 5;
-
- long far *sys_ticks = (long far *)0x0040006CL;
- char far *scr_mode = (char far *)0x00400049L;
- char far *scr = NULL;
-
- static barwide = 0;
-
- /* ------------------------------------------------- */
- /* Ein Fortschritts-Graph wird initialisiert. Dabei */
- /* werden die übergebenen Werte in die neue Struktur */
- /* kopiert. */
- /* Es wird noch keine Aktion ausgeführt. Der Bild- */
- /* schirm bleibt unverändert. */
- /* ------------------------------------------------- */
- BAR * init(const char *title,
- const char *line1,
- const char *line2,
- const long max,
- short restore)
- {
- BAR * tmp;
- int size;
-
- /* Pointer auf den Bildschirmspeicher setzen */
- if (*scr_mode == 7)
- scr = (char *) MK_FP(0xB000, 0);
- else
- scr = (char *) MK_FP(0xB800, 0);
-
- size = (wx * (whight + 1) * (wwide + 2)) << 1;
- if ((tmp = (BAR *)malloc(sizeof(BAR))) == NULL)
- return(NULL);
-
- tmp->buffer = (char *) malloc(size);
- if (tmp->buffer == NULL)
- {
- free(tmp);
- return(NULL);
- }
-
- tmp->title = strdup(title);
- if (strlen(tmp->title) > wwide - 2)
- tmp->title[wwide - 3] = 0;
-
- tmp->line1 = strdup(line1);
- if (strlen(tmp->line1) > wwide - 2)
- tmp->line1[wwide - 3] = 0;
-
- tmp->line2 = strdup(line2);
- if (strlen(tmp->line2) > wwide - 2)
- tmp->line2[wwide - 3] = 0;
-
- tmp->max = max;
- tmp->last_delta = (max == 0L ? 0L : -1L);
- tmp->initialized = 0;
- tmp->restore = restore;
- barwide = (wwide - 2);
-
- return(tmp);
- }
-
- /* ------------------------------------------------- */
- /* Ein Bereich des Bildschirm soll gelöscht werden. */
- /* Um keine bestehenden Windows zu zerstören oder */
- /* Cursorposition und Farbe zu ändern, wird mit */
- /* Interrupt 0x10, Funktion 6 gearbeitet. */
- /* ------------------------------------------------- */
- void clear_window(int x1,
- int y1,
- int x2,
- int y2,
- int color)
- {
- union REGS regs;
-
- regs.x.ax = 0x0600;
- regs.h.bh = color;
- regs.x.cx = ((y1 - 1) << 8) + (x1 - 1);
- regs.x.dx = ((y2 - 1) << 8) + (x2 - 1);
- int86(0x10, ®s, ®s);
- }
-
-
- /* ------------------------------------------------- */
- /* Ein String wird ab der Koordinate (x/y) direkt in */
- /* den Bildschirmspeicher geschrieben. */
- /* ------------------------------------------------- */
- void draw_string(int x, int y, char *s)
- {
- for (;*s; s++,x++)
- *(scr + XY(x, y)) = *s;
- }
-
-
- /* ------------------------------------------------- */
- /* Mit dieser Funktion wird beim ersten Aufruf von */
- /* show_bar(...) das Fenster erstellt, in dem der */
- /* Graph gezeigt wird. Dabei werden die Werte wx, wy,*/
- /* wwide und whight verwendet, die auch extern geän- */
- /* dert werden können. Aus Geschwindigkeitsgründen */
- /* wird auf eine Überprüfung dieser Daten verzichtet.*/
- /* ------------------------------------------------- */
- BAR *draw_bar_ground(BAR *bar)
- {
- register int n, middle;
-
- /* Bildschirm sichern ... */
- gettext(wx, wy, wx + wwide + 2,
- wy + whight + 1, bar->buffer);
-
- /* Fenster unter dem Bar löschen ... */
- clear_window(wx, wy, wx + wwide,
- wy + whight, wcolor);
-
- /* Box zeichen: horizontale Linien ... */
- for (n = wx + 1; n < wx + wwide; n++)
- {
- *(scr + XY(n, wy)) = 0xC4;
- *(scr + XY(n, wy + whight)) = 0xC4;
- }
-
- /* Box zeichnen: vertikale Linien ... */
- for (n = wy+1; n < wy + whight; n++)
- {
- *(scr + XY(wx, n)) = 0xB3;
- *(scr + XY(wx + wwide, n)) = 0xB3;
- }
-
- /* Box zeichnen: Alle Ecken ... */
- *(scr + XY(wx, wy)) = 0xDA;
- *(scr + XY(wx+wwide, wy)) = 0xBF;
- *(scr + XY(wx, wy + whight)) = 0xC0;
- *(scr + XY(wx+wwide, wy + whight)) = 0xD9;
-
- /* Box mit Schatten versehen ... */
- if (*scr_mode == 7)
- {
- /* Monochrom-Karte */
- for (n = wx + 2; n <= wx + wwide + 2; n++)
- {
- *(scr + XY(n, wy + whight + 1)) = 0xB0;
- *(scr + XY(n, wy + whight + 1) +1) = wcolor;
- }
- for (n = wy + 1; n <= wy + whight; n++)
- {
- *(scr + XY(wx + wwide + 1, n)) = 0xB0;
- *(scr + XY(wx + wwide + 1, n) +1) = wcolor;
- *(scr + XY(wx + wwide + 2, n)) = 0xB0;
- *(scr + XY(wx + wwide + 2, n) +1) = wcolor;
- }
- }
- else
- {
- for (n = wx + 2; n <= wx + wwide + 2; n++)
- *(scr + XY(n, wy + whight + 1) + 1)=shadow;
- for (n = wy + 1; n <= wy + whight; n++)
- {
- *(scr + XY(wx + wwide + 1, n) + 1) = shadow;
- *(scr + XY(wx + wwide + 2, n) + 1) = shadow;
- }
- }
-
- /* Zeichnen der "Bar-Legende" ... */
- for (n = 1; n < wwide; n++)
- if (n % 5)
- *(scr + XY(wx + n, wy + 5)) = 0xFA;
- else
- *(scr + XY(wx + n, wy + 5)) = 0x07;
-
- middle = wx + ((wwide - strlen(bar->title)+1) >> 1);
- draw_string(middle, wy, bar->title);
- middle = wx + ((wwide - strlen(bar->line1)+1) >> 1);
- draw_string(middle, wy + 2, bar->line1);
- middle = wx + ((wwide - strlen(bar->line2)+1) >> 1);
- draw_string(middle, wy + 3, bar->line2);
-
- return(bar);
- }
-
-
- /* ------------------------------------------------- */
- /* Diese Funktion wird immer aufgerufen, wenn eine */
- /* Veränderung der Anzeige gewünscht wird. */
- /* ------------------------------------------------- */
- void show_bar(BAR * bar, long count)
- {
- long delta, /* Rechenfeld */
- n; /* Schleifenz. */
- static long last_shown;
-
- if (*scr_mode == 7)
- {
- bcolor = BLACK + (LIGHTGRAY << 4);
- wcolor = WHITE + (BLACK << 4);
- }
-
- /* Fenster schon gezeichnet ? ... */
- if (!bar ->initialized)
- {
- bar = draw_bar_ground(bar);
- bar->initialized = 1;
- last_shown = 0L;
- }
-
- /* Man wußte nicht, wieviel zu bearbeiten war */
- if (bar->max == 0L)
- {
- if (*sys_ticks - last_shown >= time_diff)
- {
- if (bar->last_delta == 0L)
- bar -> last_delta = wx + 1;
- else
- *(scr + XY((int)bar -> last_delta++, wy+5)+1) =
- wcolor;
- if (bar->last_delta == wx + wwide)
- bar->last_delta = wx + 1;
- *(scr + XY((int)bar -> last_delta, wy + 5) + 1) =
- bcolor;
- last_shown = *sys_ticks;
- }
- return;
- }
- /* Delta berechnen ... */
- delta = count * barwide / bar -> max;
- if (delta > bar->max) /* ggf. verkürzen */
- delta = bar->max;
-
- if (delta == bar->last_delta)
- return;
- else
- bar->last_delta = delta; /* Wert speichern */
-
- /* in einer Schleife den Graphen zeichnen ... */
- for (n = delta + 1;n; n--)
- *(scr + XY(wx + (int)n, wy + 5) + 1) =
- bcolor;
- }
-
- /* ------------------------------------------------- */
- /* Diese Funktion ist aufzurufen, wenn der Prozeß, */
- /* der den Graphen brauchte, beendet ist. Der alte */
- /* Bildschirm wird restauriert und der Speicher, der */
- /* von der BAR * Variablen belegt wurde, wird wieder */
- /* freigegeben. */
- /* ------------------------------------------------- */
- BAR *done(BAR *bar)
- {
- puttext(wx, wy,
- wx + wwide + 2, wy + whight + 1,
- bar->buffer);
-
- if (bar->restore)
- {
- wx = WX;
- wy = WY;
- wwide = WWIDE;
- whight = WHIGHT;
- wcolor = WCOLOR;
- bcolor = BCOLOR;
- shadow = SHADOW;
- time_diff = TIME_DIFF;
- }
-
- free(bar->buffer);
- free(bar->title);
- free(bar->line1);
- free(bar->line2);
- free(bar);
- return(NULL);
- }
-
-
- /* ------------------------------------------------- */
- /* Ende von BAR.C */
-