home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / os2 / hpgl312.zip / TO_ATARI.C < prev    next >
C/C++ Source or Header  |  1993-04-18  |  24KB  |  835 lines

  1. /*
  2.    Copyright (C) 1992 Norbert Meyer.  All rights reserved.
  3.    Distributed by Free Software Foundation, Inc.
  4.  
  5. This file is part of HP2xx.
  6.  
  7. HP2xx is distributed in the hope that it will be useful, but
  8. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  9. to anyone for the consequences of using it or for whether it serves any
  10. particular purpose or works at all, unless he says so in writing.  Refer
  11. to the GNU General Public License, Version 2 or later, for full details.
  12.  
  13. Everyone is granted permission to copy, modify and redistribute
  14. HP2xx, but only under the conditions described in the GNU General Public
  15. License.  A copy of this license is supposed to have been
  16. given to you along with HP2xx so you can know your rights and
  17. responsibilities.  It should be in a file named COPYING.  Among other
  18. things, the copyright notice and this notice must be preserved on all
  19. copies.
  20.  
  21. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  22. */
  23.  
  24. /**
  25.  ** TO_ATARI.C:  Zweite Version für einen Atari-Previewer im
  26.  **              Rahmen des HP2xx-Projektes von Heinz Werntges.
  27.  **
  28.  **              Die erste Version für einen Atari-Previewer
  29.  **              wertete jeweils die temporäre Datei aus, in der
  30.  **              zunächst in einem HP2xx-spezifischem Code alle
  31.  **              Plot-Anweisungen gesammelt werden (Diese
  32.  **              Zwischendatei wird von HP2xx benutzt, um
  33.  **              anschlie₧end daraus zum einen die HP2xx-Bitmap zu
  34.  **              erzeugen, und zum anderen um auf dieser Grundlage
  35.  **              vektororientierte Datei-Formate wie das
  36.  **              Postscript-Format zu errechnen).
  37.  **
  38.  **              Dieses Vorgehen hatte aber einen entscheidenden
  39.  **              Nachteil: Da der Vektorteil von HP2xx von Zeit zu
  40.  **              Zeit weiterentwickelt wird, mu₧te dann jeweils
  41.  **              auch der Atari-Previewer angepa₧t werden.
  42.  **
  43.  **              Daher wertet die neue Version nun nicht mehr den
  44.  **              Vektorteil des HP2xx aus. Stattdessen wird die
  45.  **              von HP2xx zur Verfügung gestellte Bitmap als
  46.  **              Berechnungsgrundlage genommen. Für die Bitmap ist
  47.  **              ein festes Format garantiert, so da₧ der
  48.  **              Previewer auf lange Sicht nicht mehr geändert
  49.  **              werden mu₧.
  50.  **
  51.  **              Der Atari-Previewer nutzt nur VDI-Zeichenbefehle.
  52.  **              Dadurch ist er zwar nicht gerade einer der
  53.  **              schnellsten, sollte aber in jeder auf dem Atari
  54.  **              verfügbaren Graphikauflösung arbeiten.
  55.  **
  56.  **              Zudem bietet der Previewer bescheidenen
  57.  **              Bedienungskomfort (Scrollen durch ein zu gro₧
  58.  **              geratenes Bild per Pfeiltasten, Hilfstext
  59.  **              abrufbar). Auf eine komplette Fensterverwaltung
  60.  **              wurde jedoch verzichtet. Dies hätte den Previewer
  61.  **              zum einen unnötig aufgebläht und zum anderen wäre
  62.  **              es schon irgendwie merkwürdig gewesen, wenn nach
  63.  **              einem rein buchstabenorientiertem Programmteil
  64.  **              auf einmal ein typisches GEM-Programm auf dem
  65.  **              Schirm erscheint.
  66.  **
  67.  **              Damit der Benutzer sich nicht so sehr mit den
  68.  **              Besonderheiten seines Bildschirms herumplagen
  69.  **              mu₧, beachtet der Atari-Previewer Bildschirm-
  70.  **              auflösungen mit sehr ungleich gro₧en Pixeln (ein
  71.  **              typischer Fall ist die mittlere Auflösung für den
  72.  **              Atari ST). Ist also in der Bitmap für die x- und
  73.  **              die y-Richtung jeweils die gleiche Auflösung
  74.  **              gewählt, so erscheint im Preview ein Kreis
  75.  **              (wenigstens so ungefähr) auch auf dem Bildschirm
  76.  **              als Kreis - unabhängig davon, ob man etwas
  77.  **              merkwürdige Graphikeigenschaften in seinem
  78.  **              Rechner hat oder nicht.
  79.  **
  80.  **              Bisher wurde der Previewer mit folgenden
  81.  **              Bildschirmauflösungen getestet (sollte aber - wie
  82.  **              gesagt - auch bei anderen Bildschirmauflösungen
  83.  **              laufen):
  84.  **
  85.  **              - ST niedrig ( 320 x 200, 16 Farben)
  86.  **
  87.  **              - ST mittel  ( 640 x 200, 4 Farben)
  88.  **
  89.  **              - ST hoch    ( 640 x 400, monochrom)
  90.  **
  91.  **              Trotz ausführlicher Test mu₧ aber darauf
  92.  **              hingewiesen werden, da₧ die Benutzung des
  93.  **              Atari-Previewer auf eigene Gefahr geschieht.
  94.  **/
  95.  
  96. /**  V. 0.00  16.05.92 NM Null-Version (nicht lauffähig)
  97.  **  V. 1.00  22.05.92 NM erste lauffähige Version
  98.  **/
  99.  
  100. /* V. 2.00
  101.    Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de)
  102.  
  103.    - Ausgaberoutine völlig umgeschrieben
  104.    - dadurch wesentlich schneller
  105.    - Farbunterstützung
  106.    - getestet auf allen Farbauflösungen des TT (incl. ST Hoch)
  107.    - Bilder werden gestreckt statt gestaucht bei nicht-quadratischen
  108.      Auflösungen (wurde wegen der Farbunterstützung nötig) */
  109.  
  110. /**
  111.  **  Standard-Header für GEM-Programme:
  112.  **/
  113.  
  114. #ifndef __PUREC__
  115. /* Standard-Namen */
  116. #include <osbind.h>
  117. #include <aesbind.h>
  118. #include <vdibind.h>
  119. #else
  120. #include <tos.h>
  121. #include <aes.h>
  122. #include <vdi.h>
  123. #endif
  124. #include <stdio.h>
  125. #include <stdlib.h>
  126.  
  127. /**
  128.  **  Header für HP2xx:
  129.  **/
  130.  
  131. #include "bresnham.h"
  132. #include "hp2xx.h"
  133.  
  134. /**
  135.  **  ergänzende Standard-Definitionen für GEM-Programme:
  136.  **/
  137.  
  138. typedef enum
  139. {                /* boolean definieren   */
  140.   FALSCH,
  141.   WAHR
  142. } boolean;
  143.  
  144. #define CON     2        /* Console (VT-52)  */
  145.  
  146. /*
  147.  *  weitere Definitionen:
  148.  */
  149.  
  150. #define CLS     fprintf(stderr,"\033E")    /* Bildschirm löschen   */
  151.  
  152.  /* Scancodes:           */
  153. #define SC_H        35        /* H    \               */
  154. #define SC_HELP     98        /* Help  >  gl. Fkt.    */
  155. #define SC_F1       59        /* F1   /               */
  156. #define SC_I        23        /* I für Info           */
  157. #define SC_Q        16        /* Q    \ Programm-     */
  158. #define SC_ESC      1        /* Esc  / abbruch       */
  159. #define SC_PF_LKS   75        /* Pfeil links          */
  160. #define SC_C_PF_LKS 115        /* Control Pfeil links  */
  161. #define SC_PF_RTS   77        /* Pfeil rechts         */
  162. #define SC_C_PF_RTS 116        /* Control Pfeil rechts */
  163. #define SC_PF_OBN   72        /* Pfeil nach oben      */
  164. #define SC_PF_UTN   80        /* Pfeil nach unten     */
  165.  
  166.  /* Sondertastenbits:    */
  167. #define KB_SHIFT_RTS        1    /* Shift-rechts         */
  168. #define KB_SHIFT_LKS        2    /* Shift-links          */
  169. #define KB_CONTROL          4    /* Control              */
  170. #define KB_ALTERNATE        8    /* Alternate            */
  171.  
  172. /*
  173.  *  globale Variablen für GEM-Programme:
  174.  */
  175.  
  176. int gl_apid;            /* Applikations-Identifikationsnummer   */
  177.  
  178. int phys_handle,        /* physikalisches Handle (GRAF_HANDLE)  */
  179.   vdi_handle;            /* VDI-Handle (V_OPENVWK)               */
  180.  
  181. int gl_hchar,            /* Höhe,                                */
  182.   gl_wchar,            /* Breite eines Standard-Zeichens       */
  183.   gl_hbox,            /* Höhe, Breite der Box um ein          */
  184.   gl_wbox;            /* Zeichen des Standard-Zeichensatzes   */
  185.  
  186. int w_text,            /* Anzahl Standard-Zeichen pro Zeile    */
  187.   h_text;            /* Anzahl Zeilen                        */
  188.  
  189. int work_in[12],        /* Parameterübergabe-Felder für         */
  190.   work_out[57],            /* VDI-Aufrufe (inkl. V_OPENVWK)        */
  191.   pxyarray[10];
  192.  
  193. int cntrl[12],            /* vom VDI und AES benutzte Parameter-  */
  194.   initin[128],            /* übergabefelder                       */
  195.   ptsin[128], intout[128], ptsout[128];
  196.  
  197. int w_screen, h_screen;        /* Größe des Schirms insgesamt          */
  198. int w_pixel, h_pixel;        /* Pixelbreite /-höhe in 1/1000 mm      */
  199. int color_max;            /* gleichzeitig verfügbare Farben       */
  200. int color_palette;        /* Anzahl Farben insgesamt              */
  201.  
  202. /**
  203.  **  Globale Variablen für den ATARI-Previewer
  204.  **/
  205.  
  206. /* Grö₧e des Schirms und Korrekturfaktoren für nicht quadratische Pixel */
  207. int rx_min, rx_max, rx_factor, ry_min, ry_max, ry_factor;
  208.  
  209. /* eine Pixelreihe auf dem Schirm */
  210. static Byte *rx_reihe;
  211.  
  212. /* Schirmausmaße nach Korrektur für nicht quadratische Pixel */
  213. int sx_max, sy_max;
  214.  
  215. /* Darzustellender Bildausschnitt nach Korrektur für
  216.    nicht quadratische Pixel */
  217. int dx_min, dx_max, dy_min, dy_max;
  218.  
  219. /* Grö₧e der Bitmap (in Pixeleinheiten) */
  220. int px_max, py_max;
  221.  
  222. /* Offset zur Umrechnung vom p- ins d-System */
  223. int ox, oy;
  224.  
  225. /**
  226.  **  Funktionsprototypen für GEM-Initialisation:
  227.  **/
  228.  
  229. boolean open_vwork (void);    /* Öffnet virtuele Workstation  */
  230. void close_vwork (void);    /* Schließt virt. Workstation   */
  231.  
  232. /**
  233.  **  HP2xx - Funktionsprototypen:
  234.  **/
  235.  
  236. void PicBuf_to_ATARI (PicBuf *, PAR *);    /* GEM-Initialisierung und  */
  237.  /* Termination (Hauptprg.)  */
  238.  
  239. void preview (PicBuf *, PAR *);    /* Vorbelegungen, Tastendrücke auswerten */
  240.  
  241. void hilfe (void);        /* Gibt Hilfstext aus       */
  242.  
  243. void info (void);        /* Bildschirmparameter-Info */
  244.  
  245. void zeichne (PicBuf *);    /* Führt Graphik aus        */
  246.  
  247. int lese_pixel (PicBuf *);    /* Liest einzeln. Pixel */
  248. void zeichne_pixelreihe (int);    /* Zeichnet Pixelreihe  */
  249.  
  250. /*------------------------------------------------------------------*/
  251.  
  252. /**
  253.  ** open_vwork:  Öffnet die Workstation, fragt wichtigste Kenndaten
  254.  **              ab
  255.  **/
  256.  
  257. boolean
  258. open_vwork (void)
  259. {
  260.   int i;
  261.  
  262.   if ((gl_apid = appl_init ()) != -1)
  263.     {
  264.  
  265.       /* phys. Handle und Standard-Zeichengrö₧e erfragen  */
  266.  
  267.       phys_handle = graf_handle (&gl_wchar, &gl_hchar, &gl_wbox,
  268.                  &gl_hbox);
  269.       vdi_handle = phys_handle;
  270.  
  271.       /* work_in vorbesetzen, virtuelle Workstation auf   */
  272.       /* Bildschirm öffnen                                */
  273.  
  274.       work_in[0] = phys_handle;    /* Handle-Nr.       */
  275.       for (i = 1; i < 10; work_in[i++] = 1);    /* alles Standard   */
  276.       work_in[10] = 2;        /* RC-Koordinaten   */
  277.       v_opnvwk (work_in, &vdi_handle, work_out);    /* Bildschirm öffnen*/
  278.  
  279.       /* Kenngrö₧en des Desktops abfragen */
  280.  
  281.       w_pixel = work_out[3];    /* Pixelbreite /-höhe       */
  282.       h_pixel = work_out[4];    /*   in 1/1000 mm           */
  283.       color_max = work_out[13];    /* gleichz.darstellb.Farb.  */
  284.       color_palette = work_out[39];    /* verfügbare Farben        */
  285.       w_screen = work_out[0] + 1;    /* Bildschirmbreite /-höhe  */
  286.       h_screen = work_out[1] + 1;    /*       in Pixeln          */
  287.       vq_chcells (vdi_handle, &h_text, &w_text);    /* in Stand.zeichen */
  288.  
  289.       /* Maus abschalten (hier kein Maus-bedienbares Programm)    */
  290.  
  291.       graf_mouse (M_OFF, NULL);
  292.  
  293.       return (WAHR);
  294.     }
  295.   else
  296.     return (FALSCH);
  297. }
  298.  
  299. /*------------------------------------------------------------------*/
  300.  
  301. /**
  302.  ** close_vwork: Schaltet die Maus wieder an,
  303.  **              schlie₧t die Workstation
  304.  **              und die Applikation
  305.  **/
  306.  
  307. void
  308. close_vwork (void)
  309. {
  310.   graf_mouse (M_ON, NULL);
  311.   v_clsvwk (vdi_handle);
  312.   appl_exit ();
  313. }
  314.  
  315. static int last_color = -1;
  316. /* Standard-Farbenbelegung wird vorausgesetzt */
  317. static int xx2vdi[8] = {WHITE, BLACK, RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW};
  318.  
  319. #ifdef __GNUC__
  320. inline
  321. #endif
  322. void
  323. set_line_color (int color)
  324. {
  325.   if (color != last_color)
  326.     {
  327.       vsl_color (vdi_handle, xx2vdi[color]);
  328.       last_color = color;
  329.     }
  330. }
  331.  
  332. /*------------------------------------------------------------------*/
  333.  
  334. /**
  335.  ** zeichne_pixelreihe:  Gibt eine Pixelreihe auf dem Schirm aus
  336.  **             mit Beachtung von ry_factor
  337.  **/
  338. void
  339. zeichne_pixelreihe (int ry)
  340. {
  341.   register int start = rx_min;    /* Beginn des Linienstücks      */
  342.   register int pos;        /* x Position                   */
  343.   int curr_color = rx_reihe[rx_min];
  344.   int ry_n;
  345.  
  346.   for (pos = rx_min + 1; pos <= rx_max; pos++)
  347.     {
  348.       if (rx_reihe[pos] != curr_color)
  349.     {
  350.       if (curr_color != xxBackground)
  351.         {
  352.           set_line_color (curr_color);
  353.           /* Linie(n) ausgeben */
  354.           for (ry_n = 0; ry_n < ry_factor; ry_n++)
  355.         {
  356.           pxyarray[0] = start;    /* x1 */
  357.           pxyarray[1] = ry + ry_n; /* y1 */
  358.           pxyarray[2] = pos - 1; /* x2 */
  359.           pxyarray[3] = ry + ry_n; /* y2 */
  360.           v_pline (vdi_handle, 2, pxyarray);
  361.         }
  362.         }
  363.       start = pos;
  364.       curr_color = rx_reihe[pos];
  365.     }
  366.     }
  367.   if (curr_color != xxBackground)
  368.     {
  369.       set_line_color (curr_color);
  370.       /* Linie(n) ausgeben */
  371.       for (ry_n = 0; ry_n < ry_factor; ry_n++)
  372.     {
  373.       pxyarray[0] = start;        /* x1 */
  374.       pxyarray[1] = ry + ry_n;    /* y1 */
  375.       pxyarray[2] = rx_max;        /* x2 */
  376.       pxyarray[3] = ry + ry_n;    /* y2 */
  377.       v_pline (vdi_handle, 2, pxyarray);
  378.     }
  379.     }
  380. }
  381.  
  382. /*------------------------------------------------------------------*/
  383.  
  384. /**
  385.  ** zeichne: Steuert das eigentliche Darstellen der Graphik
  386.  **
  387.  **/
  388.  
  389. void
  390. zeichne (PicBuf *picbuf)
  391. {
  392.   register int rx_n;        /* Zähler zum "Sammeln" von Pixeln      */
  393.   RowBuf *zeile;
  394.   int px, py;
  395.   int rx, ry;
  396.   int color_index;
  397.  
  398.   v_clrwk (vdi_handle);        /* Bildschirm löschen   */
  399.  
  400.   /* Ggf. graue / grüne Ränder am Bildschirmrand          */
  401.   if (sx_max > px_max)
  402.     {
  403.       /* seitlichen Rand zeichnen */
  404.       if (rx_min > 0)
  405.     {
  406.       /* linker Rand */
  407.       pxyarray[0] = 0;        /* x1   */
  408.       pxyarray[1] = 0;        /* y1   */
  409.       pxyarray[2] = rx_min - 1;    /* x2   */
  410.       pxyarray[3] = h_screen - 1;    /* y2   */
  411.       v_bar (vdi_handle, pxyarray);
  412.     }
  413.       if (rx_max < w_screen - 1)
  414.     {
  415.       /* rechter Rand */
  416.       pxyarray[0] = rx_max + 1;    /* x1   */
  417.       pxyarray[1] = 0;        /* y1   */
  418.       pxyarray[2] = w_screen - 1;    /* x2   */
  419.       pxyarray[3] = h_screen - 1;    /* y2   */
  420.       v_bar (vdi_handle, pxyarray);
  421.     }
  422.     }
  423.  
  424.   if (sy_max > py_max)
  425.     {
  426.       /* Rand oben/unten zeichnen */
  427.       if (ry_min > 0)
  428.     {
  429.       /* oberer Rand */
  430.       pxyarray[0] = 0;        /* x1   */
  431.       pxyarray[1] = 0;        /* y1   */
  432.       pxyarray[2] = w_screen - 1;    /* x2   */
  433.       pxyarray[3] = ry_min - 1;    /* y2   */
  434.       v_bar (vdi_handle, pxyarray);
  435.     }
  436.       if (ry_max < h_screen - 1)
  437.     {
  438.       /* unterer Rand */
  439.       pxyarray[0] = 0;        /* x1   */
  440.       pxyarray[1] = ry_max + 1;    /* y1   */
  441.       pxyarray[2] = w_screen - 1;    /* x2   */
  442.       pxyarray[3] = h_screen - 1;    /* y2   */
  443.       v_bar (vdi_handle, pxyarray);
  444.     }
  445.     }
  446.   /* Steuerung der Pixeldarstellung */
  447.   py = oy + 1;
  448.   for (ry = ry_min; ry <= ry_max; ry += ry_factor, py++)
  449.     {
  450.       zeile = get_RowBuf (picbuf, picbuf->nr - py);
  451.       px = ox;
  452.       for (rx = rx_min; rx <= rx_max; px++)
  453.     {
  454.       color_index = index_from_RowBuf (zeile, px, picbuf);
  455.       for (rx_n = 0; rx_n < rx_factor && rx <= rx_max; rx++, rx_n++)
  456.         rx_reihe[rx] = color_index;
  457.     }
  458.       zeichne_pixelreihe (ry);
  459.     }
  460. }
  461.  
  462. /*------------------------------------------------------------------*/
  463.  
  464. /**
  465.  ** hilfe:   Gibt Hilfstext aus
  466.  **
  467.  **/
  468.  
  469. void
  470. hilfe (void)
  471. {
  472.   static char *hilfe80 =
  473. "                            ATARI PREVIEWER  H I L F E\n"
  474. "                            ==========================\n"
  475. "\n"
  476. "     <H>\n"
  477. "oder <Help>         Diesen Hilfstext anzeigen lassen\n"
  478. "oder <F1>\n"
  479. "\n"
  480. "     <I>            Information über wichtigste Kenngrö₧en des Bildschirms\n"
  481. "                    anzeigen lassen\n"
  482. "\n"
  483. "     <Esc>          Previewer verlassen, Programm beenden\n"
  484. "oder <Q>\n"
  485. "\n"
  486. "     <Pfeiltasten>  Verschieben des aktuellen Bildausschnittes in Richtung\n"
  487. "                    des Pfeils (wenn möglich). Die Verschiebung kann durch\n"
  488. "                    gleichzeitiges Drücken weiterer Tasten variiert\n"
  489. "                    werden:\n"
  490. "\n"
  491. "                    <keine weitere Taste>   bildschirmweise verschieben\n"
  492. "                    <Control>               jeweils 1/8 Bildschirmbreite\n"
  493. "                    <Shift>                 pixelweise verschieben\n"
  494. "\n"
  495. "\n"
  496. ">>> Zur Programmfortsetzung bitte Taste drücken <<<";
  497.  
  498.   static char *hilfe40 =
  499.   "ATARI PREVIEWER  H I L F E\n"
  500.   "==========================\n"
  501.   "<H> oder <Help> oder <F1>\n"
  502.   "    Diesen Hilfstext anzeigen lassen\n"
  503.   "<I>\n"
  504.   "    Information über wichtigste Kenn-\n"
  505.   "    grö₧en des Bildschirms anzeigen\n"
  506.   "    lassen\n"
  507.   "<Esc> oder <Q>\n"
  508.   "    Previewer verlassen, Programm\n"
  509.   "    beenden\n"
  510.   "<Pfeiltasten>\n"
  511.   "    Verschieben des aktuellen Bildaus-\n"
  512.   "    schnittes in Richtung des Pfeils\n"
  513.   "    (wenn möglich). Die Verschiebung\n"
  514.   "    kann durch gleichzeitiges Drücken\n"
  515.   "    weiterer Tasten variiert werden:\n"
  516.   "    <keine weitere Taste>\n"
  517.   "        bildschirmweise verschieben\n"
  518.   "    <Control>\n"
  519.   "        jeweils 1/8 Bildschirmbreite\n"
  520.   "    <Shift>\n"
  521.   "        pixelweise verschieben\n"
  522.   "\n"
  523.   ">>> Bitte Taste drücken <<<";
  524.  
  525.   CLS;
  526.   if (w_text < 80)
  527.     fprintf (stderr, "%s", hilfe40);
  528.   else
  529.     fprintf (stderr, "%s", hilfe80);
  530.   Bconin (CON);
  531. }
  532.  
  533. /*------------------------------------------------------------------*/
  534.  
  535. /**
  536.  ** info:    Gibt Information über alle wichtigen Kenngrö₧en der
  537.  **          aktuellen Bildschirmauflösung aus
  538.  **
  539.  **/
  540.  
  541. void
  542. info (void)
  543. {
  544.  
  545.   CLS;                /* Bildschirm löschen   */
  546.  
  547.   fprintf (stderr, "Bildschirmkenngrö₧en-Info\n");
  548.   fprintf (stderr, "=========================\n\n");
  549.  
  550.   fprintf (stderr, "Bildschirmbreite:  %4d\n", w_screen);
  551.   fprintf (stderr, "-höhe [Pixel]:     %4d\n", h_screen);
  552.   fprintf (stderr, "\n");
  553.   fprintf (stderr, "Pixelbreite [µm]:  %4d\n", w_pixel);
  554.   fprintf (stderr, "Pixelhöhe   [µm]:  %4d\n", h_pixel);
  555.   fprintf (stderr, " ( Verh.(x / y) ≈ %4d\n", rx_factor);
  556.   fprintf (stderr, "   Verh.(y / x) ≈ %4d )\n", ry_factor);
  557.   fprintf (stderr, "\n");
  558.   fprintf (stderr, "Buchstabenbreite:  %4d\n", gl_wchar);
  559.   fprintf (stderr, "- höhe [Pixel]:    %4d\n", gl_hchar);
  560.   fprintf (stderr, "\n");
  561.   fprintf (stderr, "\"Box\"breite:       %4d\n", gl_wbox);
  562.   fprintf (stderr, "\"Box\"höhe [Pixel]: %4d\n", gl_hbox);
  563.   fprintf (stderr, "\n");
  564.   fprintf (stderr, "Zeichen/Zeile:     %4d\n", w_text);
  565.   fprintf (stderr, "Zeilen/Bildschirm: %4d\n", h_text);
  566.   fprintf (stderr, "\n");
  567.   fprintf (stderr, "Farbenzahl:        %4d\n", color_max);
  568.   fprintf (stderr, "Farbennuancen:     %4d\n", color_palette);
  569.  
  570.   fprintf (stderr, "\n>>> Taste drücken <<<\n");
  571.   Bconin (CON);
  572. }
  573.  
  574. /*------------------------------------------------------------------*/
  575.  
  576. /**
  577.  ** preview: Koordiniert alle Aktivitäten wie Hilfstext anzeigen,
  578.  **          eigentlichen Preview durchführen, Tastendrücke aus-
  579.  **          werten usw.
  580.  **
  581.  **/
  582.  
  583. void
  584. preview (PicBuf *picbuf, PAR *par)
  585. {
  586.   long scancode;        /* Scancode der gedrückten Taste    */
  587.   long kbret = 0;        /* Stellung der Sondertasten        */
  588.   boolean newdraw;        /* Neues Zeichnen nötig?            */
  589.  
  590.   if (!par->quiet)
  591.     {
  592.       /* Ausgabe der Begrü₧ungsmeldung    */
  593.       fprintf (stderr, "\n\n");
  594.       fprintf (stderr, "ATARI-Preview\n");
  595.       fprintf (stderr, "=============\n");
  596.       fprintf (stderr, "\n");
  597.       fprintf (stderr, "Bitte Taste drücken:\n");
  598.       fprintf (stderr, "\n");
  599.       fprintf (stderr, "<H>, <F1> oder <Help> für Hilfstext\n");
  600.       fprintf (stderr, "<Q> oder <Esc>        für Abbruch\n");
  601.       fprintf (stderr, "<beliebige Taste>     für Preview\n");
  602.       fprintf (stderr, "\n");
  603.       fprintf (stderr, "Hinweis:\n");
  604.       fprintf (stderr, "Die Hilfe-Funktion ist auch während\n");
  605.       fprintf (stderr, "des Previews aktiv\n");
  606.       scancode = (Bconin (CON) >> 16) & 255;    /* Tastendruck abwarten */
  607.     }
  608.   else
  609.     scancode = 0;
  610.  
  611.   if (scancode != SC_Q && scancode != SC_ESC)
  612.     {
  613.       /* erstmalige Vorbesetzung der Variablen der    */
  614.       /* verschiedenen Pixelsysteme                   */
  615.  
  616.       if (w_pixel >= h_pixel)
  617.     {
  618.       rx_factor = 1;
  619.       ry_factor = (w_pixel + h_pixel - 1) / h_pixel;
  620.     }
  621.       else
  622.     {
  623.       rx_factor = (h_pixel + w_pixel - 1) / w_pixel;
  624.       ry_factor = 1;
  625.     }
  626.  
  627.       sx_max = w_screen / rx_factor;
  628.       sy_max = h_screen / ry_factor;
  629.  
  630.       px_max = picbuf->nc;
  631.       py_max = picbuf->nr;
  632.  
  633.       ox = 0;
  634.       oy = 0;
  635.  
  636.       if (sx_max > px_max)
  637.     {
  638.       dx_min = (sx_max - px_max) / 2;
  639.       dx_max = dx_min + px_max - 1;
  640.     }
  641.       else
  642.     {
  643.       dx_min = 0;
  644.       dx_max = sx_max - 1;
  645.     }
  646.       if (sy_max > py_max)
  647.     {
  648.       dy_min = (sy_max - py_max) / 2;
  649.       dy_max = dy_min + py_max - 1;
  650.     }
  651.       else
  652.     {
  653.       dy_min = 0;
  654.       dy_max = sy_max - 1;
  655.     }
  656.  
  657.       rx_min = dx_min * rx_factor;
  658.       rx_max = dx_max * rx_factor;
  659.       ry_min = dy_min * ry_factor;
  660.       ry_max = dy_max * ry_factor;
  661.  
  662.       /* Graphikparameter zum Zeichnen vorbesetzen            */
  663.  
  664.       /* Clipping an Bildschirmgrenzen    */
  665.       pxyarray[0] = 0;
  666.       pxyarray[1] = 0;
  667.       pxyarray[2] = w_screen - 1;
  668.       pxyarray[3] = h_screen - 1;
  669.       vs_clip (vdi_handle, 1, pxyarray);
  670.  
  671.       /* Stil für Flächen: grau (s/w) oder grün (Farbe)       */
  672.       vsf_perimeter (vdi_handle, 0);    /* kein Rahmen      */
  673.       if (color_max < 4)
  674.     {
  675.       vsf_interior (vdi_handle, 2);    /* Füllstil: Muster */
  676.       vsf_style (vdi_handle, 4);    /* Muster: grau     */
  677.       vsf_color (vdi_handle, BLACK); /* Füllfarbe        */
  678.     }
  679.       else
  680.     {
  681.       vsf_interior (vdi_handle, 1);    /* Füllstil: voll   */
  682.       vsf_color (vdi_handle, GREEN); /* Füllfarbe        */
  683.     }
  684.  
  685.       /* Stil für Linien festlegen */
  686.       vsl_type (vdi_handle, 1);        /* Linienstil           */
  687.       vsl_width (vdi_handle, 1);    /* L.breite (ungerade!) */
  688.       vsl_ends (vdi_handle, 0, 0);    /* Linienenden          */
  689.       vsl_color (vdi_handle, BLACK);    /* Linienfarbe          */
  690.  
  691.       /* Schleifenvorbereitung: Vom Begrü₧ungstext aus        */
  692.       /* darf nur <H>, <Help> oder <F1> eine Bedeutung haben  */
  693.       if (scancode != SC_H && scancode != SC_HELP && scancode != SC_F1)
  694.     scancode = 0;
  695.       /* es soll immer am Anfang einmal gezeichnet werden     */
  696.       newdraw = TRUE;
  697.  
  698.       /* Tastaturabfrage-Schleife, bis Ende gewünscht         */
  699.       for (;;)
  700.     {
  701.       switch (scancode)
  702.         {
  703.         case SC_Q:
  704.         case SC_ESC:
  705.           return;
  706.  
  707.         case SC_H:
  708.         case SC_HELP:
  709.         case SC_F1:
  710.           /* Hilfstext auf Wunsch ausgeben                    */
  711.           hilfe ();
  712.           newdraw = TRUE;
  713.           break;
  714.         case SC_I:
  715.           /* Graphik-Information auf Wunsch ausgeben          */
  716.           info ();
  717.           newdraw = TRUE;
  718.           break;
  719.  
  720.           /* gemä₧ letztem Tastendruck - wenn sinnvoll -  */
  721.           /* Bildausschnitt neu zeichnen                  */
  722.         case SC_PF_OBN:
  723.           if (sy_max >= py_max)
  724.         break;
  725.           if (oy > 0)
  726.         {
  727.           if (kbret & KB_CONTROL)
  728.             oy -= sy_max / 8;
  729.           else if (kbret & (KB_SHIFT_RTS | KB_SHIFT_LKS))
  730.             oy -= 1;
  731.           else
  732.             oy -= sy_max;
  733.           if (oy < 0)
  734.             oy = 0;
  735.           newdraw = TRUE;
  736.         }
  737.           break;
  738.         case SC_PF_UTN:
  739.           if (sy_max >= py_max)
  740.         break;
  741.           if (oy < py_max - sy_max)
  742.         {
  743.           if (kbret & KB_CONTROL)
  744.             oy += sy_max / 8;
  745.           else if (kbret & (KB_SHIFT_RTS | KB_SHIFT_LKS))
  746.             oy += 1;
  747.           else
  748.             oy += sy_max;
  749.           if (oy > py_max - sy_max)
  750.             oy = py_max - sy_max;
  751.           newdraw = TRUE;
  752.         }
  753.           break;
  754.         case SC_PF_RTS:
  755.         case SC_C_PF_RTS:
  756.           if (sx_max >= px_max)
  757.         break;
  758.           if (ox < px_max - sx_max)
  759.         {
  760.           if (scancode == SC_C_PF_RTS)
  761.             ox += sx_max / 8;
  762.           else if (kbret & (KB_SHIFT_LKS | KB_SHIFT_RTS))
  763.             ox += 1;
  764.           else
  765.             ox += sx_max;
  766.           if (ox > px_max - sx_max)
  767.             ox = px_max - sx_max;
  768.           newdraw = TRUE;
  769.         }
  770.           break;
  771.         case SC_PF_LKS:
  772.         case SC_C_PF_LKS:
  773.           if (sx_max >= px_max)
  774.         break;
  775.           if (ox > 0)
  776.         {
  777.           if (scancode == SC_C_PF_LKS)
  778.             ox -= sx_max / 8;
  779.           else if (kbret & (KB_SHIFT_RTS | KB_SHIFT_LKS))
  780.             ox -= 1;
  781.           else
  782.             ox -= sx_max;
  783.           if (ox < 0)
  784.               ox = 0;
  785.           newdraw = TRUE;
  786.         }
  787.           break;
  788.         }
  789.       if (newdraw)
  790.         {
  791.           zeichne (picbuf);
  792.           newdraw = FALSE;
  793.         }
  794.       /* Tastendruck abwarten, Scancode extrahieren   */
  795.       scancode = (Bconin (CON) >> 16) & 255;
  796.       kbret = Kbshift (-1);    /* Sondertasten abfr.   */
  797.     }
  798.     }
  799. }
  800.  
  801. /*------------------------------------------------------------------*/
  802.  
  803. /**
  804.  **  PicBuf_to_ATARI:    Hauptprogramm:
  805.  **                      - Initialisierung und Beenden des GEM
  806.  **                      - Aufruf der eigentlichen Preview-Funktionen
  807.  **/
  808.  
  809. void
  810. PicBuf_to_ATARI (PicBuf *picbuf, PAR *par)
  811. {
  812.   if (open_vwork ())
  813.     {
  814.       rx_reihe = (Byte *) malloc (h_screen);
  815.       if (rx_reihe == NULL)
  816.     {
  817.       fprintf (stderr, "\nError: No mem for line buffer!\n");
  818.       perror ("PicBuf_to_ATARI");
  819.       close_vwork ();
  820.       exit (ERROR);
  821.     }
  822.  
  823.       (void) Cursconf (0, 1);        /* Cursor aus           */
  824.       preview (picbuf, par);        /* Previewer aufrufen   */
  825.       (void) Cursconf (1, 1);        /* Cursor ein           */
  826.       close_vwork ();
  827.     }
  828.   else
  829.     {
  830.       fprintf (stderr, "HP2xx - ATARI-Previewer\n");
  831.       fprintf (stderr, "Fehler bei der GEM-Initialisierung!");
  832.       exit (ERROR);
  833.     }
  834. }
  835.