windows-nt/Source/XPSP1/NT/drivers/video/ms/8514a/disp/intline.c

102 lines
2.3 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*************************************************************************\
* Module Name: intline.c
*
* Copyright (c) 1993-1994 Microsoft Corporation
* Copyright (c) 1992 Digital Equipment Corporation
\**************************************************************************/
#include "precomp.h"
#define DEFAULT_DRAW_CMD DRAW_LINE | \
DRAW | \
DIR_TYPE_XY | \
MULTIPLE_PIXELS | \
WRITE | \
LAST_PIXEL_OFF
/******************************************************************************
* bIntegerLine
*
* This routine attempts to draw a line segment between two points. It
* will only draw if both end points are whole integers: it does not support
* fractional endpoints.
*
* Returns:
* TRUE if the line segment is drawn
* FALSE otherwise
*****************************************************************************/
BOOL
bIntegerLine (
PDEV* ppdev,
ULONG X1,
ULONG Y1,
ULONG X2,
ULONG Y2
)
{
LONG Cmd;
LONG DeltaX, DeltaY;
LONG ErrorTerm;
LONG Major, Minor;
X1 >>= 4;
Y1 >>= 4;
X2 >>= 4;
Y2 >>= 4;
Cmd = DEFAULT_DRAW_CMD | PLUS_Y | PLUS_X | MAJOR_Y;
DeltaX = X2 - X1;
if (DeltaX < 0) {
DeltaX = -DeltaX;
Cmd &= ~PLUS_X;
}
DeltaY = Y2 - Y1;
if (DeltaY < 0) {
DeltaY = -DeltaY;
Cmd &= ~PLUS_Y;
}
// Compute the major drawing axis
if (DeltaX > DeltaY) {
Cmd &= ~MAJOR_Y;
Major = DeltaX;
Minor = DeltaY;
} else {
Major = DeltaY;
Minor = DeltaX;
}
// Tell the S3 to draw the line
IO_FIFO_WAIT (ppdev, 7);
IO_CUR_X (ppdev, X1);
IO_CUR_Y (ppdev, Y1);
IO_MAJ_AXIS_PCNT (ppdev, Major);
IO_AXSTP (ppdev, Minor * 2);
IO_DIASTP (ppdev, 2 * Minor - 2 * Major);
// Adjust the error term so that 1/2 always rounds down, to
// conform with GIQ.
ErrorTerm = 2 * Minor - Major;
if (Cmd & MAJOR_Y) {
if (Cmd & PLUS_X) {
ErrorTerm--;
}
} else {
if (Cmd & PLUS_Y) {
ErrorTerm--;
}
}
IO_ERR_TERM (ppdev, ErrorTerm);
IO_CMD (ppdev, Cmd);
return TRUE;
}