/* gline.c (emx+gcc) -- Copyright (c) 1987-1993 by Eberhard Mattes */

#include <stdlib.h>
#include <graph.h>
#define INCL_VIO
#include <os2emx.h>
#include "graph2.h"


static int round (int n)
{
  if (n & 1)
    return (n/2+1);
  else
    return (n/2);
}


static int clip (int x1, int y1, int *x2p, int *y2p)
{
  if (*y2p < _g_clipy0 && y1 >= _g_clipy0)
    {
      *x2p = x1 + round (2 * (_g_clipy0 - y1) * (*x2p - x1) / (*y2p - y1));
      *y2p = _g_clipy0;
    }
  else if (*y2p > _g_clipy1 && y1 <= _g_clipy1)
    {
      *x2p = x1 + round (2 * (_g_clipy1 - y1) * (*x2p - x1) / (*y2p - y1));
      *y2p = _g_clipy1;
    }
  if (*x2p < _g_clipx0 && x1 >= _g_clipx0)
    {
      *y2p = y1 + round (2 * (_g_clipx0 - x1) * (*y2p - y1) / (*x2p - x1));
      *x2p = _g_clipx0;
    }
  else if (*x2p > _g_clipx1 && x1 <= _g_clipx1)
    {
      *y2p = y1 + round (2* (_g_clipx1 - x1) * (*y2p - y1) / (*x2p - x1));
      *x2p = _g_clipx1;
    }
  return (*x2p >= _g_clipx0 && *x2p <= _g_clipx1
          && *y2p >= _g_clipy0 && *y2p <= _g_clipy1);
}


void g_line (int x0, int y0, int x1,int y1, int color)
{
  if (clip (x0, y0, &x1, &y1) && clip (x1, y1, &x0, &y0))
    {
      int dx, dy, temp, iy, n, e;
      unsigned char *p;

      dx = x1 - x0;
      if (dx < 0)
        {
          dx = -dx;
          temp = x1; x1 = x0; x0 = temp;
          temp = y1; y1 = y0; y0 = temp;
        }
      ++dx;
      dy = y1 - y0; iy = 320;
      if (dy < 0)
        {
          dy = -dy;
          iy = -iy;
        }
      ++dy;
      GLOCK;
      p = _g_mem + x0 + 320 * y0;
      if (dx >= dy)
        {
          n = dx; e = dy / 2;
          do
            {
              *p = (unsigned char)color;
              ++p;
              e += dy;
              if (e >= dx)
                {
                  e -= dx;
                  p += iy;
                }
            } while (--n != 0);
        }
      else
        {
          n = dy; e = dx / 2;
          do
            {
              *p = (unsigned char)color;
              p += iy;
              e += dx;
              if (e >= dy)
                {
                  e -= dy;
                  ++p;
                }
            } while (--n != 0);
        }
      GUNLOCK;
    }
}
