/*----------------------------------------------------------------------------*
 *                                                                            *
 *  AGA-Morph-Gfx.c V1.2                                                      *
 *                                                                            *
 *----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/

#include <libraries/diskfont.h>
#include <intuition/intuition.h>
#include <intuition/classes.h>
#include <intuition/pointerclass.h>
#include <datatypes/pictureclass.h>
#include <datatypes/pictureclassext.h>
#include <graphics/gfx.h>
#include <exec/memory.h>
#include <libraries/asl.h>
#include <clib/macros.h>

#include "AGA-Morph-Language.h"
#include "AGA-Morph-Struct.h"

/*----------------------------------------------------------------------------*/

#define mm 0x80808080
#define md 0x10101010
#define mb 0xf0f0f0f0
#define pl 0xd7d7d7d7
#define pm 0x7f7f7f7f
#define pd 0x17171717

/*----------------------------------------------------------------------------*/

extern struct DPoint Points;
extern struct Gadget EditWindowBar1,EditWindowBar2,InfoCloseButton,PointsButton,
              ViewWindowBar1,ViewWindowBar2,ZoomButton;
extern struct Image InfoImage;
extern struct IntuiText InfoError,MemoryError,InfoText,InfoText06,InfoText07,
              InfoText10,InfoText11,InfoText14,InfoText15,InfoText18,InfoText20;
extern struct MPoint *Point1;
extern struct Pic Picture1,Picture2,Picture3;
extern struct PropInfo EditWindowBar1p,EditWindowBar2p,ViewWindowBar1p,
              ViewWindowBar2p;
extern struct RastPort temprp;
extern struct Screen *MorphScreen;
extern struct StringInfo PointsBp;
extern struct Window *CommandWindow,*EditWindow,*ErrorWindow,*ViewWindow;
extern LONG i,x,x1,x2,xmax,xstart,y,y1,y2,ymax,ystart;
extern UBYTE Matrix[64],Array[2048];
extern ULONG b,c,d,g,Height,r,Width;

/*----------------------------------------------------------------------------*/

void ShowInfo();
void SetPlatte();
void MouseColors(BYTE Pal);
void RethinkSliderView(struct Pic *Picture);
void RethinkSliderEdit(struct Pic *Picture);
void RethinkSliderSpinEdit();
struct Pic *DisplayPic(struct Pic *Picture,struct Window *DWin);
struct Pic *DisplaySpinPic(struct Pic *Picture1,struct Pic *Picture2,struct Window *DWin);

/*----------------------------------------------------------------------------*/

void
ShowInfo()
{
  struct IntuiMessage *Mess2;
  if (ErrorWindow=(struct Window *) OpenWindowTags(NULL,
                                                   WA_Left,          (Width-334)/2,
                                                   WA_Top,           (Height-234)/2,
                                                   WA_Width,         334,
                                                   WA_Height,        234,
                                                   WA_Title,         InfoHeader,
                                                   WA_CustomScreen,  MorphScreen,
                                                   WA_Gadgets,       &InfoCloseButton,
                                                   WA_Activate,      TRUE,
                                                   WA_GimmeZeroZero, TRUE,
                                                   WA_IDCMP,         IDCMP_GADGETUP,
                                                   TAG_END))
  {
    DisableAll();
    while (Mess2=(struct IntuiMessage *) GetMsg(CommandWindow->UserPort))
    {
      ReplyMsg((struct Message *) Mess2);
    }
    WDez((char *)InfoText06.IText,Picture1.width);
    WDez((char *)InfoText06.IText+8,Picture1.height);
    Dez((char *)InfoText07.IText+3,3*Picture1.width*Picture1.height);

    WDez((char *)InfoText10.IText,Picture2.width);
    WDez((char *)InfoText10.IText+8,Picture2.height);
    Dez((char *)InfoText11.IText+3,3*Picture2.width*Picture2.height);

    WDez((char *)InfoText14.IText,Picture3.width);
    WDez((char *)InfoText14.IText+8,Picture3.height);
    Dez((char *)InfoText15.IText+3,3*Picture3.width*Picture3.height);

    Dez((char *)InfoText18.IText+3,AvailMem(0));
    Dez((char *)InfoText20.IText+3,AvailMem(MEMF_LARGEST));
    DrawImage(ErrorWindow->RPort,&InfoImage,3,3);
    PrintIText(ErrorWindow->RPort,&InfoText,3,3);
  }
  else
  {
    ShowError(&InfoError);
  }
}

/*----------------------------------------------------------------------------*/

void
SetPalette()
{
  SetRGB32(&MorphScreen->ViewPort,0,0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa);
  SetRGB32(&MorphScreen->ViewPort,1,0x00000000,0x00000000,0x00000000);
  SetRGB32(&MorphScreen->ViewPort,2,0xffffffff,0xffffffff,0xffffffff);
  SetRGB32(&MorphScreen->ViewPort,3,0x66666666,0x88888888,0xbbbbbbbb);
  SetRGB32(&MorphScreen->ViewPort,4,0xd7d7d7d7,0xd7d7d7d7,0xd7d7d7d7);
  for (b=0;b<6;b++)
  {
    for (g=0;g<6;g++)
    {
      for (r=0;r<6;r++,c++)
      {
        SetRGB32(&MorphScreen->ViewPort,c+40,0x33333333*r,0x33333333*g,0x33333333*b);
      }
    }
  }
}

