home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 328_02 / wsave.c < prev    next >
C/C++ Source or Header  |  1991-04-02  |  6KB  |  304 lines

  1. /* wsave
  2.  *
  3.  * wsave text/graphics in current window frame,
  4.  * move it to 'wheap' storage, store address of the saved text in winsave
  5.  * if out of memory store NULL to winsave.
  6.  *
  7.  */
  8.  
  9.  
  10. #include  "wscreen.h"
  11. #include  "wsys.h"
  12.  
  13.  
  14.  
  15.  
  16. void wsave ( void )
  17.     {
  18.     int extra, extra2;        /* need extra lines for borders ? */
  19.  
  20.  
  21.  
  22.     /* text_mode screen pointers */
  23.     unsigned char   far *line_ptr;
  24.  
  25.     /* pointers to screen save area */
  26.     WHEAP             *hptr;
  27.     unsigned char   far *area;
  28.  
  29.  
  30.     int        l, t, r, b;    /* co-ords inlcuding window frame */
  31.  
  32.     int         movenum;
  33.  
  34.     unsigned     long int  nbytes;
  35.  
  36.  
  37.     struct _CHATTR         /* 2 byte char/attr */
  38.         {
  39.         unsigned char c;
  40.         unsigned char a;
  41.         };
  42.     typedef struct _CHATTR far *CHATTR;    /* far pointer to a pair */
  43.  
  44.  
  45.     #ifndef __TURBOC__
  46.     /* Microsoft C needs an 'intermediary' ptr to handle syntax correctly.
  47.      */
  48.     void far *msc_ptr;
  49.     #endif  /* Microsoft 'idiot' fix */
  50.  
  51. #ifndef TEXTONLY
  52.     unsigned int    hn;        /* hercules bank offsets */
  53.     int        color;        /* EGA color bit mask */
  54.     int        t_save;     /* save top row # for each color */
  55.  
  56.     /* graphics mode screen pointers */
  57.     unsigned char far *base, far *base_save;
  58. #endif
  59.  
  60.  
  61.  
  62.  
  63.  
  64.     /* if there is going to be a border
  65.      * then the area to save has to be larger than the text window
  66.      * (border occupies 1 line extra in each direction)
  67.      */
  68.     extra = (w0-> winbox ) ? 1 : 0;
  69.     extra2 = 2*extra;
  70.  
  71.     l = (  (w0->winleft)    -extra );
  72.     t = (  (w0->wintop)     -extra );
  73.     r = (l+(w0->winxmax)    +extra2 );
  74.     b = (t+(w0->winymax)    +extra2 );
  75.  
  76.  
  77.     /* number of characters in the window
  78.      */
  79.     movenum = r-l+1;         /* one text row */
  80.     nbytes =  movenum*(b-t+1);
  81.  
  82.  
  83.  
  84.  
  85.     if ( wmode == 'T' )
  86.         {
  87.  
  88.         /* number of bytes to allocate
  89.          * multiply by 2 (= text+attributes)
  90.          */
  91.         hptr =  wheap_alloc ( 2*nbytes, WIN_HP_PRIORITY, NULL );
  92.  
  93.         w0->winsave = hptr;
  94.  
  95.         if (hptr == NULL)
  96.             {
  97.             return;
  98.             }
  99.  
  100.         area = wheap_access ( hptr, 0 );
  101.  
  102.         movenum *= 2;    /* char and attr */
  103.  
  104.  
  105.         for (    line_ptr  = wpage_ram + 2*80*( t ) + 2*( l );
  106.             t<=b;
  107.             ++t,  line_ptr += 2*80
  108.             )
  109.             {
  110.             /* move one line per pass thru this loop
  111.              * loop limit is one char beyond end of line
  112.              */
  113.             farmemcpy ( area, line_ptr, movenum );
  114.             area += movenum;
  115.             }
  116.  
  117.         }
  118.  
  119. #ifndef TEXTONLY
  120.     else
  121.         {
  122.         /* graphics mode save
  123.          *
  124.          * Note that r and b point to the last line INCLUSIVE
  125.          * so loops need to go up to and include.
  126.          */
  127.  
  128.         /* convert single chars (=1 byte in text mode)
  129.          *    to blocks of pixels in graphics mode
  130.          */
  131.         nbytes *= (wpxchar/8) * wpychar;
  132.  
  133.  
  134.         if (wmonitor != 'H')
  135.             {
  136.             /* EGA and VGA -- 4 colors */
  137.             nbytes *= 4;
  138.             }
  139.  
  140.  
  141.  
  142.         if ( nbytes >= WHEAP_MAX )
  143.             {
  144.             /* too large to save...
  145.              * convert window to WSAVE2NULL
  146.              */
  147.             w0->winsave  = NULL;
  148.             return;
  149.             }
  150.  
  151.         hptr = wheap_alloc ( nbytes, WIN_HP_PRIORITY, NULL );
  152.  
  153.         w0-> winsave = hptr;
  154.  
  155.         if ( hptr == NULL )
  156.             {
  157.             return;
  158.             }
  159.  
  160.         area = wheap_access ( hptr, 0 );
  161.  
  162.  
  163.         /* convert top and bottom counters
  164.          * to pixel co-ords only for counting rows
  165.          */
  166.         t *= wpychar;
  167.         b  = (b+1) * wpychar;  /* includes last pixel row */
  168.  
  169.  
  170.         /* number of bytes in each row of pixels
  171.          */
  172.         movenum = r-l+1;
  173.  
  174.  
  175.  
  176.         /* get image */
  177.  
  178.         switch ( wmonitor )
  179.             {
  180.         case ( 'H'):
  181.             /* NOTE addressing hercules graphics ram:
  182.              *    l, t are 'text-mode' addresses.
  183.              *    720 pixels/row, wpxchar pixels per 'x' incr
  184.              *       so 1st factor = wxabsmax = chars per row
  185.              *    divide wpychar by 4(=# herc banks) =
  186.              *      gives #of sets of banks (4 pxl rows each)
  187.              *    wpxchar/8 =1 always, included for clarity.
  188.              *
  189.              *    because charsizes are mults of 4,
  190.              *    whbank starts at 0;
  191.              *
  192.              *    also note that l and t have been converted
  193.              *        from character rows to pixel rows
  194.              *              so don't need wpychar.
  195.              *    however, r & l still count text cols, not pxl
  196.              */
  197.             base    =  wpage_ram
  198.                 + ( (720/wpxchar)*(t/4) ) + l;
  199.  
  200.  
  201.             for ( hn = 0; t < b;  ++t, hn += 0x2000 )
  202.                 {
  203.                 /* loop iterates once per row
  204.                  */
  205.                 if ( hn == 0x8000 )
  206.                     {
  207.                     /* finished one set of 4 banks,
  208.                      * move up to next tier.
  209.                      */
  210.                     hn = 0;
  211.                     base += 90;
  212.                     }
  213.                 #ifdef __TURBOC__
  214.                     /* much easier to move all the data in TurboC
  215.                      */
  216.                     farmemcpy ( area, base+hn, movenum );
  217.                 #else
  218.                     /* Microsoft C preprocessor generates wrong code 
  219.                      * in small model.
  220.                      */
  221.                     msc_ptr = base+hn;
  222.  
  223.                     farmemcpy ( area, msc_ptr, movenum );
  224.                 #endif    /* Microsoft vs Turbo C */
  225.                 
  226.                 area  += movenum;    /* move ptr to target dn one row */
  227.                 }
  228.             break;       /* end hercules mode */
  229.  
  230.         case ( 'E' ):
  231.         case ( 'V' ):
  232.             EGA_OUT (1, EGA_ENABLE );
  233.             /* how to put point = EGA_OUT(3, putmode)*/
  234.             /*   0x18 = XOR  0x10 = OR  0x08 = AND */
  235.  
  236.  
  237.             /*  
  238.              *    note that t, b have been converted to pixel rows
  239.              *        rather than char rows.
  240.              *    however, r&l still count text columns,
  241.              *         not pixel columns
  242.              */
  243.             base_save =
  244.             base = wpage_ram + ( wegarowsize * t ) + l;
  245.  
  246.             t_save = t;
  247.  
  248.             /* default for most graphics drivers is to leave
  249.              * write mode = 0 and EGA output enabled.
  250.              * so you don't need these, but in future, ...
  251.              * EGA_OUT ( 1, EGA_ENABLE ), EGA_OUT ( 5, 0 );
  252.              *
  253.              */
  254.  
  255.             for ( color = 0; color < 4; ++color )
  256.                 {
  257.                 /* becuase the size of the save area is <64k
  258.                  *    (imposed above), the pointers are
  259.                  * always correctly normalized
  260.                  * If larger save areas are desired,
  261.                  * renormalize (area) for each new color
  262.                  * which will suffice even for super VGA
  263.                  *    (800*600 = 60k per color)
  264.                  */
  265.                 base = base_save;
  266.                 t = t_save;
  267.  
  268.                 EGA_OUT (4, color);
  269.  
  270.                 for (     ;    /* loop once per row */
  271.                     t < b;
  272.                     ++t, base += 640/wpxchar )
  273.                     {
  274.                     farmemcpy ( area, base, movenum );
  275.                     area += movenum;
  276.                     }    /* end for each rows */
  277.  
  278.                 }/* end loop for each color */
  279.  
  280.                 /* reset EGA */
  281.                 EGA_OUT (0,0);            /* BLACK */
  282.                 EGA_OUT (8, 0xff);              /* all bits */
  283.  
  284.  
  285.                 break;
  286.                 }     /* end switch (wgdriver) */
  287.  
  288.  
  289.         /* end of get image in graphics mode */
  290.  
  291.         }
  292.  
  293. #endif    /* ifdef TEXTONLY - end of graphics mode save to RAM */
  294.  
  295.     wheap_deaccess ( hptr, 1 );
  296.  
  297.     return;
  298.     }
  299.  
  300. /*-------------------------end of wsave---------------------------*/
  301.  
  302.  
  303.  
  304.