home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 01 / tricks / screen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-22  |  9.0 KB  |  235 lines

  1. /*-< Anfang SCREEN.C >------------------------------------*
  2.  *  (c) 1990 by Manfred Birnkott & toolbox                *
  3.  *--------------------------------------------------------*/
  4. #include <dos.h>
  5. #include <conio.h>
  6. #include <stdlib.h>
  7. #include "screen.h"
  8. /*--------------------------------------------------------*
  9.  *  Byte-Größe nach rechts rotieren                       *
  10.  *--------------------------------------------------------*/
  11. #define rotrb(c,n) (char)((((int)(c)<<8)|(int)(c))>>((n)%8))
  12. /*--------------------------------------------------------*
  13.  *  Grafikzeichen/Grafikcodes umwandeln                   *
  14.  *--------------------------------------------------------*/
  15. #define convertgchar(c)  convertgbyte(0,c)
  16. #define convertgcode(c)  convertgbyte(1,c)
  17. /*--------------------------------------------------------*
  18.  *  Textmodus bestimmen                                   *
  19.  *--------------------------------------------------------*/
  20. int gettextmode (void)
  21.   {struct text_info txt;
  22.    gettextinfo(&txt);
  23.    return(txt.currmode);
  24.   }
  25. /*--------------------------------------------------------*
  26.  *  Bildschirm-Basisadresse bestimmen                     *
  27.  *--------------------------------------------------------*/
  28. void far *screenbase (void)
  29.   {return((gettextmode()==7)?(void far *)MK_FP(0xb000,0)
  30.                             :(void far *)MK_FP(0xb800,0));
  31.   }
  32. /*--------------------------------------------------------*
  33.  *  Bildschirm-Koordinaten auf Gültigkeit prüfen          *
  34.  *--------------------------------------------------------*/
  35. int testscrcoord (int x, int y)
  36.   {extern int WINDOWMODE;
  37.    struct text_info txt;
  38.    gettextinfo(&txt);
  39.    if (WINDOWMODE==0)
  40.      {txt.winleft=txt.wintop=1; txt.winbottom=25;
  41.       txt.winright=(txt.currmode<2)?40:80;
  42.      }
  43.    return((x>=txt.winleft)&&(x<=txt.winright)&&
  44.           (y>=txt.wintop)&&(y<=txt.winbottom));
  45.   }
  46. /*--------------------------------------------------------*
  47.  *  Bildschirm-Koordinaten an Grenzen anpassen            *
  48.  *--------------------------------------------------------*/
  49. void justscrcoord (int *x, int *y)
  50.   {extern int WINDOWMODE;
  51.    struct text_info txt;
  52.    gettextinfo(&txt);
  53.    if (WINDOWMODE==0)
  54.      {txt.winleft=txt.wintop=1; txt.winbottom=25;
  55.       txt.winright=(txt.currmode<2)?40:80;
  56.      }
  57.    *x=max(min(*x,txt.winright),txt.winleft);
  58.    *y=max(min(*y,txt.winbottom),txt.wintop);
  59.   }
  60. /*--------------------------------------------------------*
  61.  *  Grafikzeichen oder Grafikcode konvertieren            *
  62.  *--------------------------------------------------------*/
  63. unsigned char convertgbyte (int mode, unsigned char c)
  64.   {char grcode[40]={0x11,0x51,0xd1,0x73,0x70,0xd0,0xf3,0x33,
  65.                     0xf0,0xc3,0x43,0xc1,0x50,0x05,0x45,0x54,
  66.                     0x15,0x44,0x55,0x1d,0x37,0x0f,0x3c,0xcf,
  67.                     0xfc,0x3f,0xcc,0xff,0xcd,0x47,0xdc,0x74,
  68.                     0x07,0x0d,0x1c,0x34,0x77,0xdd,0x41,0x14
  69.                    };
  70.    int i;
  71.    if (mode)     /* Grafikcode in Grafikzeichen umwandeln */
  72.      {for (i=0;(i<40)&&(c!=grcode[i]);i++);
  73.       return((i<40)?179+i:0);
  74.      }
  75.    else          /* Grafikzeichen in Grafikcode umwandeln */
  76.       return(((c>=179)&&(c<=218))?grcode[c-179]:0);
  77.   }
  78. /*--------------------------------------------------------*
  79.  *  Grafikzeichen überlagern                              *
  80.  *--------------------------------------------------------*/
  81. unsigned char overlaygchar (unsigned char c1,
  82.                             unsigned char c2)
  83.   {extern int CROSSLINEMODE;
  84.    unsigned char c=0;
  85.    if (CROSSLINEMODE&&(c1>=179)&&(c1<=218))
  86.       c=convertgcode(convertgchar(c1)|convertgchar(c2));
  87.    return((c)?c:c1);
  88.   }
  89. /*--------------------------------------------------------*
  90.  *  Bildschirm-Grafikzeichen glätten                      *
  91.  *--------------------------------------------------------*/
  92. void truncategchar (int far *scrbase, int far *ptr,
  93.                     int llen)
  94.   {extern int CROSSLINEMODE;
  95.    int  i,x,y,x1,y1;
  96.    char c,mask=0x03;
  97.    if ((CROSSLINEMODE==2)&&((c=convertgchar(*ptr))!=0))
  98.      {x1=(ptr-scrbase)%llen+1; y1=(ptr-scrbase)/llen+1;
  99.                              /* angrenzende Grafikzeichen */
  100.       for (i=0;i<4;i++)      /* betrachten                */
  101.         {if (i%2) {x=x1+((i<2)?1:-1); y=y1;}
  102.              else {y=y1+((i<2)?-1:1); x=x1;};
  103.          if ((c&mask)&&((testscrcoord(x,y)==0)||
  104.             ((rotrb(convertgchar(*(scrbase+llen*(y-1)+x-1)),
  105.             4)&mask)!=(c&mask))))
  106.             c&=mask^0xff;            /* Kante abschneiden */
  107.          mask<<=2;
  108.         }
  109.       if ((c=convertgcode(c))!=0) *(char far *)ptr=c;
  110.      }
  111.   }
  112. /*--------------------------------------------------------*
  113.  *  vertikale/horizontale Linie zeichnen (Textmodus)      *
  114.  *--------------------------------------------------------*/
  115. void drawline (int x1, int y1, int x2, int y2)
  116.   {extern unsigned char *TEXTLINESTYLE;
  117.    extern int TEXTLINEATTR;
  118.    char lc;
  119.    int  k,len,inc,llen;
  120.    int  far *scrbase,
  121.         far *screenpos,
  122.         far *ptr=NULL;
  123.    scrbase=(int far *)screenbase();
  124.    llen=(gettextmode()<2)?40:80;
  125.          /* Start- und Endpunkt auf Gültigkeit überprüfen */
  126.    justscrcoord(&x1,&y1); justscrcoord(&x2,&y2);
  127.                          /* horizontal/vertikal festlegen */
  128.    if (x1!=x2) {len=abs(x1-x2)+1; inc=(x1<=x2)?1:-1;
  129.                 lc=TEXTLINESTYLE[0];
  130.                }
  131.           else {len=abs(y1-y2)+1; inc=(y1<=y2)?llen:-llen;
  132.                 lc=TEXTLINESTYLE[1];
  133.                };
  134.                                         /* Linie zeichnen */
  135.    screenpos=scrbase+llen*(y1-1)+(x1-1);
  136.    for (k=0;k<len;k++)
  137.      {*screenpos=overlaygchar(lc,*screenpos)|
  138.                              (TEXTLINEATTR<<8);
  139.       if (k) truncategchar(scrbase,ptr,llen);
  140.       ptr=screenpos;
  141.       screenpos+=inc;
  142.      }
  143.    if (k) truncategchar(scrbase,ptr,llen);
  144.   }
  145. /*--------------------------------------------------------*
  146.  *  Umriß eines Polygons zeichnen (Textmodus)             *
  147.  *--------------------------------------------------------*/
  148. void drawpolygon (int anz, signed char *coord)
  149.   {int i,k;
  150.    for (i=1,k=0;i<anz;i++,k+=2)
  151.       drawline(coord[k],coord[k+1],coord[k+2],coord[k+3]);
  152.   }
  153. /*--------------------------------------------------------*
  154.  *  Rahmen zeichnen (Textmodus)                           *
  155.  *--------------------------------------------------------*/
  156. void drawframe (int x1, int y1, int x2, int y2)
  157.   {extern int SHADOWMODE;
  158.    extern int SHADOWATTR;
  159.    extern int TEXTLINEATTR;
  160.    extern unsigned char *FRAMELINESTYLE;
  161.    int i,k,xl,yl,anz,llen,inc=0,ls=0;
  162.    int far *scrbase,
  163.        far *screenpos,
  164.        far *ptr=NULL;
  165.    /* Eckpunkte unter Berücksichtigung eines eventuell zu */
  166.    /* zu zeichnenden Schattens auf Gültigkeit überprüfen  */
  167.    if ((SHADOWMODE)&&(SHADOWMODE<3))
  168.      {yl=-1;
  169.       xl=(SHADOWMODE<2)?-2:+2;
  170.      }
  171.    else xl=yl=0;
  172.    x1+=xl; y1+=yl; justscrcoord(&x1,&y1); x1-=xl; y1-=yl;
  173.    if (SHADOWMODE>2)
  174.      {yl=+1;
  175.       xl=(SHADOWMODE>3)?-2:+2;
  176.      }
  177.    else xl=yl=0;
  178.    x2+=xl; y2+=yl; justscrcoord(&x2,&y2); x2-=xl; y2-=yl;
  179.  
  180.    llen=(gettextmode()<2)?40:80;
  181.    screenpos=(scrbase=(int far *)screenbase())
  182.              +llen*(y1-1)+x1-1;
  183.                                        /* Rahmen zeichnen */
  184.    if (((xl=x2-x1+1)>1)&&((yl=y2-y1+1)>1))
  185.      {for (i=0;i<8;i++)
  186.         {if (i&1)
  187.            {if (i&2) {anz=yl-2; inc=llen;}
  188.                 else {anz=xl-2; inc=1;}
  189.             if (i>4) inc=-inc;
  190.            }
  191.          else anz=1;
  192.          for (k=0;k<anz;k++)
  193.            {screenpos+=inc;
  194.             *screenpos=overlaygchar(FRAMELINESTYLE[ls],
  195.                        *screenpos)|(TEXTLINEATTR<<8);
  196.             if (ptr!=NULL) truncategchar(scrbase,ptr,llen);
  197.             ptr=screenpos;
  198.            }
  199.          if (ptr!=NULL) truncategchar(scrbase,ptr,llen);
  200.          ls++;
  201.         }
  202.                                      /* Schatten zeichnen */
  203.       if (SHADOWMODE)
  204.         {ptr=scrbase+llen*((SHADOWMODE<3)?y1-2:y2)
  205.                          +(((SHADOWMODE-1)%3)?x1+1:x1-3);
  206.          for (i=0;i<xl;i++)
  207.             *((char far *)(ptr++)+1)=SHADOWATTR;
  208.          ptr=scrbase+llen*((SHADOWMODE<3)?y1-2:y1-1)
  209.                          +(((SHADOWMODE-1)%3)?x2:x1-3);
  210.          for (i=1;i<yl;i++)
  211.             *((char far *)(ptr+1)+1)=
  212.             *((char far *)(ptr+=llen)+1)=SHADOWATTR;
  213.         }
  214.      }
  215.   }
  216. /*--------------------------------------------------------*
  217.  *  Textfenster-Rahmen zeichnen                           *
  218.  *--------------------------------------------------------*/
  219. void windowframe (void)
  220.   {extern int WINDOWMODE;
  221.    struct text_info txt;
  222.    if (WINDOWMODE)
  223.      {txt.winleft=txt.wintop=1;
  224.       txt.winbottom=25; txt.winright=80;
  225.      }
  226.    else
  227.      {gettextinfo(&txt);
  228.       txt.winleft--; txt.wintop--;
  229.       txt.winbottom++; txt.winright++;
  230.      }
  231.    drawframe(txt.winleft,txt.wintop,
  232.              txt.winright,txt.winbottom);
  233.   }
  234. /*-< Ende SCREEN.C >--------------------------------------*/
  235.