/* egaline.c (emx+gcc) -- Copyright (c) 1994 by Eberhard Mattes */

#include <stdlib.h>
#include <sys/hw.h>
#include "graph2.h"
#include "ega.h"

void _ega_line (int x0, int y0, int x1, int y1, int color)
{
  if (_gline_clip (x0, y0, &x1, &y1) && _gline_clip (x1, y1, &x0, &y0))
    {
      int dx, dy, temp, iy, n, e;
      volatile unsigned char *p;
      unsigned char mask, accu;

      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 = _g_xsize / 8;
      if (dy < 0)
        {
          dy = -dy;
          iy = -iy;
        }
      ++dy;
      GLOCK;
      OUT3 (color << 8, 0x0f01, 0x0008);
      p = _g_mem + (_g_xsize / 8) * y0 + (x0 / 8);
      mask = 0x80 >> (x0 & 7);
      if (dx >= dy)
        {
          n = dx; e = dy / 2;
          accu = 0;
          do
            {
              accu |= mask;
              if (mask == 0x01)
                {
                  MASK (accu); ++(*p); accu = 0;
                  mask = 0x80; ++p;
                }
              else
                mask >>= 1;
              e += dy;
              if (e >= dx)
                {
                  e -= dx;
                  MASK (accu); ++(*p); accu = 0;
                  p += iy;
                }
            } while (--n != 0);
          if (accu != 0)
            {
              MASK (accu); ++(*p);
            }
        }
      else
        {
          n = dy; e = dx / 2;
          MASK (mask);
          do
            {
              ++(*p);
              p += iy;
              e += dx;
              if (e >= dy)
                {
                  e -= dy;
                  if (mask == 0x01)
                    {
                      mask = 0x80; ++p;
                    }
                  else
                    mask >>= 1;
                  MASK (mask);
                }
            } while (--n != 0);
        }
      OUT2 (0xff08, 0x0001);
      GUNLOCK;
    }
}
