home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff214.lzh / MandelVroom / src / scroll.c < prev    next >
C/C++ Source or Header  |  1989-05-30  |  14KB  |  537 lines

  1. /*
  2.  * MandelVroom 2.0
  3.  *
  4.  * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Permission is hereby granted to distribute this program's source
  9.  * executable, and documentation for non-comercial purposes, so long as the
  10.  * copyright notices are not removed from the sources, executable or
  11.  * documentation.  This program may not be distributed for a profit without
  12.  * the express written consent of the author Kevin L. Clague.
  13.  *
  14.  * This program is not in the public domain.
  15.  *
  16.  * Fred Fish is expressly granted permission to distribute this program's
  17.  * source and executable as part of the "Fred Fish freely redistributable
  18.  * Amiga software library."
  19.  *
  20.  * Permission is expressly granted for this program and it's source to be
  21.  * distributed as part of the Amicus Amiga software disks, and the
  22.  * First Amiga User Group's Hot Mix disks.
  23.  *
  24.  * contents: this file contains the functions used to implement MandelVroom's
  25.  * pan command.  It seems to have a bug when resizing pictures slightly
  26.  * smaller.
  27.  */
  28.  
  29. #include "mandp.h"
  30.  
  31. static int ScrollHotX, ScrollHotY;
  32.  
  33. UBYTE ScrollOn = 1;
  34.  
  35. #ifdef TEMPWINDOW
  36. #define SAFEBLIT
  37.  
  38. static struct NewWindow NewTemp = {
  39.    0,12,                     /* start position           */
  40.    80,80,                    /* width, height            */
  41.    (UBYTE) 0, (UBYTE) NORMALPEN,
  42.    MOUSEBUTTONS,             /* IDCMP flags              */
  43.                              /* MandWind flags           */
  44.    WINDOWDRAG | NOCAREREFRESH | SMART_REFRESH,
  45.    (struct Gadget *) NULL,   /* first gadget             */
  46.    (struct Image *) NULL,    /* user checkmark           */
  47.    (UBYTE *) NULL,           /* Title                    */
  48.    (struct Screen *) NULL,   /* pointer to screen        */
  49.    (struct BitMap *) NULL,   /* pointer to superbitmap   */
  50.    20,20,-1,-1,              /* sizing                   */
  51.    CUSTOMSCREEN              /* type of screen           */
  52.    };
  53.  
  54. static struct Window *TempWind;
  55. #endif
  56.  
  57. ScrollPictCmd(Msg)
  58.   struct IntuiMessage *Msg;
  59. {
  60.   struct Window *Window;
  61.   static struct Picture *Pict;
  62.  
  63.   Window = Msg->IDCMPWindow;
  64.   Pict = (struct Picture *) Window->UserData;
  65.  
  66.   switch( Msg->Class ) {
  67.     case NEWSIZE:
  68.          if (CurPict && (CurPict->Flags & SCROLL_HAPPENED)) {
  69.            MoveClipImage(CurPict);
  70.          }
  71.          break;
  72.  
  73.     case MENUPICK:
  74.          switch( SUBNUM(Msg->Code) ) {
  75.            case SETSCROLL:
  76.                 State = SCROLLPICTSTATE;
  77.                 ThrowTask(CurPict);
  78.                 if ( ! (CurPict->Flags & SCROLL_HAPPENED)) {
  79.  
  80.                   if ( AllocScrollTemp(CurPict) == UNSUCCESSFUL ) {
  81.                     return;
  82.                   }
  83.                   SaveInitialImage(CurPict);
  84.                 }
  85.                 CurPict->Flags |= SCROLL_HAPPENED;
  86.                 SetToPointer();
  87.                 break;
  88.  
  89.            case GENSCROLL:
  90.                 if (CurPict && CurPict->Flags & SCROLL_HAPPENED) {
  91.                   Generate(CurPict);
  92.                 }
  93.                 break;
  94.  
  95.            case CANCELSCROLL:
  96.                 ReColor(CurPict);
  97.                 break;
  98.          }
  99.          break;
  100.  
  101.     case MOUSEBUTTONS:
  102.          switch( Msg->Code ) {
  103.  
  104.            case SELECTDOWN:                   /* start drag */
  105.                 if (Pict == NULL || Pict != CurPict) {
  106.                   return;
  107.                 }
  108.                 ScrollHotX = MouseX - CurPict->ImageLoc.Left;
  109.                 ScrollHotY = MouseY - CurPict->ImageLoc.Top;
  110.                 Scroll( CurPict);
  111.                 ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
  112.                 break;
  113.  
  114.            case SELECTUP:                     /* stop slide */
  115.                 ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
  116.                 break;
  117.          }
  118.          break;
  119.  
  120.     case MOUSEMOVE:
  121.          Scroll( CurPict);
  122.          break;
  123.   }
  124. }
  125.  
  126. SaveInitialImage(Pict)
  127.   struct Picture *Pict;
  128. {
  129. #ifdef SAFEBLIT
  130.   SafeClipBlit(Pict->Window,  Pict->LeftMarg, Pict->TopMarg,
  131.                TempWind,      0,            0,
  132.                               Pict->CountX, Pict->CountY,
  133.                               0xc0, __LINE__);
  134. #else
  135.   ClipBlit(Pict->Window->RPort, Pict->LeftMarg, Pict->TopMarg,
  136.            &Pict->ScrollRp,           0,            0,
  137.                                 Pict->CountX, Pict->CountY,
  138.                                 0xc0);
  139. #endif
  140. }
  141.  
  142. Scroll( Pict )
  143.   struct Picture *Pict;
  144. {
  145.   CalcNewLoc(Pict,MouseX,MouseY); /* figure out location of new image */
  146.   MoveClipImage(Pict);
  147. }
  148.  
  149. CalcNewLoc(Pict, MouseX, MouseY)
  150.   register struct Picture *Pict;
  151.   int MouseX, MouseY;
  152. {
  153.   /* set new ImageLoc */
  154.  
  155.   Pict->ImageLoc.Top    = MouseY - ScrollHotY;
  156.   Pict->ImageLoc.Left   = MouseX - ScrollHotX;
  157.   Pict->ImageLoc.Bot    = Pict->ImageLoc.Top  + Pict->CountY;
  158.   Pict->ImageLoc.Right  = Pict->ImageLoc.Left + Pict->CountX;
  159. }
  160.  
  161. MoveClipImage(Pict)
  162.   register struct Picture  *Pict;
  163. {
  164.   struct Window   *Window;
  165.   struct RastPort *wind_Rp, *tmp_Rp;
  166.  
  167.   register int POLeft, PORight, POTop, POBot;
  168.  
  169.   struct Rect  SaveRect;
  170.   struct Rect  DispRect;
  171.  
  172.   Window = Pict->Window;
  173.  
  174.   SaveRect = Pict->ClipImage; /* struct assign */
  175.  
  176.   DispRect.Left  = Pict->LeftMarg;
  177.   DispRect.Top   = Pict->TopMarg;
  178.   DispRect.Right = Window->Width - Pict->RightMarg - 1;
  179.   DispRect.Bot   = Window->Height - Pict->BotMarg - 1;
  180.  
  181.   if (Pict->ImageLoc.Left  > DispRect.Right ||
  182.       Pict->ImageLoc.Top   > DispRect.Bot   ||
  183.       Pict->ImageLoc.Right < DispRect.Left  ||
  184.       Pict->ImageLoc.Bot   < DispRect.Top   ) {
  185.  
  186.     return;
  187.   }
  188.  
  189.   if (Pict->ImageLoc.Left < DispRect.Left) {
  190.     Pict->ClipImage.Left =  DispRect.Left;
  191.     POLeft = -Pict->ImageLoc.Left + Pict->LeftMarg;
  192.   } else {
  193.     Pict->ClipImage.Left =  Pict->ImageLoc.Left;
  194.     POLeft =  0;
  195.   }
  196.  
  197.   if (Pict->ImageLoc.Top < DispRect.Top) {
  198.     Pict->ClipImage.Top = DispRect.Top;
  199.     POTop = -Pict->ImageLoc.Top + Pict->TopMarg;
  200.   } else {
  201.     Pict->ClipImage.Top = Pict->ImageLoc.Top;
  202.     POTop = 0;
  203.   }
  204.  
  205.   if (Pict->ImageLoc.Right <= DispRect.Right) {
  206.     Pict->ClipImage.Right = Pict->ImageLoc.Right;
  207.     PORight = Pict->CountX-1;
  208.   } else {
  209.     Pict->ClipImage.Right = DispRect.Right;
  210.     PORight = DispRect.Right - Pict->ImageLoc.Left;
  211.   }
  212.  
  213.   if (Pict->ImageLoc.Bot <= DispRect.Bot) {
  214.     Pict->ClipImage.Bot = Pict->ImageLoc.Bot;
  215.     POBot = Pict->CountY - 1;
  216.   } else {
  217.     Pict->ClipImage.Bot = DispRect.Bot;
  218.     POBot = DispRect.Bot - Pict->ImageLoc.Top;
  219.   }
  220.  
  221.   wind_Rp = Window->RPort;
  222.  
  223. #ifdef TEMPWINDOW
  224.   tmp_Rp = TempWind->RPort;
  225. #else
  226.   tmp_Rp = &Pict->ScrollRp;
  227. #endif
  228.  
  229.   if (POLeft < PORight && POTop < POBot) {
  230.  
  231.   /* Now copy temp rastport data to window */
  232.  
  233. #ifdef SAFEBLIT
  234.     SafeClipBlit(TempWind, POLeft, POTop, Window,
  235.                        Pict->ClipImage.Left, Pict->ClipImage.Top,
  236.                        PORight - POLeft + 1, POBot - POTop + 1, 0xc0,
  237.                        __LINE__);
  238. #else
  239.     ClipBlit(tmp_Rp,   POLeft, POTop, wind_Rp,
  240.                        Pict->ClipImage.Left, Pict->ClipImage.Top,
  241.                        PORight - POLeft + 1, POBot - POTop + 1, 0xc0);
  242. #endif
  243.  
  244. #if 0
  245.     printf("l %d t %d r %d b %d\n",POLeft, POTop, PORight, POBot);
  246.     printf("width %d height %d\n",
  247.             PORight - POLeft + 1, POBot - POTop + 1);
  248. #endif
  249.   }
  250.  
  251.   Pict->DataClip.Left  = POLeft;
  252.   Pict->DataClip.Right = PORight;
  253.   Pict->DataClip.Top   = POTop;
  254.   Pict->DataClip.Bot   = POBot;
  255.  
  256.   /* Undraw the old picture */
  257.  
  258.   SetAPen(wind_Rp, 0);
  259.  
  260.   if (Pict->ClipImage.Left > SaveRect.Left) {
  261.  
  262.     FillCheck(Window, SaveRect.Left, SaveRect.Top,
  263.                       Pict->ClipImage.Left, SaveRect.Bot);
  264.   } else
  265.   if (Pict->ClipImage.Right < SaveRect.Right) {
  266.  
  267.     FillCheck(Window, Pict->ClipImage.Right, Pict->ClipImage.Top,
  268.                       SaveRect.Right, SaveRect.Bot);
  269.   }
  270.  
  271.   if (Pict->ClipImage.Top > SaveRect.Top) {
  272.  
  273.     FillCheck(Window, SaveRect.Left, SaveRect.Top,
  274.                       SaveRect.Right, Pict->ClipImage.Top);
  275.   } else
  276.   if (Pict->ClipImage.Bot < SaveRect.Bot) {
  277.  
  278.     FillCheck(Window, SaveRect.Left,  Pict->ClipImage.Bot,
  279.                       SaveRect.Right, SaveRect.Bot);
  280.   }
  281. }
  282.  
  283. FillCheck(Window,src_x,src_y,dst_x,dst_y)
  284.   struct Window *Window;
  285.   int src_x,src_y,dst_x,dst_y;
  286. {
  287.   if (src_x < 0 || src_x > Window->Width) {
  288. #ifdef DEBUG
  289.     printf("Bad Fill src_x %d Width %d\n",
  290.             src_x,Window->Width);
  291. #endif
  292.     return;
  293.   }
  294.  
  295.   if (src_y < 0 || src_y > Window->Height) {
  296. #ifdef DEBUG
  297.     printf("Bad Fill src_y %d Height %d\n",
  298.             src_y,Window->Height);
  299. #endif
  300.     return;
  301.   }
  302.  
  303.   if (dst_x < 0 || dst_x > Window->Width) {
  304. #ifdef DEBUG
  305.     printf("Bad Fill dst_x %d Width %d\n",
  306.             dst_x,Window->Width);
  307. #endif
  308.     return;
  309.   }
  310.  
  311.   if (dst_y < 0 || dst_y > Window->Height) {
  312. #ifdef DEBUG
  313.     printf("Bad Fill dst_y %d Height %d\n",
  314.             dst_y,Window->Height);
  315. #endif
  316.     return;
  317.   }
  318.   if (src_x > dst_x) {
  319. #ifdef DEBUG
  320.     printf("inverted rect fill\n");
  321. #endif
  322.     return;
  323.   }
  324.   if (src_y > dst_y) {
  325. #ifdef DEBUG
  326.     printf("end for end flipped rect fill\n");
  327. #endif
  328.     return;
  329.   }
  330.   RectFill(Window->RPort, src_x,src_y,dst_x,dst_y);
  331. }
  332.  
  333. AllocScrollTemp( Pict )
  334.   register struct Picture *Pict;
  335. {
  336.   LONG Plane;
  337.   PLANEPTR t;
  338.  
  339.   extern struct MenuItem ScrollSub[];
  340.  
  341.   static ScrollInited;
  342.  
  343.   extern struct NewScreen NewScreen;
  344.  
  345.   if ( !ScrollOn )
  346.     return;
  347.  
  348. #ifdef TEMPWINDOW
  349.  
  350.   NewTemp.Width    = Pict->Window->Width;
  351.   NewTemp.Height   = Pict->Window->Height;
  352.   NewTemp.LeftEdge = NewScreen.Width - NewTemp.Width-2;
  353.   NewTemp.TopEdge  = 0;
  354.   NewTemp.Screen   = screen;
  355.   TempWind         = OpenWindow( &NewTemp );
  356. /*WindowToBack( TempWind );*/
  357.   return( SUCCESSFUL );
  358.  
  359. #else
  360.  
  361.   if ( Pict->ScrollRp.BitMap == NULL ) {
  362.  
  363.     InitRastPort( &Pict->ScrollRp );
  364.     Pict->ScrollRp.BitMap = &Pict->ScrollBitMap;
  365.   }
  366.  
  367.   InitBitMap( &Pict->ScrollBitMap, (long) NewScreen.Depth,
  368.                Pict->CountX, Pict->CountY);
  369.  
  370.   for (Plane = 0; Plane < NewScreen.Depth; Plane++) {
  371.  
  372.     t = (PLANEPTR) AllocRaster(Pict->CountX, Pict->CountY);
  373.     Pict->ScrollBitMap.Planes[Plane] = (PLANEPTR) t;
  374.  
  375.     if (t == NULL) {
  376.       FreeScrollTemp( Pict );
  377.       return(UNSUCCESSFUL);
  378.     }
  379.   }
  380.   return(SUCCESSFUL);
  381. #endif
  382. }
  383.  
  384. FreeScrollTemp( Pict )
  385.   struct Picture *Pict;
  386. {
  387.   LONG Plane;
  388.  
  389.   if (Pict->Flags & SCROLL_HAPPENED) {
  390.  
  391. #ifdef TEMPWINDOW
  392.     CloseWindow( TempWind );
  393. #else
  394.  
  395.     for (Plane = 0; Plane < Pict->ScrollBitMap.Depth; Plane++) {
  396.  
  397.       if (Pict->ScrollBitMap.Planes[Plane]) {
  398.  
  399.         FreeRaster( (char *) Pict->ScrollBitMap.Planes[Plane],
  400.                     Pict->CountX,Pict->CountY);
  401.         Pict->ScrollBitMap.Planes[Plane] = NULL;
  402.       }
  403.     }
  404. #endif
  405.   }
  406.   ResetScrollRects(Pict);
  407. }
  408.  
  409. ResetScrollRects(Pict)
  410.   struct Picture *Pict;
  411. {
  412.   Pict->Flags &= ~SCROLL_HAPPENED;
  413.  
  414.   Pict->ImageLoc.Left   = Pict->LeftMarg;
  415.   Pict->ImageLoc.Top    = Pict->TopMarg;
  416.   Pict->ImageLoc.Right  = Pict->LeftMarg + Pict->CountX - 1;
  417.   Pict->ImageLoc.Bot    = Pict->TopMarg  + Pict->CountY - 1;
  418.  
  419.   Pict->ClipImage = Pict->ImageLoc; /* struct assignment */
  420. }
  421.  
  422. #ifdef SAFEBLIT
  423. static
  424. SafeClipBlit( src_Wind, src_x, src_y,
  425.               dst_Wind, dst_x, dst_y,
  426.               width, height, min_terms,
  427.               line_no )
  428.  
  429.   struct Window *src_Wind, *dst_Wind;
  430.   LONG   src_x, src_y, dst_x, dst_y, width, height, min_terms;
  431.   LONG   line_no;
  432. {
  433.  
  434.   if (src_x < 0 || src_x > src_Wind->Width) {
  435.     printf("Line %d Bad blit src_x %d Width %d\n",
  436.             line_no,src_x,src_Wind->Width);
  437.     return;
  438.   }
  439.  
  440.   if (src_y < 0 || src_y > src_Wind->Height) {
  441.     printf("Line %d Bad blit src_y %d Height %d\n",
  442.             line_no, src_y,src_Wind->Height);
  443.     return;
  444.   }
  445.  
  446.   if (width < 1 || width > src_Wind->Width) {
  447.     printf("Line %d Bad blit width %d\n",line_no, width);
  448.     return;
  449.   }
  450.  
  451.   if (src_x + width > src_Wind->Width) {
  452.     printf("Line %d Blit outside %d Width %d \n",
  453.             line_no,src_x+width,src_Wind->Width);
  454.     return;
  455.   }
  456.  
  457.   if (height < 1 || height > src_Wind->Height) {
  458.     printf("Line %d Bad blit height %d\n",line_no,height);
  459.     return;
  460.   }
  461.  
  462.   if (src_y + height > src_Wind->Height) {
  463.     printf("Line %d Blit outside %d Height %d \n",
  464.             line_no,src_y+height,src_Wind->Height);
  465.     return;
  466.   }
  467.  
  468.   ClipBlit( src_Wind->RPort, src_x, src_y,
  469.             dst_Wind->RPort, dst_x, dst_y,
  470.             width, height, min_terms);
  471. }
  472. #endif
  473.  
  474. ScrollComplex(Pict)
  475.   struct Picture *Pict;
  476. {
  477.   int left, top;
  478.   int count_x, count_y;
  479.   SHORT *NewCounts;
  480.  
  481.   count_x = Pict->Window->Width  - Pict->LeftMarg - Pict->RightMarg;
  482.   count_y = Pict->Window->Height - Pict->BotMarg  - Pict->TopMarg;
  483.  
  484.   NewCounts = (SHORT *) safeAllocMem(count_x*count_y*sizeof(SHORT),MEMF_CLEAR);
  485.  
  486.   if (NewCounts == NULL) {
  487.     DispErrMsg("Can't scroll. Out of RAM.",0);
  488.     return;
  489.   }
  490.  
  491.   ScrollData(Pict, NewCounts, count_x, count_y);
  492.  
  493.   FreeCounts( Pict );
  494.  
  495.   left  = Pict->ImageLoc.Left  - Pict->LeftMarg;
  496.   top   = Pict->ImageLoc.Top   - Pict->TopMarg;
  497.  
  498.   Pict->RealLow  -= Pict->RealGap * left;
  499.   Pict->ImagLow  -= Pict->ImagGap * top;
  500.   Pict->RealHigh  = Pict->RealLow + Pict->RealGap * count_x;
  501.   Pict->ImagHigh  = Pict->ImagLow + Pict->ImagGap * count_y;
  502.  
  503.   FreeScrollTemp(Pict);
  504.  
  505.   Pict->Counts = NewCounts;
  506.   Pict->CountX = count_x;
  507.   Pict->CountY = count_y;
  508.   Pict->CountsSize = count_x * count_y * sizeof(*Pict->Counts);
  509.   Pict->CurLine = 0;
  510. }
  511.  
  512. ScrollData(Pict, NewCounts, width, height)
  513.   register struct Picture *Pict;
  514.   SHORT *NewCounts;
  515.   int width, height;
  516. {
  517.   int sr,sc;
  518.   register SHORT *s_rowp, *d_rowp, *sp, *dp;
  519.  
  520.   s_rowp = Pict->Counts +  Pict->DataClip.Top * Pict->CountX;
  521.   d_rowp = NewCounts    + (Pict->ClipImage.Top-Pict->TopMarg) * width;
  522.  
  523.   for (sr = Pict->DataClip.Top; sr < Pict->DataClip.Bot; sr++) {
  524.  
  525.     dp = d_rowp + Pict->ClipImage.Left - Pict->LeftMarg;
  526.     sp = s_rowp + Pict->DataClip.Left;
  527.  
  528.     for (sc = Pict->DataClip.Left; sc < Pict->DataClip.Right; sc++) {
  529.  
  530.       *dp++ = *sp++;
  531.     }
  532.     s_rowp += Pict->CountX;
  533.     d_rowp += width;
  534.   }
  535. }
  536.  
  537.