/*----------------------------------------------------------------------------*/

void
MouseColors(BYTE Pal)
{
  switch(Pal)
  {
    case 0:
    {
      SetRGB32(&MorphScreen->ViewPort,4,pl,pl,pl);
      SetRGB32(&MorphScreen->ViewPort,5,pm,pm,pm);
      SetRGB32(&MorphScreen->ViewPort,17,mm,mm,mm);
      SetRGB32(&MorphScreen->ViewPort,18,md,md,md);
      SetRGB32(&MorphScreen->ViewPort,19,mb,mb,mb);
      break;
    }
    case 1:
    {
      SetRGB32(&MorphScreen->ViewPort,4,pl,pd,pd);
      SetRGB32(&MorphScreen->ViewPort,5,pm,pd,pd);
      SetRGB32(&MorphScreen->ViewPort,17,mm,0,0);
      SetRGB32(&MorphScreen->ViewPort,18,md,0,0);
      SetRGB32(&MorphScreen->ViewPort,19,mb,0,0);
      break;
    }
    case 2:
    {
      SetRGB32(&MorphScreen->ViewPort,4,pd,pl,pd);
      SetRGB32(&MorphScreen->ViewPort,5,pd,pm,pd);
      SetRGB32(&MorphScreen->ViewPort,17,0,mm,0);
      SetRGB32(&MorphScreen->ViewPort,18,0,md,0);
      SetRGB32(&MorphScreen->ViewPort,19,0,mb,0);
      break;
    }
    case 3:
    {
      SetRGB32(&MorphScreen->ViewPort,4,pd,pd,pl);
      SetRGB32(&MorphScreen->ViewPort,5,pd,pd,pm);
      SetRGB32(&MorphScreen->ViewPort,17,0,0,mm);
      SetRGB32(&MorphScreen->ViewPort,18,0,0,md);
      SetRGB32(&MorphScreen->ViewPort,19,0,0,mb);
      break;
    }
    case 4:
    {
      SetRGB32(&MorphScreen->ViewPort,4,pl,pl,pd);
      SetRGB32(&MorphScreen->ViewPort,5,pm,pm,pd);
      SetRGB32(&MorphScreen->ViewPort,17,mm,mm,0);
      SetRGB32(&MorphScreen->ViewPort,18,md,md,0);
      SetRGB32(&MorphScreen->ViewPort,19,mb,mb,0);
      break;
    }
    case 5:
    {
      SetRGB32(&MorphScreen->ViewPort,4,pl,pd,pl);
      SetRGB32(&MorphScreen->ViewPort,5,pm,pd,pm);
      SetRGB32(&MorphScreen->ViewPort,17,mm,0,mm);
      SetRGB32(&MorphScreen->ViewPort,18,md,0,md);
      SetRGB32(&MorphScreen->ViewPort,19,mb,0,mb);
      break;
    }
    case 6:
    {
      SetRGB32(&MorphScreen->ViewPort,4,pd,pl,pl);
      SetRGB32(&MorphScreen->ViewPort,5,pd,pm,pm);
      SetRGB32(&MorphScreen->ViewPort,17,0,mm,mm);
      SetRGB32(&MorphScreen->ViewPort,18,0,md,md);
      SetRGB32(&MorphScreen->ViewPort,19,0,mb,mb);
      break;
    }
  }
}

/*----------------------------------------------------------------------------*/

void
RethinkSliderView(struct Pic *Picture)
{
  if (Picture)
  {
    if (ZoomButton.Flags & GFLG_SELECTED)
    {
      xmax=4*Picture->width;
      ymax=4*Picture->height;
    }
    else
    {
      xmax=Picture->width;
      ymax=Picture->height;
    }
    if (ymax<=ViewWindow->GZZHeight)
    {
      NewModifyProp(&ViewWindowBar2,ViewWindow,0,
                    AUTOKNOB | FREEVERT | PROPBORDERLESS | PROPNEWLOOK,
                    0,0,
                    MAXBODY,MAXBODY,
                    0);
    }
    else
    {
      NewModifyProp(&ViewWindowBar2,ViewWindow,0,
                    AUTOKNOB | FREEVERT | PROPBORDERLESS | PROPNEWLOOK,
                    0,ViewWindowBar2p.VertPot,
                    MAXBODY,(MAXBODY*ViewWindow->GZZHeight)/ymax,
                    0);
    }
    if (xmax<=ViewWindow->GZZWidth)
    {
      NewModifyProp(&ViewWindowBar1,ViewWindow,0,
                    AUTOKNOB | FREEHORIZ | PROPBORDERLESS | PROPNEWLOOK,
                    0,0,
                    MAXBODY,MAXBODY,
                    0);
    }
    else
    {
      NewModifyProp(&ViewWindowBar1,ViewWindow,0,
                    AUTOKNOB | FREEHORIZ | PROPBORDERLESS | PROPNEWLOOK,
                    ViewWindowBar1p.HorizPot,0,
                    (MAXBODY*ViewWindow->GZZWidth)/xmax,MAXBODY,
                    0);
    }
  }
}

