Browse Source

Make DrawLine bin exact by copying from its original source.

pull/109/head
Sergey Semushin 7 years ago committed by Anders Jenbo
parent
commit
b971d8a2cb
  1. 366
      Source/engine.cpp

366
Source/engine.cpp

@ -2088,234 +2088,202 @@ void engine_draw_pixel(int sx, int sy)
// 52B99C: using guessed type int gbNotInView; // 52B99C: using guessed type int gbNotInView;
// 69CF0C: using guessed type int gpBufEnd; // 69CF0C: using guessed type int gpBufEnd;
/* // Exact copy from https://github.com/erich666/GraphicsGems/blob/dad26f941e12c8bf1f96ea21c1c04cd2206ae7c9/gems/DoubleLine.c
* Xiaolin Wu's anti-aliased line algorithm // Except:
*/ // * not in view checks
// * global variable instead of reverse flag
// * condition for pixels_left < 0 removed
#define GG_SWAP(A, B) \
{ \
(A) ^= (B); \
(B) ^= (A); \
(A) ^= (B); \
}
#define GG_ABSOLUTE(I, J, K) (((I) - (J)) * ((K) = (((I) - (J)) < 0 ? -1 : 1)))
void DrawLine(int x0, int y0, int x1, int y1, BYTE col) void DrawLine(int x0, int y0, int x1, int y1, BYTE col)
{ {
int i, sx, sy, dx, dy, nx, ny, xlen, ylen, pixels, remain, xy_same, line_dir, mult_2, mult_4; int dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left;
int sign_x, sign_y, step, i;
int x1_, y1_;
gbPixelCol = col; gbPixelCol = col;
gbNotInView = FALSE; gbNotInView = FALSE;
if(x0 < 0 + 64 || x0 >= 640 + 64) { if (x0 < 0 + 64 || x0 >= 640 + 64) {
gbNotInView = TRUE; gbNotInView = TRUE;
} }
if(x1 < 0 + 64 || x1 >= 640 + 64) { if (x1 < 0 + 64 || x1 >= 640 + 64) {
gbNotInView = TRUE; gbNotInView = TRUE;
} }
if(y0 < 0 + 160 || y0 >= 352 + 160) { if (y0 < 0 + 160 || y0 >= 352 + 160) {
gbNotInView = TRUE; gbNotInView = TRUE;
} }
if(y1 < 0 + 160 || y1 >= 352 + 160) { if (y1 < 0 + 160 || y1 >= 352 + 160) {
gbNotInView = TRUE; gbNotInView = TRUE;
} }
if(x1 - x0 < 0) { dx = GG_ABSOLUTE(x1, x0, sign_x);
nx = -1; dy = GG_ABSOLUTE(y1, y0, sign_y);
} else { /* decide increment sign by the slope sign */
nx = 1; if (sign_x == sign_y)
} step = 1;
xlen = nx * (x1 - x0); else
step = -1;
if(y1 - y0 < 0) {
ny = -1;
} else {
ny = 1;
}
ylen = ny * (y1 - y0);
if(ny == nx) {
xy_same = 1;
} else {
xy_same = -1;
}
if(ylen > xlen) { if (dy > dx) { /* chooses axis of greatest movement (make
x0 ^= y0 ^= x0 ^= y0; * dx) */
x1 ^= y1 ^= x1 ^= y1; GG_SWAP(x0, y0);
xlen ^= ylen ^= xlen ^= ylen; GG_SWAP(x1, y1);
GG_SWAP(dx, dy);
gbRotateMap = TRUE; gbRotateMap = TRUE;
} else { } else
gbRotateMap = FALSE; gbRotateMap = FALSE;
} /* note error check for dx==0 should be included here */
if (x0 > x1) { /* start from the smaller coordinate */
if(x0 > x1) { x = x1;
sx = x1; y = y1;
sy = y1; x1_ = x0;
dx = x0; y1_ = y0;
dy = y0;
} else { } else {
sx = x0; x = x0;
sy = y0; y = y0;
dx = x1; x1_ = x1;
dy = y1; y1_ = y1;
} }
pixels = (xlen - 1) / 4; /* Note dx=n implies 0 - n or (dx+1) pixels to be set */
remain = (xlen - 1) % 4; /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */
engine_draw_pixel(sx, sy); /* In fact (dx-1)/4 as 2 pixels are already plotted */
engine_draw_pixel(dx, dy); xend = (dx - 1) / 4;
pixels_left = (dx - 1) % 4; /* number of pixels left over at the end */
line_dir = (ylen << 2) - xlen - xlen; engine_draw_pixel(x, y);
if(line_dir < 0) { engine_draw_pixel(x1_, y1_); /* plot first two points */
mult_2 = ylen << 1; incr2 = 4 * dy - 2 * dx;
mult_4 = (mult_2 << 1) - xlen; if (incr2 < 0) { /* slope less than 1/2 */
for(i = 0; i < pixels; i++) { c = 2 * dy;
sx++; incr1 = 2 * c;
dx--; D = incr1 - dx;
if(mult_4 < 0) {
engine_draw_pixel(sx, sy); for (i = 0; i < xend; i++) { /* plotting loop */
sx++; ++x;
engine_draw_pixel(sx, sy); --x1_;
engine_draw_pixel(dx, dy); if (D < 0) {
dx--; /* pattern 1 forwards */
engine_draw_pixel(dx, dy); engine_draw_pixel(x, y);
mult_4 += mult_2 + mult_2; engine_draw_pixel(++x, y);
} else if(mult_4 < mult_2) { /* pattern 1 backwards */
engine_draw_pixel(sx, sy); engine_draw_pixel(x1_, y1_);
sy += xy_same; engine_draw_pixel(--x1_, y1_);
sx++; D += incr1;
engine_draw_pixel(sx, sy);
engine_draw_pixel(dx, dy);
dy -= xy_same;
dx--;
engine_draw_pixel(dx, dy);
mult_4 += line_dir;
} else { } else {
sy += xy_same; if (D < c) {
engine_draw_pixel(sx, sy); /* pattern 2 forwards */
sx++; engine_draw_pixel(x, y);
engine_draw_pixel(sx, sy); engine_draw_pixel(++x, y += step);
dy -= xy_same; /* pattern 2 backwards */
engine_draw_pixel(dx, dy); engine_draw_pixel(x1_, y1_);
dx--; engine_draw_pixel(--x1_, y1_ -= step);
engine_draw_pixel(dx, dy); } else {
mult_4 += line_dir; /* pattern 3 forwards */
} engine_draw_pixel(x, y += step);
} engine_draw_pixel(++x, y);
if(remain != 0) { /* pattern 3 backwards */
if(mult_4 < 0) { engine_draw_pixel(x1_, y1_ -= step);
sx++; engine_draw_pixel(--x1_, y1_);
engine_draw_pixel(sx, sy);
if(remain > 1) {
sx++;
engine_draw_pixel(sx, sy);
}
if(remain > 2) {
dx--;
engine_draw_pixel(dx, dy);
}
} else if(mult_4 < mult_2) {
sx++;
engine_draw_pixel(sx, sy);
if(remain > 1) {
sy += xy_same;
sx++;
engine_draw_pixel(sx, sy);
}
if(remain > 2) {
dx--;
engine_draw_pixel(dx, dy);
} }
D += incr2;
}
} /* end for */
/* plot last pattern */
if (pixels_left) {
if (D < 0) {
engine_draw_pixel(++x, y); /* pattern 1 */
if (pixels_left > 1)
engine_draw_pixel(++x, y);
if (pixels_left > 2)
engine_draw_pixel(--x1_, y1_);
} else { } else {
sy += xy_same; if (D < c) {
sx++; engine_draw_pixel(++x, y); /* pattern 2 */
engine_draw_pixel(sx, sy); if (pixels_left > 1)
if(remain > 1) { engine_draw_pixel(++x, y += step);
sx++; if (pixels_left > 2)
engine_draw_pixel(sx, sy); engine_draw_pixel(--x1_, y1_);
} } else {
if(remain > 2) { /* pattern 3 */
dy -= xy_same; engine_draw_pixel(++x, y += step);
dx--; if (pixels_left > 1)
engine_draw_pixel(dx, dy); engine_draw_pixel(++x, y);
if (pixels_left > 2)
engine_draw_pixel(--x1_, y1_ -= step);
} }
} }
} } /* end if pixels_left */
} else { }
mult_2 = (ylen - xlen) << 1; /* end slope < 1/2 */
mult_4 = (mult_2 << 1) + xlen; else { /* slope greater than 1/2 */
for(i = 0; i < pixels; i++) { c = 2 * (dy - dx);
sx++; incr1 = 2 * c;
dx--; D = incr1 + dx;
if(mult_4 > 0) { for (i = 0; i < xend; i++) {
sy += xy_same; ++x;
engine_draw_pixel(sx, sy); --x1_;
sy += xy_same; if (D > 0) {
sx++; /* pattern 4 forwards */
engine_draw_pixel(sx, sy); engine_draw_pixel(x, y += step);
dy -= xy_same; engine_draw_pixel(++x, y += step);
engine_draw_pixel(dx, dy); /* pattern 4 backwards */
dy -= xy_same; engine_draw_pixel(x1_, y1_ -= step);
dx--; engine_draw_pixel(--x1_, y1_ -= step);
engine_draw_pixel(dx, dy); D += incr1;
mult_4 += mult_2 + mult_2;
} else if(mult_4 < mult_2) {
engine_draw_pixel(sx, sy);
sy += xy_same;
sx++;
engine_draw_pixel(sx, sy);
engine_draw_pixel(dx, dy);
dy -= xy_same;
dx--;
engine_draw_pixel(dx, dy);
mult_4 += line_dir;
} else { } else {
sy += xy_same; if (D < c) {
engine_draw_pixel(sx, sy); /* pattern 2 forwards */
sx++; engine_draw_pixel(x, y);
engine_draw_pixel(sx, sy); engine_draw_pixel(++x, y += step);
dy -= xy_same;
engine_draw_pixel(dx, dy); /* pattern 2 backwards */
dx--; engine_draw_pixel(x1_, y1_);
engine_draw_pixel(dx, dy); engine_draw_pixel(--x1_, y1_ -= step);
mult_4 += line_dir; } else {
} /* pattern 3 forwards */
} engine_draw_pixel(x, y += step);
if(remain != 0) { engine_draw_pixel(++x, y);
if(mult_4 > 0) { /* pattern 3 backwards */
sy += xy_same; engine_draw_pixel(x1_, y1_ -= step);
sx++; engine_draw_pixel(--x1_, y1_);
engine_draw_pixel(sx, sy);
if(remain > 1) {
sy += xy_same;
sx++;
engine_draw_pixel(sx, sy);
}
if(remain > 2) {
dy -= xy_same;
dx--;
engine_draw_pixel(dx, dy);
}
} else if(mult_4 < mult_2) {
sx++;
engine_draw_pixel(sx, sy);
if(remain > 1) {
sy += xy_same;
sx++;
engine_draw_pixel(sx, sy);
}
if(remain > 2) {
dx--;
engine_draw_pixel(dx, dy);
} }
D += incr2;
}
} /* end for */
/* plot last pattern */
if (pixels_left) {
if (D > 0) {
engine_draw_pixel(++x, y += step); /* pattern 4 */
if (pixels_left > 1)
engine_draw_pixel(++x, y += step);
if (pixels_left > 2)
engine_draw_pixel(--x1_, y1_ -= step);
} else { } else {
sy += xy_same; if (D < c) {
sx++; engine_draw_pixel(++x, y); /* pattern 2 */
engine_draw_pixel(sx, sy); if (pixels_left > 1)
if(remain > 1) { engine_draw_pixel(++x, y += step);
sx++; if (pixels_left > 2)
engine_draw_pixel(sx, sy); engine_draw_pixel(--x1_, y1_);
} } else {
if(remain > 2) { /* pattern 3 */
if(mult_4 > mult_2) { engine_draw_pixel(++x, y += step);
dy -= xy_same; if (pixels_left > 1)
dx--; engine_draw_pixel(++x, y);
engine_draw_pixel(dx, dy); if (pixels_left > 2) {
} else { if (D > c) /* step 3 */
dx--; engine_draw_pixel(--x1_, y1_ -= step);
engine_draw_pixel(dx, dy); else /* step 2 */
engine_draw_pixel(--x1_, y1_);
} }
} }
} }

Loading…
Cancel
Save