bresline.c
contents ::
bresline.c
lines.c
Makefile

THIS CODE NOT MINE
//============================================================================
// b r e s l i n e . c
//
// VERSION 4: draws from both ends and calculates single offset into FB.
// (takes advantage of line symmetry). FIXES MIDPOINT PROBLEM
// WHEN DRAWING FROM BOTH ENDS. ALSO MORE EFFICIENT!
// Programmer: Kenny Hoff
// Date: 11/08/95
// Purpose: To implement the Bresenham's line drawing algorithm for all
// slopes and line directions (using minimal routines).
//============================================================================

// EXTERNALLY DEFINED FRAMEBUFFER AND FRAMEBUFFER DIMENSIONS (WIDTH))
extern unsigned char far* FrameBuffer;
extern int WIDTH;

void BresLine(int Ax, int Ay, int Bx, int By, unsigned char Color)
{
int dX, dY, fbXincr, fbYincr, fbXYincr, dPr, dPru, P;

//------------------------------------------------------------------------
// STORE THE FRAMEBUFFER ENDPOINT-ADDRESSES (A AND B)
//------------------------------------------------------------------------
unsigned char far* AfbAddr = &FrameBuffer[Ay*WIDTH+Ax];
unsigned char far* BfbAddr = &FrameBuffer[By*WIDTH+Bx];

//------------------------------------------------------------------------
// DETERMINE AMOUNT TO INCREMENT FRAMEBUFFER TO GET TO SUBSEQUENT POINTS
// (ALSO, STORE THE ABSOLUTE VALUE OF THE CHANGE IN X AND Y FOR THE LINE)
//------------------------------------------------------------------------
fbXincr=1;
if ( (dX=Bx-Ax) >= 0) goto AFTERNEGX;
dX=-dX;
fbXincr=-1;
AFTERNEGX:

fbYincr=WIDTH;
if ( (dY=By-Ay) >= 0) goto AFTERNEGY;
fbYincr=-WIDTH;
dY=-dY;
AFTERNEGY:

fbXYincr = fbXincr+fbYincr;

//------------------------------------------------------------------------
// DETERMINE INDEPENDENT VARIABLE (ONE THAT ALWAYS INCREMENTS BY 1 (OR -1) )
// AND INITIATE APPROPRIATE LINE DRAWING ROUTINE (BASED ON FIRST OCTANT
// ALWAYS). THE X AND Y'S MAY BE FLIPPED IF Y IS THE INDEPENDENT VARIABLE.
//------------------------------------------------------------------------
if (dY > dX) goto YisIndependent; // CHECK IF X OR Y IS INDEPENDENT VARIABLE

// XisIndependent:
dPr = dY+dY; // AMOUNT TO INCREMENT DECISION IF RIGHT IS CHOSEN (always)
P = -dX; // DECISION VARIABLE START VALUE
dPru = P+P; // AMOUNT TO INCREMENT DECISION IF UP IS CHOSEN
dY = dX>>1; // COUNTER FOR HALF OF LINE (COMING FROM BOTH ENDS)
XLOOP: // PROCESS EACH POINT IN THE LINE ONE AT A TIME (use dY as loop counter)
*AfbAddr=Color; // PLOT THE PIXEL FROM END A
*BfbAddr=Color; // PLOT THE PIXEL FROM END B
if ((P+=dPr) > 0) goto RightAndUp; // INCREMENT DECISION, CHECK IF THE PIXEL IS GOING RIGHT AND UP
// Up:
AfbAddr+=fbXincr; // ADVANCE TO NEXT POINT FROM END A
BfbAddr-=fbXincr; // ADVANCE TO NEXT POINT FROM END B
if ((dY=dY-1) > 0) goto XLOOP; // DECREMENT LOOP VARIABLE AND LOOP
*AfbAddr=Color; // (FIX MIDPOINT PROBLEM) PLOT LAST PT FROM END A
if ((dX & 1) == 0) return; // FINISHED IF INDEPENDENT IS EVEN (ODD # STEPS)
*BfbAddr=Color; // PLOT LAST PT FROM END B IF INDEPENDENT IS ODD (EVEN # STEPS)
return;
RightAndUp:
AfbAddr+=fbXYincr; // ADVANCE TO NEXT POINT FROM END A
BfbAddr-=fbXYincr; // ADVANCE TO NEXT POINT FROM END B
P+=dPru; // INCREMENT DECISION (for up)
if ((dY=dY-1) > 0) goto XLOOP; // DECREMENT LOOP VARIABLE AND LOOP
*AfbAddr=Color; // (FIX MIDPOINT PROBLEM) PLOT LAST PT FROM END A
if ((dX & 1) == 0) return; // FINISHED IF INDEPENDENT IS EVEN (ODD # STEPS)
*BfbAddr=Color; // PLOT LAST PT FROM END B IF INDEPENDENT IS ODD (EVEN # STEPS)
return;

YisIndependent:
dPr = dX+dX; // AMOUNT TO INCREMENT DECISION IF RIGHT IS CHOSEN (always)
P = -dY; // DECISION VARIABLE START VALUE
dPru = P+P; // AMOUNT TO INCREMENT DECISION IF UP IS CHOSEN
dX = dY>>1; // COUNTER FOR HALF OF LINE (COMING FROM BOTH ENDS)
YLOOP: // PROCESS EACH POINT IN THE LINE ONE AT A TIME (use dX as loop counter)
*AfbAddr=Color; // PLOT THE PIXEL FROM END A
*BfbAddr=Color; // PLOT THE PIXEL FROM END B
if ((P+=dPr) > 0) goto RightAndUp2;// INCREMENT DECISION, CHECK IF THE PIXEL IS GOING RIGHT AND UP
// Up:
AfbAddr+=fbYincr; // ADVANCE TO NEXT POINT FROM END A
BfbAddr-=fbYincr; // ADVANCE TO NEXT POINT FROM END B
if ((dX=dX-1) > 0) goto YLOOP; // DECREMENT LOOP VARIABLE AND LOOP
*AfbAddr=Color; // (FIX MIDPOINT PROBLEM) PLOT THE LAST POINT FROM END A
if ((dY & 1) == 0) return; // FINISHED IF INDEPENDENT IS EVEN (ODD # STEPS)
*BfbAddr=Color; // PLOT LAST PT FROM END B IF INDEPENDENT IS ODD (EVEN # STEPS)
return;
RightAndUp2:
AfbAddr+=fbXYincr; // ADVANCE TO NEXT POINT FROM END A
BfbAddr-=fbXYincr; // ADVANCE TO NEXT POINT FROM END B
P+=dPru; // INCREMENT DECISION (for up)
if ((dX=dX-1) > 0) goto YLOOP; // DECREMENT LOOP VARIABLE AND LOOP
*AfbAddr=Color; // (FIX MIDPOINT PROBLEM) PLOT THE LAST POINT FROM END A
if ((dY & 1) == 0) return; // FINISHED IF INDEPENDENT IS EVEN (ODD # STEPS)
*BfbAddr=Color; // PLOT LAST PT FROM END B IF INDEPENDENT IS ODD (EVEN # STEPS)
return;
}

James Little