/*----------------------------------------------------------------------------*/

void
RethinkSliderEdit(struct Pic *Picture)
{
  if (Picture)
  {
    if (ZoomButton.Flags & GFLG_SELECTED)
    {
      xmax=4*Picture->width;
      ymax=4*Picture->height;
    }
    else
    {
      xmax=Picture->width;
      ymax=Picture->height;
    }
    if (ymax<=EditWindow->GZZHeight)
    {
      NewModifyProp(&EditWindowBar2,EditWindow,0,
                    AUTOKNOB | FREEVERT | PROPBORDERLESS | PROPNEWLOOK,
                    0,0,
                    MAXBODY,MAXBODY,
                    0);
    }
    else
    {
      NewModifyProp(&EditWindowBar2,EditWindow,0,
                    AUTOKNOB | FREEVERT | PROPBORDERLESS | PROPNEWLOOK,
                    0,EditWindowBar2p.VertPot,
                    MAXBODY,(MAXBODY*EditWindow->GZZHeight)/ymax,
                    0);
    }
    if (xmax<=EditWindow->GZZWidth)
    {
      NewModifyProp(&EditWindowBar1,EditWindow,0,
                    AUTOKNOB | FREEHORIZ | PROPBORDERLESS | PROPNEWLOOK,
                    0,0,
                    MAXBODY,MAXBODY,
                    0);
    }
    else
    {
      NewModifyProp(&EditWindowBar1,EditWindow,0,
                    AUTOKNOB | FREEHORIZ | PROPBORDERLESS | PROPNEWLOOK,
                    EditWindowBar1p.HorizPot,0,
                    (MAXBODY*EditWindow->GZZWidth)/xmax,MAXBODY,
                    0);
    }
  }
}

/*----------------------------------------------------------------------------*/

void
RethinkSliderSpinEdit()
{
  if (ZoomButton.Flags & GFLG_SELECTED)
  {
    xmax=4*MAX(Picture1.width,Picture2.width);
    ymax=4*MAX(Picture1.height,Picture2.height);
  }
  else
  {
    xmax=MAX(Picture1.width,Picture2.width);
    ymax=MAX(Picture1.height,Picture2.height);
  }
  if (ymax<=EditWindow->GZZHeight)
  {
    NewModifyProp(&EditWindowBar2,EditWindow,0,
                  AUTOKNOB | FREEVERT | PROPBORDERLESS | PROPNEWLOOK,
                  0,0,
                  MAXBODY,MAXBODY,
                  0);
  }
  else
  {
    NewModifyProp(&EditWindowBar2,EditWindow,0,
                  AUTOKNOB | FREEVERT | PROPBORDERLESS | PROPNEWLOOK,
                  0,EditWindowBar2p.VertPot,
                  MAXBODY,(MAXBODY*EditWindow->GZZHeight)/ymax,
                  0);
  }
  if (xmax<=EditWindow->GZZWidth)
  {
    NewModifyProp(&EditWindowBar1,EditWindow,0,
                  AUTOKNOB | FREEHORIZ | PROPBORDERLESS | PROPNEWLOOK,
                  0,0,
                  MAXBODY,MAXBODY,
                  0);
  }
  else
  {
    NewModifyProp(&EditWindowBar1,EditWindow,0,
                  AUTOKNOB | FREEHORIZ | PROPBORDERLESS | PROPNEWLOOK,
                  EditWindowBar1p.HorizPot,0,
                  (MAXBODY*EditWindow->GZZWidth)/xmax,MAXBODY,
                  0);
  }
}

/*----------------------------------------------------------------------------*/

