home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / qc25 / beispiel / grdemo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-25  |  19.5 KB  |  695 lines

  1. /* GRDEMO.C - Demonstriert die Fähigkeiten der QuickC- Grafikbibliothek.
  2.  * Dabei wird MENU zur Menüanzeige und TURTLE für Turtle-Grafik benutzt.
  3.  *
  4.  * Sofern GRAPHICS.LIB und PGCHART.LIB bei der Installation nicht in 
  5.  * die Laufzeit-Bibliothek eingefügt wurden, müssen die beiden 
  6.  * Bibliotheken in die Programmliste von GRDEMO.MAK aufgenommen 
  7.  * oder auf der Befehlszeile angegeben werden 
  8. */
  9.  
  10. #include <graph.h>
  11. #include <math.h>
  12. #include <malloc.h>
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <conio.h>
  16. #include <time.h>
  17. #include "turtle.h"
  18. #include "menu.h"
  19.  
  20. /* Funktionsprototypen */
  21. int  main( void );
  22. void Kreise( void );
  23. void Kugel( void );
  24. int  Polygone( void );
  25. int  Spirale( int winkel, double inc );
  26. int  UmSpirale( double seite, int winkel, int inc );
  27. void Wanze( void );
  28. void FensterRahmen( void );
  29. void Diamant (double xy);
  30.  
  31. /* Ergibt eine Zufallszahl zwischen min und max, die im zulässigen Bereich
  32.  * für Ganzzahlen liegen muß.
  33.  */
  34. #define getrandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))
  35.  
  36. /* Konstanten */
  37. #define PI       3.141593
  38. #define LASTATR  15
  39. #define NLASTATR 14
  40.  
  41. /* Datenfeld und Aufzählungsliste für Hauptmenü */
  42. ITEM mnuMain[] =
  43. {      /* Hell hervorgehobenes Zeichen - Position */
  44.    0, "Beenden",                 /* B     0  */
  45.    0, "Kreise",                  /* K     0  */
  46.    0, "Rotierende Kugel",        /* R     0  */
  47.    0, "Tunnel",                  /* T     0  */
  48.    0, "Spirale",                 /* S     0  */
  49.    0, "Umgekehrte Spirale",      /* U     0  */
  50.    0, "Wanze",                   /* W     0  */
  51.    0, "Fenster anpassen",        /* F     0  */
  52.    0, "Modus ändern",            /* M     0  */
  53.    0, ""
  54. };
  55.  
  56. /* Konstanten für Menüauswahl definieren (0, 1, 2,...) */
  57. enum AUSWAHL
  58. {
  59.    BEENDEN, KREISE, KUGEL, TUNNEL, SPIRALE, UMSPIRAL, WANZE, FENSTER, MODUS
  60. };
  61.  
  62. /* Datenfelder aus Videomodus-Werte und entsprechende Modusnummern.
  63.  * Jedes besitzt ein vorübergehendes Datenfeld mit allen Größen und eine
  64.  * Zeigerversion die alle außer Olivetti mit einschließt.
  65.  */
  66. ITEM mnuModesT[] =
  67. {      /* Hell hervorgehobenes Zeichen - Position */
  68.    0, "ORESCOLOR ",              /* O     0  */
  69.    4, "MRES4COLOR ",             /* 4     4  */
  70.    4, "MRESNOCOLOR",             /* N     4  */
  71.    4, "HRESBW",                  /* B     4  */
  72.    0, "MRES16COLOR",             /* M     0  */
  73.    0, "HRES16COLOR",             /* H     0  */
  74.    0, "ERESCOLOR",               /* E     0  */
  75.    4, "VRES2COLOR",              /* 2     4  */
  76.    0, "VRES16COLOR",             /* V     0  */
  77.    1, "MRES256COLOR",            /* R     4  */
  78.    0, ""
  79. };
  80. ITEM *mnuModes = &mnuModesT[1]; /* Vorgabe ist kein Olivetti-Modus */
  81.  
  82. int aModesT[] =
  83. {
  84.    _ORESCOLOR,
  85.    _MRES4COLOR,
  86.    _MRESNOCOLOR,
  87.    _HRESBW,
  88.    _MRES16COLOR,
  89.    _HRES16COLOR,
  90.    _ERESCOLOR,
  91.    _VRES2COLOR,
  92.    _VRES16COLOR,
  93.    _MRES256COLOR,
  94.    _TEXTMONO,
  95.    _ERESNOCOLOR,
  96.    _HERCMONO
  97. };
  98. int *aModes = &aModesT[1];          /* Vorgabe ist kein Olivetti-Modus */
  99.  
  100. /* Globale Video-Konfiguration */
  101. struct videoconfig vc;
  102.  
  103. int main()
  104. {
  105.    int zeilMitte, spltMitte;
  106.    int fFarbe, fAnfang = WAHR;
  107.    int iMode, iMainGgw = 0, iModesGgw = 0;
  108.  
  109.    _displaycursor( _GCURSOROFF );
  110.    _getvideoconfig( &vc );
  111.    zeilMitte = vc.numtextrows / 2;
  112.    spltMitte = vc.numtextcols / 2;
  113.  
  114.    /* Besten Grafikmodus wählen, Menüs anpassen, Farbkennungen einrichten.
  115.     * Nicht vergessen, daß dafür sowohl der Adapter als auch die
  116.     * Betriebsart geprüft werden müssen.
  117.     */
  118.    switch( vc.adapter )
  119.    {
  120.       case _OCGA:
  121.          mnuModes = &mnuModesT[0];       /* Olivetti-Modus einschalten */
  122.          aModes = &aModesT[0];
  123.       case _CGA:
  124.          mnuModesT[4].achItem[0] = '\0'; /* EGA-Modi ausschalten */
  125.          iMode = _MRES4COLOR;
  126.          break;
  127.       case _HGC:
  128.          mnuModesT[7].achItem[0] = '\0';
  129.          iMode = _HERCMONO;
  130.          break;
  131.       case _OEGA:
  132.          mnuModes = &mnuModesT[0];       /* Olivetti-Modus einschalten */
  133.          aModes = &aModesT[0];
  134.       case _EGA:
  135.       mnuModesT[7].achItem[0] = '\0'; /* VGA-Modi ausschalten */
  136.          if( vc.memory > 64 )
  137.             iMode = _ERESCOLOR;
  138.          else
  139.             iMode = _HRES16COLOR;
  140.          break;
  141.       case _OVGA:
  142.       mnuModes = &mnuModesT[0];       /* Olivetti-Modus einschalten */
  143.          aModes = &aModesT[0];
  144.       case _VGA:
  145.          iMode = _VRES16COLOR;
  146.          break;
  147.       case _MCGA:
  148.          iMode = _MRES256COLOR;
  149.          break;
  150.       case _MDPA:
  151.       default:
  152.          puts( "Kein Grafikmodus verfügbar.\n" );
  153.          return WAHR;
  154.    }
  155.    switch( vc.mode )
  156.    {
  157.       case _TEXTBW80:
  158.       case _TEXTBW40:
  159.          fFarbe = FALSCH;
  160.          break;
  161.       case _TEXTMONO:
  162.       case _ERESNOCOLOR:
  163.       case _HERCMONO:
  164.          fFarbe = FALSCH;
  165.          if( iMode != _HERCMONO )
  166.             iMode = _ERESNOCOLOR;
  167.          mnuMain[8].achItem[0] = '\0';   /* Modus-Änderung ausschalten */
  168.          break;
  169.       default:
  170.          fFarbe = WAHR;
  171.          break;
  172.    }
  173.  
  174.    /* Gegenwärtigen Modus in Modus-Datenfeld finden. */
  175.    for( iModesGgw = 0; aModes[iModesGgw] != iMode; iModesGgw++ )
  176.       ;
  177.  
  178.    /* Zufallsgenerator mit Uhrzeit als Anfangswert füttern. */
  179.    srand( (unsigned)time( NULL ) );
  180.  
  181.    while( WAHR )
  182.    {
  183.       /* Auf Text-Modus schalten; wahlweise ganzen Bildschirm zu blau. */
  184.       _setvideomode(_DEFAULTMODE );
  185.       if( fFarbe )
  186.          _setbkcolor( (long)_TBLUE );
  187.       _clearscreen( _GCLEARSCREEN );
  188.  
  189.       /* Aus Menü wählen. */
  190.       iMainGgw = Menue( zeilMitte, spltMitte, mnuMain, iMainGgw );
  191.  
  192.       /* Grafikmodus einrichten und Turtle-Grafik initialisieren. Fenster
  193.        * mit Rand versehen.
  194.        */
  195.       if( iMainGgw != MODUS )
  196.       {
  197.          _setvideomode( iMode );
  198.          _displaycursor( _GCURSOROFF );
  199.          _getvideoconfig( &vc );
  200.          InitTurtle( &vc );
  201.          Rechteck( 2 * tc.xMax, 2 * tc.yMax );
  202.       }
  203.  
  204.       /* Zu neuer Menüwahl verzweigen. */
  205.       switch( iMainGgw )
  206.       {
  207.          case BEENDEN:
  208.             _setvideomode( _DEFAULTMODE );
  209.             return FALSCH;
  210.          case KREISE:
  211.             Kreise();
  212.             break;
  213.          case KUGEL:
  214.             Kugel();
  215.             break;
  216.          case TUNNEL:
  217.             StiftStatus( FALSCH );
  218.             GeheZu( -tc.xMax * .2, tc.yMax * .15 );
  219.             StiftStatus( WAHR );
  220.             Polygone();
  221.             while( !GetKey( NO_WAIT ) )
  222.                FarbWertWeiter( VORGABE );   /* Rotate palette */
  223.             break;
  224.          case SPIRALE:
  225.          if( Spirale( getrandom( 30, 80 ), (double)getrandom( 1, 5 ) ) )
  226.                break;
  227.             while( !GetKey( NO_WAIT ) )
  228.                FarbWertWeiter( VORGABE );
  229.             break;
  230.          case UMSPIRAL:
  231.             FarbIndexWeiter( 0 );
  232.             if( UmSpirale( (double)getrandom( 8, 20 ),
  233.                        getrandom( 4, 22 ),
  234.                        getrandom( 3, 31 ) ) )
  235.                break;
  236.             while( !GetKey( NO_WAIT ) )
  237.                FarbWertWeiter( VORGABE );
  238.             break;
  239.          case WANZE:
  240.             Wanze();
  241.             break;
  242.          case FENSTER:
  243.             FensterRahmen();
  244.             continue;
  245.          case MODUS:
  246.             if( fFarbe )
  247.                _setbkcolor( (long)_TBLUE );
  248.             _clearscreen( _GCLEARSCREEN );
  249.  
  250.             iModesGgw = Menue( zeilMitte, spltMitte, mnuModes, iModesGgw );
  251.             iMode = aModes[iModesGgw];
  252.             if( vc.adapter == _MCGA )
  253.                switch( iMode )
  254.                {
  255.                   case _MRES16COLOR:
  256.                   case _HRES16COLOR:
  257.                   case _ERESCOLOR:
  258.                   case _VRES16COLOR:
  259.                      _settextposition( 1, 22 );
  260.                      _outtext( "Modus nicht verwendbar" );
  261.                      iMode = _MRES256COLOR;
  262.                }
  263.             break;
  264.       }
  265.    }
  266. }
  267.  
  268. /* Kreise - In runder Anordnung Kreise unterschiedlicher Größe und Farbe
  269.  *          auf dem Bildschirm zeichnen.
  270.  *
  271.  * Parameter: Keine
  272.  *
  273.  * Ergebnis:  Keines
  274.  *
  275.  * Benutzt:   tc
  276.  */
  277. void Kreise()
  278. {
  279.    double x, y, xyRadius;
  280.    int fFuell, fStiftStatus;
  281.  
  282.    /* Stifteinstellung und Füll-Kennungen initialisieren und speichern. */
  283.    if( tc.afi <= 4 )
  284.       fFuell = AusFuellung( FALSCH );
  285.    else
  286.       fFuell = AusFuellung( WAHR );
  287.    fStiftStatus = StiftStatus( FALSCH );
  288.  
  289.    while( WAHR )
  290.    {
  291.       /* Kreise zeichnen. */
  292.       for( xyRadius = 10.0; xyRadius <= 130.0; xyRadius++ )
  293.       {
  294.          x = (tc.xMax - 30) * atan( sin( xyRadius / PI ) );
  295.          y = (tc.yMax - 30) * atan( cos( xyRadius / PI ) );
  296.          GeheZu( x, y );
  297.          StiftFarbe( FarbIndexWeiter( VORGABE ) );
  298.          Kreis( xyRadius );
  299.          if( GetKey( NO_WAIT ) )
  300.          {
  301.             StiftStatus( fStiftStatus );
  302.             AusFuellung( fFuell );
  303.             return;
  304.          }
  305.       }
  306.  
  307.       /* Für Palettenmodi (ausgen. 256-Farbig) neu anfangen. */
  308.       if( tc.afw == 64 || tc.afw == 16 )
  309.       {
  310.          _clearscreen( _GCLEARSCREEN );
  311.          AusFuellung( FALSCH );
  312.          GeheZu( 0.0, 0.0 );
  313.          StiftFarbe( WEISS );
  314.          Rechteck( 2 * tc.xMax, 2 * tc.yMax );
  315.          AusFuellung( fFuell );
  316.          FarbWertWeiter( VORGABE );
  317.       }
  318.    }
  319. }
  320.  
  321. /* Kugel - Scheiben einer Kugel zeichnen und füllen. Für EGA+ Modi mit mehr
  322.  * als 4 Farbindizes die Farben weiterrotieren.
  323.  *
  324.  * Parameter: Keine
  325.  *
  326.  * Ergebnis:  Keines
  327.  *
  328.  * Benutzt:   tc
  329.  */
  330. void Kugel()
  331. {
  332.    double xGgw, xGroesse, yGroesse, xInc;
  333.    short ciRand, fFuell;
  334.    short cvi = 0, ci = 0, c = 0;
  335.    extern long cvlColors[];
  336.  
  337.    yGroesse = xGroesse = tc.yMax * 0.9 * 2;
  338.    fFuell = AusFuellung( FALSCH );
  339.    FarbIndexWeiter( 0 );
  340.    xInc = xGroesse / 14;
  341.    ciRand = StiftFarbe( VORGABE );
  342.    RandFarbe( ciRand );
  343.  
  344.    /* Scheiben zeichnen. */
  345.    for( xGgw = xInc; xGgw <= xGroesse; xGgw += xInc * 2 )
  346.       Ellipse( xGgw, yGroesse );
  347.    AusFuellung( WAHR );
  348.    StiftStatus( FALSCH );
  349.    Schwenken( 90 );
  350.    xGroesse /= 2;
  351.    GeheZu( xGroesse - xInc, 0.0 );
  352.  
  353.    FarbWertWeiter( GRENZE );
  354.  
  355.    /* Scheiben füllen. */
  356.    while( tc.xGgw >= (-xGroesse + xInc))
  357.    {
  358.       StiftFarbe( FarbIndexWeiter( VORGABE ) );
  359.       Fuellen();
  360.       Bewege( -xInc );
  361.    }
  362.  
  363.    while( !GetKey( NO_WAIT ) )
  364.       FarbWertWeiter( GRENZE );
  365.  
  366.    StiftStatus( WAHR );
  367.    AusFuellung( fFuell );
  368. }
  369.  
  370. /* Polygone - Zeichnet Polygone (Vielecke), vom Dreieck angefangen, wobei
  371.  * deren Größe immer weiter wächst, indem die Anzahl der Seiten
  372.  * inkrementiert wird, ohne die Seitelänge zu verringern. Natürlich muß der
  373.  * Stift aktiv sein.
  374.  *
  375.  * Parameter: Keine
  376.  *
  377.  * Ergebnis:  1 bei Benutzer-Unterbrechung, 0 bei Bildschirmrand
  378.  *
  379.  * Benutzt:   tc
  380.  */
  381. int Polygone()
  382. {
  383.    int cSeiten = 3, atrib = 1;
  384.    double dxy = tc.yEinheit;
  385.  
  386.    while( WAHR )
  387.    {
  388.       StiftFarbe( FarbIndexWeiter( VORGABE ) );
  389.       if( !Poly( cSeiten++, dxy += 1.5 ) )
  390.          return FALSCH;
  391.       if( GetKey( NO_WAIT ) )
  392.          return WAHR;
  393.    }
  394. }
  395.  
  396. /* Spirale  - Zeichnet eine Spirale durch laufendes Verlängern der Seiten
  397.  *            einer sich drehenden Figur.
  398.  *
  399.  * Parameter: wnkl - bestimmt Dichte
  400.  *            xyInc - bestimmt Größe der Seiten
  401.  *
  402.  * Ergebnis:  1 bei Benutzer-Unterbrechung, 0 bei Bildschirmrand
  403.  *
  404.  * Benutzt:   tc
  405.  */
  406. int Spirale( int wnkl, double xyInc )
  407. {
  408.    double xy = tc.yEinheit;
  409.  
  410.    while( WAHR )
  411.    {
  412.       StiftFarbe( FarbIndexWeiter( VORGABE ) );
  413.       if( !Bewege( xy += xyInc ) )
  414.          return FALSCH;
  415.       Schwenken( wnkl );
  416.       if( GetKey( NO_WAIT ) )
  417.          return WAHR;
  418.    }
  419. }
  420.  
  421. /* UmSpirale - Zeichnet eine umgekehrte Spirale durch laufendes Vergrößern
  422.  *             aller Winkel einer einer sich drehenden Figur, ohne die
  423.  *             Länge der Seiten zu ändern.
  424.  *
  425.  * Parameter: xy - bestimmt Größe
  426.  *            wnkl - bestimmt Dichte
  427.  *            xyInc - bestimmt Größe der Seiten
  428.  *
  429.  * Ergebnis:  1 bei Benutzer-Unterbrechung, 0 bei Bildschirmrand
  430.  *
  431.  */
  432. int UmSpirale( double xy, int wnkl, int wnklInc )
  433. {
  434.    while( WAHR )
  435.    {
  436.       StiftFarbe( FarbIndexWeiter( VORGABE ) );
  437.       if( !Bewege( xy ) )
  438.          return FALSCH;
  439.       Schwenken( wnkl += wnklInc );
  440.       if( GetKey( NO_WAIT ))
  441.          return WAHR;
  442.    }
  443. }
  444.  
  445. /* Wanze - Zeichnet einen geflügelten Käfer auf dem Bildschirm und bewegt
  446.  *         ihn dann willkürlich herum.
  447.  *
  448.  * Parameter: Keine
  449.  *
  450.  * Ergebnis:  Keines
  451.  *
  452.  * Benutzt:   tc
  453.  */
  454. void Wanze()
  455. {
  456.  
  457.    static unsigned char uVordFlgel[] = { 0x81, 0x3c, 0xc3, 0x66,
  458.                                          0x66, 0x0f, 0xf0, 0x18 };
  459.    static unsigned char uHintFlgel[] = { 0x66, 0x0f, 0xf0, 0x18,
  460.                                          0x81, 0x3c, 0xc3, 0x66 };
  461.    char *buffer;               /* Bild - Zwischenspeicher */
  462.  
  463.    /* Käfer zeichnen. */
  464.    StiftStatus( FALSCH );
  465.    AusFuellung( WAHR );
  466.    Bewege( 40.0 );            /* Vordere Flügel zeichnen und ausfüllen */
  467.    Schwenken( 90 );
  468.    Bewege( 80.0 );
  469.    StiftFarbe( 1 );
  470.    _setfillmask( uVordFlgel );
  471.    Ellipse( 172.0, 70.0 );
  472.    Schwenken( 180 );
  473.    Bewege( 160.0 );
  474.    Ellipse( 172.0, 70.0 );
  475.    Schwenken(-90 );
  476.    GeheZu( 0.0, 0.0 );
  477.    Bewege( 25.0 );            /* Hintere Flügel zeichnen und ausfüllen */
  478.    Schwenken( 90 );
  479.    Bewege( 70.0 );
  480.    StiftFarbe( 2 );
  481.    _setfillmask( uHintFlgel );
  482.    Ellipse( 150.0, 70.0 );
  483.    Schwenken( 180 );
  484.    Bewege( 140.0 );
  485.    Ellipse( 150.0, 70.0 );
  486.    Schwenken(-90 );
  487.    GeheZu( 0.0, 0.0 );
  488.    _setfillmask( NULL );      /* Körper des Käfers zeichnen    */
  489.    StiftFarbe( 3 );
  490.    RandFarbe( 3 );
  491.    Ellipse( 52.0, 220.0 );
  492.    StiftFarbe( 1 );           /* Nun die Augen */
  493.    RandFarbe( 1 );
  494.    AusFuellung( FALSCH );
  495.    Bewege( 90.0 );
  496.    Schwenken( 90 );
  497.    Bewege( 22.0 );
  498.    Kreis( 20.0 );
  499.    StiftFarbe( 0 );
  500.    Fuellen();
  501.    StiftFarbe( 1 );
  502.    Schwenken( 180 );
  503.    Bewege( 44.0 );
  504.    Kreis( 20.0 );
  505.    StiftFarbe( 0 );
  506.    Fuellen();
  507.  
  508.    /* Position einnehmen - rechts-oben des Bildes. */
  509.    GeheZu( 0.0, 0.0 );
  510.    Richtung( 0 );
  511.    Bewege( 120.0 );
  512.    Schwenken( -90 );
  513.    Bewege( 175.0 );
  514.    Schwenken( 90 );
  515.  
  516.    /* Bildgröße feststellen und Speicher dafür zuordnen. */
  517.    buffer = (char *)malloc( (size_t)BildGroesse( 350.0, 240.0 ) );
  518.    BildHolen( 350.0, 240.0, buffer );
  519.  
  520.    /* Nach Zufallswerten herumschwirren, an Bildschirmrändern anpassen. */
  521.    while( !GetKey( NO_WAIT ) )
  522.    {
  523.       if( tc.xGgw <= (-tc.xMax + 15.0) )
  524.          Richtung( 90 );
  525.       else if( tc.yGgw <= (-tc.yMax + 15.0) )
  526.          Richtung( 180 );
  527.       else if( tc.xGgw >= (tc.xMax - 365.0) )
  528.          Richtung( 270 );
  529.       else if( tc.yGgw >= (tc.yMax - 255.0) )
  530.          Richtung( 0 );
  531.       else
  532.          Schwenken( getrandom( -20, 20 ) );
  533.       Bewege( 3.0 );
  534.       BildPos( buffer, _GPSET );
  535.    }
  536.    free( (char *)buffer );
  537. }
  538.  
  539. /* FensterRahmen - Damit kann man im Dialogbetrieb den Bildschirmausschnitt
  540.  * einrichten. Richtungstasten allein zum Verändern der Fenstergröße;
  541.  * Richtungstasten mit Umschalter bewegen das Fenster. Die Die Plus- bzw.
  542.  * Minustaste auf dem Zahlentastenblock verändern das Seitenverhältnis, ohne
  543.  * das Fenster selbst zu beeinflussen. Dabei erscheinen zur Orientierung ein
  544.  * Fensterrahmen und ein Kreis.
  545.  *
  546.  * Parameter: Keine
  547.  *
  548.  * Ergebnis:  Keines
  549.  *
  550.  * Benutzt:   tc and vc
  551.  */
  552. #define WININC 4
  553. void FensterRahmen()
  554. {
  555.    short i, iSchreibModus;
  556.    double xyRadius = 400.0, xEcke, yEcke;
  557.    char achT[40];
  558.  
  559.    while( WAHR )
  560.    {
  561.       /* Anleitungen anzeigen. */
  562.       _settextposition( 2, 2 );
  563.       _outtext(" Seitenverhältnis   graue PLUS- und MINUS-Taste\n" );
  564.       _settextposition( 3, 2 );
  565.       _outtext(" Fenstergröße               mit Richtungstasten\n" );
  566.       _settextposition( 4, 2 );
  567.       _outtext(" Fenster verschieben      UMSCH+Richtungstasten\n" );
  568.       _settextposition( 5, 2 );
  569.       _outtext(" Fertig                              EINGABETASTE\n\n" );
  570.  
  571. /* Speichern des alten Schreibmodus und Setzen von XOR, damit Sie
  572.  * Figuren durch erneutes Erstellen gelöscht werden. Dies möglicht das 
  573.  * Überschreiben von Text ohne ihn zu löschen.
  574.  */
  575.  
  576. iSchreibModus = _getwritemode();
  577. _setwritemode( _GXOR );
  578.  
  579. while ( WAHR )
  580. {
  581.      /* Daten ausgeben */
  582.      _settextposition( 6,2 );
  583.       sprintf( achT, "\n  Seitenvh=%1.2f  xMax=%.f  yMax=%.f",
  584.             tc.yxSeitenvh, tc.xMax, tc.yMax );
  585.       _outtext( achT );
  586.  
  587.       /* Berechnen der aktuellen Boxenecken. */
  588.       xEcke = 2 * tc.xMax;
  589.       yEcke = 2 * tc.yMax;
  590.  
  591.        /* Zeichnen der Kanten des Rechtecks und des Diamanten
  592.         * um das Verhältnis darzustellen.
  593.         */
  594.         Rechteck( xEcke, yEcke );
  595.         Diamant( xyRadius);
  596.  
  597.       switch( GetKey( CLEAR_WAIT ) )
  598.       {
  599.          /* Seitenverhältnis anpassen. */
  600.          case N_MINUS:
  601.          if( tc.yxSeitenvh > 0.4)
  602.             tc.yxSeitenvh = (tc.xMax - (WININC * tc.yEinheit)) / tc.yMax;
  603.             break;
  604.          case N_PLUS:
  605.          if( tc.yxSeitenvh < 8.0)
  606.          tc.yxSeitenvh = (tc.xMax + (WININC * tc.yEinheit)) / tc.yMax;
  607.             break;
  608.  
  609.          /* Fenstergröße einrichten. */
  610.          case U_RT:
  611.             if( tc.xsLinks < (vc.numxpixels / 3) )
  612.                tc.xsLinks += WININC;
  613.             if( tc.xsRechts > (vc.numxpixels - (vc.numxpixels / 3)) )
  614.                tc.xsRechts -= WININC;
  615.             break;
  616.          case U_LT:
  617.             if( tc.xsLinks )
  618.                tc.xsLinks -= WININC;
  619.             if( tc.xsRechts < vc.numxpixels )
  620.                tc.xsRechts += WININC;
  621.             break;
  622.          case U_DN:
  623.             if( tc.ysOben < (vc.numypixels / 3) )
  624.                tc.ysOben += WININC;
  625.             if( tc.ysUnten > (vc.numypixels - (vc.numypixels / 3)) )
  626.                tc.ysUnten -= WININC;
  627.             break;
  628.          case U_UP:
  629.             if( tc.ysOben )
  630.                tc.ysOben -= WININC;
  631.             if( tc.ysUnten < vc.numypixels )
  632.                tc.ysUnten += WININC;
  633.             break;
  634.  
  635.          /* Fensterposition einrichten. */
  636.          case S_LT:
  637.             if( tc.xsLinks )
  638.             {
  639.                tc.xsLinks -= WININC;
  640.                tc.xsRechts -= WININC;
  641.             }
  642.             break;
  643.          case S_RT:
  644.             if( tc.xsRechts < vc.numxpixels )
  645.             {
  646.                tc.xsLinks += WININC;
  647.                tc.xsRechts += WININC;
  648.             }
  649.             break;
  650.          case S_UP:
  651.             if( tc.ysOben )
  652.             {
  653.                tc.ysOben -= WININC;
  654.                tc.ysUnten -= WININC;
  655.             }
  656.             break;
  657.          case S_DN:
  658.             if( tc.ysUnten < vc.numypixels )
  659.             {
  660.                tc.ysOben += WININC;
  661.                tc.ysUnten += WININC;
  662.             }
  663.             break;
  664.  
  665.          /* Ende. */
  666.          case EINGABE:
  667.          _setwritemode( iSchreibModus );
  668.             return;
  669.  
  670.          /* Unbekannte Tasten ignorieren. */
  671.       default:
  672.          break;
  673.       }
  674.       /* Nach jeder Einstellung Bildschirm löschen, und auf Vorgaben rücksetzen. */
  675.       Rechteck( xEcke, yEcke );
  676.       Diamant ( xyRadius );
  677.       Home();
  678.    }
  679. }
  680. }
  681. /* Funktion wird von FensterRahmen zum Zeichnen des Diamanten benutzt. */
  682. void Diamant( double xy )
  683. {
  684.         StiftStatus( FALSCH );
  685.         GeheZu( 0.0, xy );
  686.         StiftStatus( WAHR );
  687.         GeheZu( xy, 0.0 );
  688.         GeheZu( 0.0, -xy );
  689.         GeheZu( -xy, 0.0 );
  690.         GeheZu( 0.0, xy );
  691.         StiftStatus( FALSCH );
  692.         GeheZu( 0.0, 0.0 );
  693.         StiftStatus( WAHR );
  694. }
  695.