home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / comms / comprgs / term232.lha / Source_Code / termSource / termScroll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-18  |  13.7 KB  |  636 lines

  1. /*
  2. **    $Id: termScroll.c,v 1.7 92/08/15 20:15:10 olsen Sta Locker: olsen $
  3. **    $Revision: 1.7 $
  4. **    $Date: 92/08/15 20:15:10 $
  5. **
  6. **    Support routines for optimized screen scrolling.
  7. **
  8. **    Copyright ⌐ 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* ScrollLineRectFill():
  15.      *
  16.      *    Fill a rectangular portion of the window raster with the help
  17.      *    of the scrolling information.
  18.      */
  19.  
  20. VOID __regargs
  21. ScrollLineRectFill(struct RastPort *RPort,WORD MinX,WORD MinY,WORD MaxX,WORD MaxY)
  22. {
  23.     if(RPort -> BitMap -> Depth == 1)
  24.         RectFill(RPort,MinX,MinY,MaxX,MaxY);
  25.     else
  26.     {
  27.         if(MinX < MaxX)
  28.         {
  29.             /* Is there anything on the screen at all? */
  30.  
  31.             if(ScrollLineFirst <= ScrollLineLast)
  32.             {
  33.                 WORD    ScrollLineMask    = 0,
  34.                     ScrollLineLeft    = 32767,
  35.                     ScrollLineRight    = 0,
  36.                     Temp,i;
  37.  
  38.                     /* Determine screen colour mask. */
  39.  
  40.                 for(i = MinY / TextFontHeight ; i <= MaxY / TextFontHeight ; i++)
  41.                 {
  42.                     if(ScrollLines[i] . Width)
  43.                     {
  44.                         if((Temp = ScrollLines[i] . Left * ScrollLines[i] . Width) < ScrollLineLeft)
  45.                             ScrollLineLeft = Temp;
  46.  
  47.                         if((Temp = (ScrollLines[i] . Right * ScrollLines[i] . Width) - 1) > ScrollLineRight)
  48.                             ScrollLineRight = Temp;
  49.  
  50.                         ScrollLineMask |= ScrollLines[i] . ColourMask;
  51.                     }
  52.                 }
  53.  
  54.                     /* Wrap the bits. */
  55.  
  56.                 ScrollLineMask &= (1 << Screen -> RastPort . BitMap -> Depth) - 1;
  57.  
  58.                     /* Did we get a sensible colour? */
  59.  
  60.                 if(ScrollLineMask && ScrollLineLeft <= ScrollLineRight)
  61.                 {
  62.                         /* Determine new left margin. */
  63.  
  64.                     if(ScrollLineLeft > MinX)
  65.                         MinX = ScrollLineLeft;
  66.  
  67.                         /* Determine new right margin. */
  68.  
  69.                     if(ScrollLineRight < MaxX)
  70.                         MaxX = ScrollLineRight;
  71.  
  72.                         /* Determine new top line margin. */
  73.  
  74.                     if((Temp = ScrollLineFirst * TextFontHeight) > MinY)
  75.                         MinY = Temp;
  76.  
  77.                         /* Determine new bottom line margin. */
  78.  
  79.                     if((Temp = ((ScrollLineLast + 1) * TextFontHeight) - 1) < MaxY)
  80.                         MaxY = Temp;
  81.  
  82.                         /* Set the colour mask. */
  83.  
  84.                     if(!(Config . DisableBlinking & TERMINAL_FASTER))
  85.                         SetWrMsk(RPort,ScrollLineMask);
  86.  
  87.                         /* And clear the raster. */
  88.  
  89.                     if(MinX < MaxX && MinY < MaxY)
  90.                     {
  91.                         if(MaxX == ScrollLineRight)
  92.                             RectFill(RPort,MinX,MinY,MaxX + 4,MaxY);
  93.                         else
  94.                             RectFill(RPort,MinX,MinY,MaxX,MaxY);
  95.                     }
  96.                 }
  97.             }
  98.         }
  99.     }
  100. }
  101.  
  102.     /* ScrollLineRaster():
  103.      *
  104.      *    Scroll the window raster with the help
  105.      *    of the scrolling information.
  106.      */
  107.  
  108. VOID __regargs
  109. ScrollLineRaster(struct RastPort *RPort,WORD DeltaX,WORD DeltaY,WORD MinX,WORD MinY,WORD MaxX,WORD MaxY)
  110. {
  111.     if(RPort -> BitMap -> Depth == 1)
  112.         ScrollRaster(RPort,DeltaX,DeltaY,MinX,MinY,MaxX,MaxY);
  113.     else
  114.     {
  115.         if(MinX < MaxX)
  116.         {
  117.             WORD ScrollLineMask;
  118.  
  119.                 /* Are we to scroll a line in horizontal direction? If so, use the
  120.                  * colour mask of the current line.
  121.                  */
  122.  
  123.             if(DeltaX)
  124.             {
  125.                 if(ScrollLineMask = ScrollLines[CursorY] . ColourMask & ((1 << Screen -> RastPort . BitMap -> Depth) - 1))
  126.                 {
  127.                         /* Set the colour mask. */
  128.  
  129.                     if(!(Config . DisableBlinking & TERMINAL_FASTER))
  130.                         SetWrMsk(RPort,ScrollLineMask);
  131.  
  132.                         /* And scroll the raster. */
  133.  
  134.                     ScrollRaster(RPort,DeltaX,DeltaY,MinX,MinY,MaxX,MaxY);
  135.                 }
  136.             }
  137.             else
  138.             {
  139.                     /* Any data on screen worth scrolling? */
  140.  
  141.                 if(ScrollLineFirst <= ScrollLineLast)
  142.                 {
  143.                     WORD Temp,First,Last,SaveMinY = MinY / TextFontHeight,SaveMaxY = MaxY / TextFontHeight,ScrollLineLeft = 32767,ScrollLineRight = 0,i;
  144.  
  145.                         /* Reset colourmask. */
  146.  
  147.                     ScrollLineMask = 0;
  148.  
  149.                         /* Build both the colour mask and the margins. */
  150.  
  151.                     for(i = MinY / TextFontHeight ; i <= MaxY / TextFontHeight ; i++)
  152.                     {
  153.                         if(ScrollLines[i] . Width)
  154.                         {
  155.                             if((Temp = ScrollLines[i] . Left * ScrollLines[i] . Width) < ScrollLineLeft)
  156.                                 ScrollLineLeft = Temp;
  157.  
  158.                             if((Temp = (ScrollLines[i] . Right * ScrollLines[i] . Width) - 1) > ScrollLineRight)
  159.                                 ScrollLineRight = Temp;
  160.  
  161.                             ScrollLineMask |= ScrollLines[i] . ColourMask;
  162.                         }
  163.                     }
  164.  
  165.                         /* Wrap the bits. */
  166.  
  167.                     ScrollLineMask &= (1 << Screen -> RastPort . BitMap -> Depth) - 1;
  168.  
  169.                         /* Sensible results? */
  170.  
  171.                     if(ScrollLineMask && ScrollLineLeft <= ScrollLineRight)
  172.                     {
  173.                             /* Determine new left margin. */
  174.  
  175.                         if(ScrollLineLeft > MinX)
  176.                             MinX = ScrollLineLeft;
  177.  
  178.                             /* Determine new right margin. */
  179.  
  180.                         if(ScrollLineRight < MaxX)
  181.                             MaxX = ScrollLineRight;
  182.  
  183.                             /* Scroll down or up? */
  184.  
  185.                         if(DeltaY < 0)
  186.                         {
  187.                                 /* So we are to scroll down, find the first
  188.                                  * blank line if any.
  189.                                  */
  190.  
  191.                             if((Temp = ScrollLineFirst * TextFontHeight) > MinY)
  192.                                 MinY = Temp;
  193.  
  194.                                 /* Find the last blank lines if any. */
  195.  
  196.                             if((Temp = ((ScrollLineLast + 1) * TextFontHeight) - DeltaY - 1) < MaxY)
  197.                                 MaxY = Temp;
  198.  
  199.                                 /* Determine margins and the like... */
  200.  
  201.                             Last    = (MaxY + 1) / TextFontHeight;
  202.                             First    = Last - ((MaxY - MinY + TextFontHeight + DeltaY) / TextFontHeight);
  203.                             Temp    = (-DeltaY) / TextFontHeight;
  204.  
  205.                                 /* Move the scroll line info up. */
  206.  
  207.                             for(i = Last - 1 ; i >= First ; i--)
  208.                                 ScrollLines[i] = ScrollLines[i - Temp];
  209.  
  210.                                 /* Clear the remaining lines. */
  211.  
  212.                             for(i = First - Temp ; i < First ; i++)
  213.                             {
  214.                                 ScrollLines[i] . Left        = 255;
  215.                                 ScrollLines[i] . Right        = 0;
  216.                                 ScrollLines[i] . ColourMask    = 0;
  217.                                 ScrollLines[i] . Width        = 0;
  218.                             }
  219.  
  220.                                 /* Is the first line we were working
  221.                                  * on the first line of the whole display?
  222.                                  * If so, update the line marker.
  223.                                  */
  224.  
  225.                             if(!SaveMinY)
  226.                                 ScrollLineFirst += Temp;
  227.  
  228.                                 /* Now take a look at the last line.
  229.                                  * If the last line we were working
  230.                                  * on is in fact the last line of the
  231.                                  * display, update the line marker.
  232.                                  */
  233.  
  234.                             if(SaveMaxY == LastLine)
  235.                             {
  236.                                 ScrollLineLast += Temp;
  237.  
  238.                                 if(ScrollLineLast > LastLine)
  239.                                     ScrollLineLast = LastLine;
  240.                             }
  241.                         }
  242.                         else
  243.                         {
  244.                                 /* So we are to scroll up, find the last
  245.                                  * blank line if any.
  246.                                  */
  247.  
  248.                             if((Temp = ((ScrollLineLast + 1) * TextFontHeight) - 1) < MaxY)
  249.                                 MaxY = Temp;
  250.  
  251.                                 /* Find the first blank lines if any. */
  252.  
  253.                             if((Temp = (ScrollLineFirst * TextFontHeight) - DeltaY) > MinY)
  254.                                 MinY = Temp;
  255.  
  256.                                 /* Determine margins and the like... */
  257.  
  258.                             First    = MinY / TextFontHeight;
  259.                             Last    = ((MaxY - MinY + TextFontHeight - DeltaY) / TextFontHeight);
  260.                             Temp    = DeltaY / TextFontHeight;
  261.  
  262.                                 /* Move the scroll line info down. */
  263.  
  264.                             for(i = First ; i < First + Last ; i++)
  265.                                 ScrollLines[i] = ScrollLines[i + Temp];
  266.  
  267.                                 /* Clear the remaining lines. */
  268.  
  269.                             for(i = First + Last ; i < First + Last + Temp ; i++)
  270.                             {
  271.                                 ScrollLines[i] . Left        = 255;
  272.                                 ScrollLines[i] . Right        = 0;
  273.                                 ScrollLines[i] . ColourMask    = 0;
  274.                                 ScrollLines[i] . Width        = 0;
  275.                             }
  276.  
  277.                                 /* Decrease number of last line. */
  278.  
  279.                             if(SaveMaxY == LastLine)
  280.                             {
  281.                                 if(ScrollLineLast > Temp)
  282.                                     ScrollLineLast -= Temp;
  283.                                 else
  284.                                     ScrollLineLast = 0;
  285.                             }
  286.  
  287.                                 /* Decrease number of first line. */
  288.  
  289.                             if(!SaveMinY)
  290.                             {
  291.                                 if(ScrollLineFirst > Temp)
  292.                                     ScrollLineFirst -= Temp;
  293.                                 else
  294.                                     ScrollLineFirst = 0;
  295.                             }
  296.                         }
  297.  
  298.                             /* Adapt possible changes in the lines for first and last line. */
  299.  
  300.                         while(ScrollLineFirst < RasterHeight)
  301.                         {
  302.                             if(ScrollLines[ScrollLineFirst] . Left > ScrollLines[ScrollLineFirst] . Right)
  303.                                 ScrollLineFirst++;
  304.                             else
  305.                                 break;
  306.                         }
  307.  
  308.                         while(ScrollLineLast > 0)
  309.                         {
  310.                             if(ScrollLines[ScrollLineLast] . Left > ScrollLines[ScrollLineLast] . Right)
  311.                                 ScrollLineLast--;
  312.                             else
  313.                                 break;
  314.                         }
  315.  
  316.                             /* Set the colour mask. */
  317.  
  318.                         if(!(Config . DisableBlinking & TERMINAL_FASTER))
  319.                             SetWrMsk(RPort,ScrollLineMask);
  320.  
  321.                             /* And scroll the raster. */
  322.  
  323.                         if(MinX < MaxX && MinY < MaxY)
  324.                         {
  325.                             if(MaxX == ScrollLineRight)
  326.                                 ScrollRaster(RPort,DeltaX,DeltaY,MinX,MinY,MaxX + 4,MaxY);
  327.                             else
  328.                                 ScrollRaster(RPort,DeltaX,DeltaY,MinX,MinY,MaxX,MaxY);
  329.                         }
  330.                     }
  331.                 }
  332.             }
  333.         }
  334.     }
  335. }
  336.  
  337.     /* ScrollLineEraseScreen(BYTE Mode):
  338.      *
  339.      *    Erase a part of the screen.
  340.      */
  341.  
  342. VOID __regargs
  343. ScrollLineEraseScreen(BYTE Mode)
  344. {
  345.     if(RPort -> BitMap -> Depth > 1)
  346.     {
  347.         WORD i;
  348.  
  349.         switch(Mode)
  350.         {
  351.                 /* Erase from first line to current cursor line (inclusive). */
  352.  
  353.             case 1:    ScrollLineFirst = CursorY;
  354.  
  355.                     /* Reset the lines. */
  356.  
  357.                 for(i = 0 ; i < CursorY ; i++)
  358.                 {
  359.                     ScrollLines[i] . Left        = 255;
  360.                     ScrollLines[i] . Right        = 0;
  361.                     ScrollLines[i] . ColourMask    = 0;
  362.                     ScrollLines[i] . Width        = 0;
  363.                 }
  364.  
  365.                 ScrollLines[CursorY] . Left = CursorX + 1;
  366.  
  367.                 if(ScrollLines[CursorY] . Right < ScrollLines[CursorY] . Left)
  368.                 {
  369.                     ScrollLines[CursorY] . Left    = 255;
  370.                     ScrollLines[CursorY] . Right    = 0;
  371.                 }
  372.  
  373.                 break;
  374.  
  375.                 /* Erase entire screen. */
  376.  
  377.             case 2:    for(i = 0 ; i < RasterHeight ; i++)
  378.                 {
  379.                     ScrollLines[i] . Left        = 255;
  380.                     ScrollLines[i] . Right        = 0;
  381.                     ScrollLines[i] . ColourMask    = 0;
  382.                     ScrollLines[i] . Width        = 0;
  383.                 }
  384.  
  385.                 ScrollLineFirst    = 255;
  386.                 ScrollLineLast    = 0;
  387.  
  388.                 break;
  389.  
  390.                 /* Erase from current cursor position to end of screen. */
  391.  
  392.             default:for(i = CursorY + 1 ; i < RasterHeight ; i++)
  393.                 {
  394.                     ScrollLines[i] . Left        = 255;
  395.                     ScrollLines[i] . Right        = 0;
  396.                     ScrollLines[i] . ColourMask    = 0;
  397.                     ScrollLines[i] . Width        = 0;
  398.                 }
  399.  
  400.                 if(CursorX)
  401.                 {
  402.                     ScrollLines[CursorY] . Right = CursorX;
  403.  
  404.                     if(ScrollLines[CursorY] . Right < ScrollLines[CursorY] . Left)
  405.                     {
  406.                         ScrollLines[CursorY] . Left    = 255;
  407.                         ScrollLines[CursorY] . Right    = 0;
  408.                     }
  409.                 }
  410.                 else
  411.                 {
  412.                     ScrollLines[CursorY] . Left    = 255;
  413.                     ScrollLines[CursorY] . Right    = 0;
  414.                 }
  415.  
  416.                     /* Cleared the entire screen? */
  417.  
  418.                 if(CursorY)
  419.                     ScrollLineLast = CursorY;
  420.                 else
  421.                 {
  422.                     ScrollLineFirst    = 255;
  423.                     ScrollLineLast    = 0;
  424.                 }
  425.  
  426.                 break;
  427.         }
  428.  
  429.             /* Adapt possible changes in the lines for first and last line. */
  430.  
  431.         while(ScrollLineFirst < RasterHeight)
  432.         {
  433.             if(ScrollLines[ScrollLineFirst] . Left > ScrollLines[ScrollLineFirst] . Right)
  434.                 ScrollLineFirst++;
  435.             else
  436.                 break;
  437.         }
  438.  
  439.         while(ScrollLineLast > 0)
  440.         {
  441.             if(ScrollLines[ScrollLineLast] . Left > ScrollLines[ScrollLineLast] . Right)
  442.                 ScrollLineLast--;
  443.             else
  444.                 break;
  445.         }
  446.     }
  447. }
  448.  
  449.     /* ScrollLineEraseLine(BYTE Mode):
  450.      *
  451.      *    Erase parts of the current cursor line.
  452.      */
  453.  
  454. VOID __regargs
  455. ScrollLineEraseLine(BYTE Mode)
  456. {
  457.     if(RPort -> BitMap -> Depth > 1)
  458.     {
  459.         switch(Mode)
  460.         {
  461.                 /* Erase from left margin to current cursor position (inclusive). */
  462.  
  463.             case 1:    ScrollLines[CursorY] . Left = CursorX + 1;
  464.                 break;
  465.  
  466.                 /* Erase entire line. */
  467.  
  468.             case 2:    ScrollLines[CursorY] . Left    = 255;
  469.                 ScrollLines[CursorY] . Right    = 0;
  470.  
  471.                 break;
  472.  
  473.                 /* Erase from current cursor position towards end of line. */
  474.  
  475.             default:if(CursorX)
  476.                     ScrollLines[CursorY] . Right = CursorX;
  477.                 else
  478.                 {
  479.                     ScrollLines[CursorY] . Left    = 255;
  480.                     ScrollLines[CursorY] . Right    = 0;
  481.                 }
  482.  
  483.                 break;
  484.         }
  485.  
  486.             /* Adapt possible changes in the lines for first and last line. */
  487.  
  488.         while(ScrollLineFirst < RasterHeight)
  489.         {
  490.             if(ScrollLines[ScrollLineFirst] . Left > ScrollLines[ScrollLineFirst] . Right)
  491.                 ScrollLineFirst++;
  492.             else
  493.                 break;
  494.         }
  495.  
  496.         while(ScrollLineLast > 0)
  497.         {
  498.             if(ScrollLines[ScrollLineLast] . Left > ScrollLines[ScrollLineLast] . Right)
  499.                 ScrollLineLast--;
  500.             else
  501.                 break;
  502.         }
  503.     }
  504. }
  505.  
  506.     /* ScrollLineEraseCharacters(WORD Chars):
  507.      *
  508.      *    Erase a number of characters in the current cursor line.
  509.      */
  510.  
  511. VOID __regargs
  512. ScrollLineEraseCharacters(WORD Chars)
  513. {
  514.     if(RPort -> BitMap -> Depth > 1)
  515.     {
  516.             /* Any characters to erase? */
  517.  
  518.         if(ScrollLines[CursorY] . Right)
  519.             ScrollLines[CursorY] . Right -= Chars;
  520.     }
  521. }
  522.  
  523.     /* ScrollLineShiftChar(WORD Size):
  524.      *
  525.      *    Shift the characters following the current cursor position
  526.      *    Size characters to the right.
  527.      */
  528.  
  529. VOID __regargs
  530. ScrollLineShiftChar(WORD Size)
  531. {
  532.     if(RPort -> BitMap -> Depth > 1)
  533.     {
  534.             /* Any characters to scroll? */
  535.  
  536.         if(ScrollLines[CursorY] . Right > 0)
  537.             ScrollLines[CursorY] . Right += Size;
  538.     }
  539. }
  540.  
  541.     /* ScrollLinePutString(WORD Length):
  542.      *
  543.      *    Update the line info according to the length of a string
  544.      *    to be printed.
  545.      */
  546.  
  547. VOID __regargs
  548. ScrollLinePutString(WORD Length)
  549. {
  550.     if(RPort -> BitMap -> Depth > 1)
  551.     {
  552.         BYTE Width;
  553.  
  554.             /* Which scale is the font we are currently using? */
  555.  
  556.         if(RasterAttr[CursorY] >= SCALE_ATTR_TOP2X)
  557.         {
  558.                 /* Valid length? */
  559.  
  560.             if(CursorX + Length >= RasterWidth / 2)
  561.                 Length = (RasterWidth / 2) - CursorX;
  562.  
  563.                 /* Double width. */
  564.  
  565.             Width = TextFontWidth * 2;
  566.         }
  567.         else
  568.         {
  569.             if(Config . FontScale == SCALE_HALF)
  570.             {
  571.                     /* Valid length? */
  572.  
  573.                 if(CursorX + Length >= RasterWidth * 2)
  574.                     Length = (RasterWidth * 2) - CursorX;
  575.  
  576.                     /* Half width. */
  577.  
  578.                 Width = TextFontWidth / 2;
  579.             }
  580.             else
  581.             {
  582.                     /* Valid length? */
  583.  
  584.                 if(CursorX + Length >= RasterWidth)
  585.                     Length = RasterWidth - CursorX;
  586.  
  587.                     /* Normal width. */
  588.  
  589.                 Width = TextFontWidth;
  590.             }
  591.         }
  592.  
  593.             /* Sensible value? */
  594.  
  595.         if(Length > 0)
  596.         {
  597.             struct ScrollLineInfo *Alias = &ScrollLines[CursorY];
  598.  
  599.                 /* Update line colour mask. */
  600.  
  601.             Alias -> ColourMask |= (RPort -> FgPen|RPort -> BgPen);
  602.  
  603.                 /* Update font scale. */
  604.  
  605.             Alias -> Width = Width;
  606.  
  607.                 /* Set write mask (will affect Text() since it is called
  608.                  * after this routine has finished.
  609.                  */
  610.  
  611.             if(!(Config . DisableBlinking & TERMINAL_FASTER))
  612.                 SetWrMsk(RPort,Alias -> ColourMask);
  613.  
  614.                 /* Update right margin. */
  615.  
  616.             if(CursorX < Alias -> Left)
  617.                 Alias -> Left = CursorX;
  618.  
  619.                 /* Update left margin. */
  620.  
  621.             if(CursorX + Length > Alias -> Right)
  622.                 Alias -> Right = CursorX + Length;
  623.  
  624.                 /* Update topmost line. */
  625.  
  626.             if(CursorY < ScrollLineFirst)
  627.                 ScrollLineFirst = CursorY;
  628.  
  629.                 /* Update bottommost line. */
  630.  
  631.             if(CursorY > ScrollLineLast)
  632.                 ScrollLineLast = CursorY;
  633.         }
  634.     }
  635. }
  636.