struct Pic *
DisplayPic(struct Pic *Picture,struct Window *DWin)
{
  BYTE OPoints;
  CopyMemQuick(DWin->RPort,&temprp,sizeof(temprp));
  temprp.Layer=0;
  if (Picture)
  {
    if (temprp.BitMap=(struct BitMap *)AllocBitMap(DWin->GZZWidth,1,8,BMF_DISPLAYABLE,DWin->RPort->BitMap))
    {
      if (ZoomButton.Flags & GFLG_SELECTED)
      {
        if (DWin==ViewWindow)
        {
          if (DWin->GZZWidth<=4*Picture->width)
          {
            xstart=((4*Picture->width-DWin->GZZWidth)*ViewWindowBar1p.HorizPot)/65535;
          }
          else
          {
            xstart=0;
          }
          if (DWin->GZZHeight<=4*Picture->height)
          {
            ystart=((4*Picture->height-DWin->GZZHeight)*ViewWindowBar2p.VertPot)/65535;
          }
          else
          {
            ystart=0;
          }
          if ((Picture==&Picture3) || (!(PointsButton.Flags & GFLG_SELECTED)))
          {
            OPoints=0;
          }
          else
          {
            OPoints=1;
          }
        }
        else
        {
          if (DWin->GZZWidth<=4*Picture->width)
          {
            xstart=((4*Picture->width-DWin->GZZWidth)*EditWindowBar1p.HorizPot)/65535;
          }
          else
          {
            xstart=0;
          }
          if (DWin->GZZHeight<=4*Picture->height)
          {
            ystart=((4*Picture->height-DWin->GZZHeight)*EditWindowBar2p.VertPot)/65535;
          }
          else
          {
            ystart=0;
          }
          OPoints=1;
        }
        xstart=(xstart >> 2) << 2;
        ystart=(ystart >> 2) << 2;
        xmax=DWin->GZZWidth-1+xstart;
        ymax=DWin->GZZHeight-1+ystart;
        y=ystart;
        for (y1=(ystart >> 2);(y1<Picture->height) && (y1*4<=ymax);y1++)
        {
          for (y2=0;(y2<4) && (y1*4+y2<=ymax);y2++)
          {
            y=y1*4+y2;
            for (x1=(xstart >> 2);(x1<Picture->width) && (x1*4<=xmax);x1++)
            {
              c=x1+y1*(Picture->width);
              for (x2=0;(x2<4) && (x1*4+x2<=xmax);x2++)
              {
                x=x1*4+x2;
                r=*((Picture->r)+c);
                g=*((Picture->g)+c);
                b=*((Picture->b)+c);
                r=r+Matrix[x%8+(y%8)*8]; r=r/51;
                g=g+Matrix[x%8+(y%8)*8]; g=g/51;
                b=b+Matrix[x%8+(y%8)*8]; b=b/51;
                Array[x-xstart]=40+r+g*6+b*36;
              }
            }
            WritePixelLine8(DWin->RPort,0,y-ystart,xmax+1-xstart,&Array,&temprp);
          }
        }
        if (y<=ymax-1)
        {
          for (x=xstart;(x<=xmax) && (x<Picture->width);x++)
          {
            Array[x-xstart]=0;
          }
          for (;y<=ymax;y++)
          {
            WritePixelLine8(DWin->RPort,0,y-ystart,xmax+1-xstart,&Array,&temprp);
          }
        }
        if (OPoints)
        {
          Point1=Points.First;
          SetAPen(DWin->RPort,4);
          i=0;
          while (Point1)
          {
            i++;
            if (Picture==&Picture1)
            {
              x=Point1->P.x1*4;
              y=Point1->P.y1*4;
            }
            else
            {
              x=Point1->P.x2*4;
              y=Point1->P.y2*4;
            }
            Point1=Point1->Next;
            if (x>=xstart)
            {
              if (x<=xmax)
              {
                if (y>=ystart)
                {
                  if (y<=ymax)
                  {
                    x=x-xstart;
                    y=y-ystart;
                    if (i==PointsBp.LongInt)
                    {
                      WritePixel(DWin->RPort,x+1,y-2);
                      WritePixel(DWin->RPort,x+2,y-2);
                      WritePixel(DWin->RPort,x+1,y-1);
                      WritePixel(DWin->RPort,x+2,y-1);
                      WritePixel(DWin->RPort,x+1,y);
                      WritePixel(DWin->RPort,x+2,y);
                      WritePixel(DWin->RPort,x-2,y+1);
                      WritePixel(DWin->RPort,x-1,y+1);
                      WritePixel(DWin->RPort,x,y+1);
                      WritePixel(DWin->RPort,x+3,y+1);
                      WritePixel(DWin->RPort,x+4,y+1);
                      WritePixel(DWin->RPort,x+5,y+1);
                      WritePixel(DWin->RPort,x-2,y+2);
                      WritePixel(DWin->RPort,x-1,y+2);
                      WritePixel(DWin->RPort,x,y+2);
                      WritePixel(DWin->RPort,x+3,y+2);
                      WritePixel(DWin->RPort,x+4,y+2);
                      WritePixel(DWin->RPort,x+5,y+2);
                      WritePixel(DWin->RPort,x+1,y+3);
                      WritePixel(DWin->RPort,x+2,y+3);
                      WritePixel(DWin->RPort,x+1,y+4);
                      WritePixel(DWin->RPort,x+2,y+4);
                      WritePixel(DWin->RPort,x+1,y+5);
                      WritePixel(DWin->RPort,x+2,y+5);
                    }
                    else
                    {
                      WritePixel(DWin->RPort,x,y);
                      WritePixel(DWin->RPort,x+1,y);
                      WritePixel(DWin->RPort,x+2,y);
                      WritePixel(DWin->RPort,x+3,y);
                      WritePixel(DWin->RPort,x,y+1);
                      WritePixel(DWin->RPort,x+3,y+1);
                      WritePixel(DWin->RPort,x,y+2);
                      WritePixel(DWin->RPort,x+3,y+2);
                      WritePixel(DWin->RPort,x,y+3);
                      WritePixel(DWin->RPort,x+1,y+3);
                      WritePixel(DWin->RPort,x+2,y+3);
                      WritePixel(DWin->RPort,x+3,y+3);
                    }
                  }
                }
              }
            }
          }
        }
      }
      else
      {
        if (DWin==ViewWindow)
        {
          if (DWin->GZZWidth<=Picture->width)
          {
            xstart=((Picture->width-DWin->GZZWidth)*ViewWindowBar1p.HorizPot)/65535;
          }
          else
          {
            xstart=0;
          }
          if (DWin->GZZHeight<=Picture->height)
          {
            ystart=((Picture->height-DWin->GZZHeight)*ViewWindowBar2p.VertPot)/65535;
          }
          else
          {
            ystart=0;
          }
          if ((Picture==&Picture3) || (!(PointsButton.Flags & GFLG_SELECTED)))
          {
            OPoints=0;
          }
          else
          {
            OPoints=1;
          }
        }
        else
        {
          if (DWin->GZZWidth<=Picture->width)
          {
            xstart=((Picture->width-DWin->GZZWidth)*EditWindowBar1p.HorizPot)/65535;
          }
          else
          {
            xstart=0;
          }
          if (DWin->GZZHeight<=Picture->height)
          {
            ystart=((Picture->height-DWin->GZZHeight)*EditWindowBar2p.VertPot)/65535;
          }
          else
          {
            ystart=0;
          }
          OPoints=1;
        }
        xmax=DWin->GZZWidth-1+xstart;
        ymax=DWin->GZZHeight-1+ystart;
        for (y=ystart;(y<Picture->height) && (y<=ymax);y++)
        {
          for (x=xstart;(x<Picture->width) && (x<=xmax);x++)
          {
            c=x+y*(Picture->width);
            r=*((Picture->r)+c);
            g=*((Picture->g)+c);
            b=*((Picture->b)+c);
            r=r+Matrix[x%8+(y%8)*8]; r=r/51;
            g=g+Matrix[x%8+(y%8)*8]; g=g/51;
            b=b+Matrix[x%8+(y%8)*8]; b=b/51;
            Array[x-xstart]=40+r+g*6+b*36;
          }
          WritePixelLine8(DWin->RPort,0,y-ystart,xmax+1-xstart,&Array,&temprp);
        }
        if (y<=ymax-1)
        {
          for (x=xstart;(x<=xmax) && (x<Picture->width);x++)
          {
            Array[x-xstart]=0;
          }
          for (;y<=ymax;y++)
          {
            WritePixelLine8(DWin->RPort,0,y-ystart,xmax+1-xstart,&Array,&temprp);
          }
        }
        if (OPoints)
        {
          Point1=Points.First;
          SetAPen(DWin->RPort,4);
          i=0;
          while (Point1)
          {
            i++;
            if (Picture==&Picture1)
            {
              x=Point1->P.x1;
              y=Point1->P.y1;
            }
            else
            {
              x=Point1->P.x2;
              y=Point1->P.y2;
            }
            Point1=Point1->Next;
            if (x>=xstart)
            {
              if (x<=xmax)
              {
                if (y>=ystart)
                {
                  if (y<=ymax)
                  {
                    x=x-xstart;
                    y=y-ystart;
                    if (i==PointsBp.LongInt)
                    {
                      WritePixel(DWin->RPort,x,y-2);
                      WritePixel(DWin->RPort,x,y-1);
                      WritePixel(DWin->RPort,x-2,y);
                      WritePixel(DWin->RPort,x-1,y);
                      WritePixel(DWin->RPort,x+1,y);
                      WritePixel(DWin->RPort,x+2,y);
                      WritePixel(DWin->RPort,x,y+1);
                      WritePixel(DWin->RPort,x,y+2);
                    }
                    else
                    {
                      WritePixel(DWin->RPort,x-1,y-1);
                      WritePixel(DWin->RPort,x,y-1);
                      WritePixel(DWin->RPort,x+1,y-1);
                      WritePixel(DWin->RPort,x-1,y);
                      WritePixel(DWin->RPort,x+1,y);
                      WritePixel(DWin->RPort,x-1,y+1);
                      WritePixel(DWin->RPort,x,y+1);
                      WritePixel(DWin->RPort,x+1,y+1);
                    }
                  }
                }
              }
            }
          }
        }
      }
      FreeBitMap(temprp.BitMap);
    }
    else
    {
      ShowError(&MemoryError);
    }
  }
  return(Picture);
}

