#define TOP 1
#define BOTTOM 2
#define LEFT 4
#define RIGHT 8
#include "intlong.h"
bit16 clipxl = VPX1;
bit16 clipxr = VPX2;
bit16 clipyt = VPY2;
bit16 clipyb = VPY1;

void code(bit16 x, bit16 y, bit16 *c)
{
  *c = 0;
  if(x < clipxl) {
    *c = LEFT;
  } else {
    if(x > clipxr) {
      *c = RIGHT;
    }
  }
  if(y < clipyb) {
    *c += BOTTOM;
  } else {
    if(y > clipyt) {
      *c += TOP;
    }
  }
}

/* Cohen-Sutherland clipping algorithm */
bit16 clip(bit16 x1, bit16 y1, bit16 x2, bit16 y2, atomtype *ip)
{
  bit16 c,c1,c2,x,y;
  code(x1,y1,&c1);
  code(x2,y2,&c2);
  while(c1 | c2) {
    if((c1 & c2) != 0) return 0;
    c = (c1 == 0) ? c2 : c1;
    if(LEFT & c) {                      /* crosses left edge */
      y = mul16(y2-y1,clipxl-x1) / (x2 - x1) + y1;
      x = clipxl;
    } else {
      if(RIGHT & c) {                   /* crosses right edge */
        y = mul16(y2-y1,clipxr-x1) / (x2 - x1) + y1;
        x = clipxr;
      } else {
        if(BOTTOM & c) {                /* crosses bottom edge */
          x = mul16(x2-x1,clipyb-y1) / (y2 - y1) + x1;
          y = clipyb;
        } else {
          if(TOP & c) {                 /* crosses top edge */
            x = mul16(x2-x1,clipyt-y1) / (y2 - y1) + x1;
            y = clipyt;
          }
        }
      }
    }
    if(c == c1) {
      x1 = x;
      y1 = y;
      code(x,y,&c1);
    } else {
      x2 = x;
      y2 = y;
      code(x,y,&c2);
    }
  }
  /* here if line is visible */
  ip->type = 'v';
  ip->x1 = x1;
  ip->y1 = y1;
  ip->x2 = x2;
  ip->y2 = y2;
  return 1;
}