/*----------------------------------------------------------------------------*/

struct Pic *
DisplaySpinPic(struct Pic *Picture1,struct Pic *Picture2,struct Window *DWin)
{
  xstart=0;
  ystart=0;
  xmax=DWin->GZZWidth-1+xstart;
  ymax=DWin->GZZHeight-1+ystart;
  CopyMemQuick(DWin->RPort,&temprp,sizeof(temprp));
  temprp.Layer=0;
  if ((Picture1) && (Picture2))
  {
    if (temprp.BitMap=(struct BitMap *)AllocBitMap(xmax,1,8,BMF_DISPLAYABLE,DWin->RPort->BitMap))
    {
      if (ZoomButton.Flags & GFLG_SELECTED)
      {
        if (DWin->GZZWidth<=4*MAX(Picture1->width,Picture2->width))
        {
          xstart=((4*MAX(Picture1->width,Picture2->width)-DWin->GZZWidth)*EditWindowBar1p.HorizPot)/65535;
        }
        else
        {
          xstart=0;
        }
        if (DWin->GZZHeight<=4*MAX(Picture1->height,Picture1->height))
        {
          ystart=((4*MAX(Picture1->height,Picture2->height)-DWin->GZZHeight)*EditWindowBar2p.VertPot)/65535;
        }
        else
        {
          ystart=0;
        }
        xstart=(xstart >> 2) << 2;
        ystart=(ystart >> 2) << 2;
        xmax=DWin->GZZWidth-1+xstart;
        ymax=DWin->GZZHeight-1+ystart;
        y=ystart;
        for (y1=(ystart >> 2);(y1<MAX(Picture1->height,Picture2->height)) && (y1*4<=ymax);y1++)
        {
          for (y2=0;(y2<4) && (y1*4+y2<=ymax);y2++)
          {
            y=y1*4+y2;
            for (x1=(xstart >> 2);(x1<MAX(Picture1->width,Picture2->width)) && (x1*4<=xmax);x1++)
            {
              c=x1+y1*(Picture1->width);
              d=x1+y1*(Picture2->width);
              for (x2=0;(x2<4) && (x1*4+x2<=xmax);x2++)
              {
                x=x1*4+x2;
                if ((x1<Picture1->width) && (y1<Picture1->height))
                {
                  if ((x1<Picture2->width) && (y1<Picture2->height))
                  {
                    r=(*((Picture1->r)+c)+*((Picture2->r)+d)) >> 1;
                    g=(*((Picture1->g)+c)+*((Picture2->g)+d)) >> 1;
                    b=(*((Picture1->b)+c)+*((Picture2->b)+d)) >> 1;
                  }
                  else
                  {
                    r=(*((Picture1->r)+c)+128) >> 1;
                    g=(*((Picture1->g)+c)+128) >> 1;
                    b=(*((Picture1->b)+c)+128) >> 1;
                  }
                }
                else
                {
                  r=(*((Picture2->r)+d)+128) >> 1;
                  g=(*((Picture2->g)+d)+128) >> 1;
                  b=(*((Picture2->b)+d)+128) >> 1;
                }
                r=r+Matrix[x%8+(y%8)*8]; r=r/51;
                g=g+Matrix[x%8+(y%8)*8]; g=g/51;
                b=b+Matrix[x%8+(y%8)*8]; b=b/51;
                Array[x-xstart]=40+r+g*6+b*36;
              }
            }
            WritePixelLine8(DWin->RPort,0,y-ystart,xmax+1-xstart,&Array,&temprp);
          }
        }
        if (y<=ymax-1)
        {
          for (x=xstart;(x<=xmax) && (x<MAX(Picture1->width,Picture2->width));x++)
          {
            Array[x-xstart]=0;
          }
          for (;y<=ymax;y++)
          {
            WritePixelLine8(DWin->RPort,0,y-ystart,xmax+1-xstart,&Array,&temprp);
          }
        }
        Point1=Points.First;
        i=0;
        while (Point1)
        {
          i++;
          SetAPen(DWin->RPort,5);
          x1=4*Point1->P.x1-xstart;
          y1=4*Point1->P.y1-ystart;
          WritePixel(DWin->RPort,x1,y1);
          WritePixel(DWin->RPort,x1+1,y1);
          WritePixel(DWin->RPort,x1+2,y1);
          WritePixel(DWin->RPort,x1+3,y1);
          WritePixel(DWin->RPort,x1,y1+1);
          WritePixel(DWin->RPort,x1+3,y1+1);
          WritePixel(DWin->RPort,x1,y1+2);
          WritePixel(DWin->RPort,x1+3,y1+2);
          WritePixel(DWin->RPort,x1,y1+3);
          WritePixel(DWin->RPort,x1+1,y1+3);
          WritePixel(DWin->RPort,x1+2,y1+3);
          WritePixel(DWin->RPort,x1+3,y1+3);
          x2=4*Point1->P.x2-xstart;
          y2=4*Point1->P.y2-ystart;
          WritePixel(DWin->RPort,x2,y2);
          WritePixel(DWin->RPort,x2+1,y2);
          WritePixel(DWin->RPort,x2+2,y2);
          WritePixel(DWin->RPort,x2+3,y2);
          WritePixel(DWin->RPort,x2,y2+1);
          WritePixel(DWin->RPort,x2+3,y2+1);
          WritePixel(DWin->RPort,x2,y2+2);
          WritePixel(DWin->RPort,x2+3,y2+2);
          WritePixel(DWin->RPort,x2,y2+3);
          WritePixel(DWin->RPort,x2+1,y2+3);
          WritePixel(DWin->RPort,x2+2,y2+3);
          WritePixel(DWin->RPort,x2+3,y2+3);
          Move(DWin->RPort,x1,y1);
          Draw(DWin->RPort,x2,y2);
          x=4*Point1->P.xs-xstart;
          y=4*Point1->P.ys-ystart;
          if (i==PointsBp.LongInt)
          {
            SetAPen(DWin->RPort,4);
            WritePixel(DWin->RPort,x+1,y-2);
            WritePixel(DWin->RPort,x+2,y-2);
            WritePixel(DWin->RPort,x+1,y-1);
            WritePixel(DWin->RPort,x+2,y-1);
            WritePixel(DWin->RPort,x+1,y);
            WritePixel(DWin->RPort,x+2,y);
            WritePixel(DWin->RPort,x-2,y+1);
            WritePixel(DWin->RPort,x-1,y+1);
            WritePixel(DWin->RPort,x,y+1);
            WritePixel(DWin->RPort,x+3,y+1);
            WritePixel(DWin->RPort,x+4,y+1);
            WritePixel(DWin->RPort,x+5,y+1);
            WritePixel(DWin->RPort,x-2,y+2);
            WritePixel(DWin->RPort,x-1,y+2);
            WritePixel(DWin->RPort,x,y+2);
            WritePixel(DWin->RPort,x+3,y+2);
            WritePixel(DWin->RPort,x+4,y+2);
            WritePixel(DWin->RPort,x+5,y+2);
            WritePixel(DWin->RPort,x+1,y+3);
            WritePixel(DWin->RPort,x+2,y+3);
            WritePixel(DWin->RPort,x+1,y+4);
            WritePixel(DWin->RPort,x+2,y+4);
            WritePixel(DWin->RPort,x+1,y+5);
            WritePixel(DWin->RPort,x+2,y+5);
          }
          else
          {
            WritePixel(DWin->RPort,x,y);
            WritePixel(DWin->RPort,x+1,y);
            WritePixel(DWin->RPort,x+2,y);
            WritePixel(DWin->RPort,x+3,y);
            WritePixel(DWin->RPort,x,y+1);
            WritePixel(DWin->RPort,x+3,y+1);
            WritePixel(DWin->RPort,x,y+2);
            WritePixel(DWin->RPort,x+3,y+2);
            WritePixel(DWin->RPort,x,y+3);
            WritePixel(DWin->RPort,x+1,y+3);
            WritePixel(DWin->RPort,x+2,y+3);
            WritePixel(DWin->RPort,x+3,y+3);
          }
          Point1=Point1->Next;
          Move(DWin->RPort,x1,y1);
          Draw(DWin->RPort,(21*x1+14*x-3*x2) >> 5,(21*y1+14*y-3*y2) >> 5);
          Draw(DWin->RPort,(3*x1+6*x-x2) >> 3,(3*y1+6*y-y2) >> 3);
          Draw(DWin->RPort,(5*x1+30*x-3*x2) >> 5,(5*y1+30*y-3*y2) >> 5);
          Draw(DWin->RPort,x,y);
          Draw(DWin->RPort,(5*x2+30*x-3*x1) >> 5,(5*y2+30*y-3*y1) >> 5);
          Draw(DWin->RPort,(3*x2+6*x-x1) >> 3,(3*y2+6*y-y1) >> 3);
          Draw(DWin->RPort,(21*x2+14*x-3*x1) >> 5,(21*y2+14*y-3*y1) >> 5);
          Draw(DWin->RPort,x2,y2);
        }
      }
      else
      {
        if (DWin->GZZWidth<=MAX(Picture1->width,Picture2->width))
        {
          xstart=((MAX(Picture1->width,Picture2->width)-DWin->GZZWidth)*EditWindowBar1p.HorizPot)/65535;
        }
        else
        {
          xstart=0;
        }
        if (DWin->GZZHeight<=MAX(Picture1->height,Picture2->height))
        {
          ystart=((MAX(Picture1->height,Picture2->height)-DWin->GZZHeight)*EditWindowBar2p.VertPot)/65535;
        }
        else
        {
          ystart=0;
        }
        for (y=ystart;(y<MAX(Picture1->height,Picture2->height)) && (y<=ymax);y++)
        {
          for (x=xstart;(x<MAX(Picture1->width,Picture2->width)) && (x<=xmax);x++)
          {
            c=x+y*(Picture1->width);
            d=x+y*(Picture2->width);
            if ((x<Picture1->width) && (y<Picture1->height))
            {
              if ((x<Picture2->width) && (y<Picture2->height))
              {
                r=(*((Picture1->r)+c)+*((Picture2->r)+d)) >> 1;
                g=(*((Picture1->g)+c)+*((Picture2->g)+d)) >> 1;
                b=(*((Picture1->b)+c)+*((Picture2->b)+d)) >> 1;
              }
              else
              {
                r=(*((Picture1->r)+c)+128) >> 1;
                g=(*((Picture1->g)+c)+128) >> 1;
                b=(*((Picture1->b)+c)+128) >> 1;
              }
            }
            else
            {
              r=(*((Picture2->r)+d)+128) >> 1;
              g=(*((Picture2->g)+d)+128) >> 1;
              b=(*((Picture2->b)+d)+128) >> 1;
            }
            r=r+Matrix[x%8+(y%8)*8]; r=r/51;
            g=g+Matrix[x%8+(y%8)*8]; g=g/51;
            b=b+Matrix[x%8+(y%8)*8]; b=b/51;
            Array[x-xstart]=40+r+g*6+b*36;
          }
          WritePixelLine8(DWin->RPort,0,y-ystart,xmax+1-xstart,&Array,&temprp);
        }
        if (y<=ymax-1)
        {
          for (x=xstart;(x<=xmax) && (x<MAX(Picture1->width,Picture2->width));x++)
          {
            Array[x-xstart]=0;
          }
          for (;y<=ymax;y++)
          {
            WritePixelLine8(DWin->RPort,0,y-ystart,xmax+1-xstart,&Array,&temprp);
          }
        }
        Point1=Points.First;
        i=0;
        while (Point1)
        {
          i++;
          SetAPen(DWin->RPort,5);
          x1=Point1->P.x1-xstart;
          y1=Point1->P.y1-ystart;
          WritePixel(DWin->RPort,x1-1,y1-1);
          WritePixel(DWin->RPort,x1,y1-1);
          WritePixel(DWin->RPort,x1+1,y1-1);
          WritePixel(DWin->RPort,x1-1,y1);
          WritePixel(DWin->RPort,x1+1,y1);
          WritePixel(DWin->RPort,x1-1,y1+1);
          WritePixel(DWin->RPort,x1,y1+1);
          WritePixel(DWin->RPort,x1+1,y1+1);
          x2=Point1->P.x2-xstart;
          y2=Point1->P.y2-ystart;
          WritePixel(DWin->RPort,x2-1,y2-1);
          WritePixel(DWin->RPort,x2,y2-1);
          WritePixel(DWin->RPort,x2+1,y2-1);
          WritePixel(DWin->RPort,x2-1,y2);
          WritePixel(DWin->RPort,x2+1,y2);
          WritePixel(DWin->RPort,x2-1,y2+1);
          WritePixel(DWin->RPort,x2,y2+1);
          WritePixel(DWin->RPort,x2+1,y2+1);
          Move(DWin->RPort,x1,y1);
          Draw(DWin->RPort,x2,y2);
          x=Point1->P.xs-xstart;
          y=Point1->P.ys-ystart;
          if (i==PointsBp.LongInt)
          {
            SetAPen(DWin->RPort,4);
            WritePixel(DWin->RPort,x,y-2);
            WritePixel(DWin->RPort,x,y-1);
            WritePixel(DWin->RPort,x-2,y);
            WritePixel(DWin->RPort,x-1,y);
            WritePixel(DWin->RPort,x+1,y);
            WritePixel(DWin->RPort,x+2,y);
            WritePixel(DWin->RPort,x,y+1);
            WritePixel(DWin->RPort,x,y+2);
          }
          else
          {
            WritePixel(DWin->RPort,x-1,y-1);
            WritePixel(DWin->RPort,x,y-1);
            WritePixel(DWin->RPort,x+1,y-1);
            WritePixel(DWin->RPort,x-1,y);
            WritePixel(DWin->RPort,x+1,y);
            WritePixel(DWin->RPort,x-1,y+1);
            WritePixel(DWin->RPort,x,y+1);
            WritePixel(DWin->RPort,x+1,y+1);
          }
          Point1=Point1->Next;
          Move(DWin->RPort,x1,y1);
          Draw(DWin->RPort,(21*x1+14*x-3*x2) >> 5,(21*y1+14*y-3*y2) >> 5);
          Draw(DWin->RPort,(3*x1+6*x-x2) >> 3,(3*y1+6*y-y2) >> 3);
          Draw(DWin->RPort,(5*x1+30*x-3*x2) >> 5,(5*y1+30*y-3*y2) >> 5);
          Draw(DWin->RPort,x,y);
          Draw(DWin->RPort,(5*x2+30*x-3*x1) >> 5,(5*y2+30*y-3*y1) >> 5);
          Draw(DWin->RPort,(3*x2+6*x-x1) >> 3,(3*y2+6*y-y1) >> 3);
          Draw(DWin->RPort,(21*x2+14*x-3*x1) >> 5,(21*y2+14*y-3*y1) >> 5);
          Draw(DWin->RPort,x2,y2);
        }
      }
      FreeBitMap(temprp.BitMap);
    }
    else
    {
      ShowError(&MemoryError);
    }
  }
  return((struct Pic *)-1);
}

/*----------------------------------------------------------------------------*/

/* End of Text */
