Can't beleive I used to write this stuff...

Miscellaneous Forums/General Discussion/Can't beleive I used to write this stuff...

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

/////////////////////////////////////////////////
// LINEASM.CPP (c) 17/11/1997 Jake Birkett
/////////////////////////////////////////////////
// Assembly implementation of Bresenham's Line Algorithm
//
// External Functions :
///////////////////////
// void LineASM(void);
//
// External Variables :
///////////////////////
// unsigned int lx1 = 0; // line start x coord
// unsigned int ly1 = 0;
// unsigned int lx2 = 0; // line end y coord
// unsigned int ly2 = 0;
//
// unsigned char far *line_dest;
// unsigned char line_colour; // 0-255

/////////////////////////////////////////////////
// I N C L U D E S //////////////////////////////
/////////////////////////////////////////////////

#include "lineasm.h"
/////////////////////////////////////////////////
// D E F I N E S ////////////////////////////////
/////////////////////////////////////////////////

/////////////////////////////////////////////////
// P R O T O T Y P E S //////////////////////////
/////////////////////////////////////////////////
// INTERNAL

// EXTERNAL
void LineASM(void);

/////////////////////////////////////////////////
// G L O B A L S ////////////////////////////////
/////////////////////////////////////////////////
// INTERNAL

// EXTERNAL
unsigned int lx1 = 0; // line start x coord
unsigned int ly1 = 0;
unsigned int lx2 = 0; // line end y coord
unsigned int ly2 = 0;

unsigned char far *line_dest=(unsigned char far *)0xA0000000L; // default destination is video buffer
unsigned char line_colour; // 0-255

/////////////////////////////////////////////////
// F U N C T I O N S ////////////////////////////
/////////////////////////////////////////////////
void LineASM(void)
{ // Draws a line using Bresenham's Line Algorithm onto the
	// video buffer or alternate destination specified by line_dest.
	// Uses 4 octants and pre-specifies up or down

		// AL = Line_Colour
		// BX = DeltaX
		// SI = DeltaY
		// ES:DI = line dest address

		// load registers
		asm push	ds;								// precaution
		asm mov		al, line_colour;	// al = line colour;
		asm mov		bx, lx2;
		asm	sub		bx, lx1;          // DeltaX
		asm mov		si, ly2;
		asm sub		si, ly1;					// DeltaY

		asm les		di, line_dest;  	// memory dest address
		asm mov		dx, ly1;					// calc y offset = y*320 ... y<<8 + y<<6 ... or (y<<2 + y)<<6 quicker
		asm shl		dx, 1;
		asm shl		dx, 1;
		asm add		dx, ly1;
		asm mov		cl, 6;
		asm	shl		dx, cl;
		asm	add		di, dx;
		asm add		di, lx1;					// add x offset
		asm mov		byte ptr es:[di], al; // draw first pixel

		// see if ldy<0 or ldy>0
		asm cmp		si, 0;
		asm jns		Line_Down;   			// if ldy>0 line is moving down
		asm neg		si;					 			// make DeltaY positive
		asm mov		dx, -320;					// set y movement to up
		asm jmp		Continue;
Line_Down:
		asm mov		dx, 320;					// set y movement to down
Continue:
		// see if ldx<0 or ldx>0
		asm cmp		bx, 0;
		asm js		Down_Left;				// if ldx<0 line is moving left

Down_Right: // line is moving Down and Right ... Oct 0 and 1
		asm cmp		bx, si;						// is DeltaX>DeltaY
		asm js		V_Line;						// no, so do a Vertical Line

H_Line:
		asm mov		cx, bx;						// cx = number of pixels in line
		asm jcxz	Line_End;					// jumps if cx=0

		// calc error term values
		asm shl		si, 1;         		// binary shift left ... DeltaY*2
		asm mov		bp, si;						// bp = error term
		asm sub		bp, bx;						// error term starts at DeltaY*2 - DeltaX
		asm shl		bx, 1;						// DeltaX*2
		asm sub		si, bx;						// si = DeltaY*2 - DeltaX*2 ... Error Decrement Value ... used in loop
		asm add   bx, si;						// bx = clever convert bx to DeltaY*2 ... Error Increment Value ... used in loop

H_Line_Loop:
		asm and		bp, bp;						// see if error term is negative
		asm js		Move_X_Coord;			// yes, stay at same Y Coord
		// move the Y Coord
		asm add		di, dx;						// increment Y Coord ...  add 320 to pixel address
		asm add		bp, si;						// decrement Error Term with si
		asm jmp		Next_X_Pixel;
Move_X_Coord:
		asm add		bp, bx;						// increment Error Term with bx
Next_X_Pixel:
		asm inc		di;								// add 1 to X Coord
		asm mov		byte ptr es:[di], al;
		asm loop H_Line_Loop;				// draw next pixel
		asm jmp Line_End;

V_Line:
		asm mov		cx, si;						// cx = number of pixels in line
		asm jcxz	Line_End;					// jumps if cx=0

		// calc error term values
		asm shl		bx, 1;          	// binary shift left ... DeltaY*2
		asm mov		bp, bx;						// bp = error term
		asm sub		bp, si;						// error term starts at DeltaY*2 - DeltaX
		asm shl		si, 1;						// DeltaX*2
		asm sub		bx, si;						// bx = DeltaY*2 - DeltaX*2 ... Error Decrement Value ... used in loop
		asm add   si, bx;						// si = clever convert bx to DeltaY*2 ... Error Increment Value ... used in loop

V_Line_Loop:
		asm and		bp, bp;						// see if error term is negative
		asm jns		Advance_X_Coord;	// no, so advance X Coord
		// don't advance X Coord
		asm add		bp, si;						// increment Error Term with si
		asm jmp		Next_Y_Pixel;
Advance_X_Coord:
		asm inc		di;								// increment X Coord by 1 pixel
		asm add		bp, bx;						// decrement Error Term with bx
Next_Y_Pixel:
		asm add		di, dx;						// add 1 to Y Coord ... address + 320 bytes
		asm mov		byte ptr es:[di], al;
		asm loop V_Line_Loop;				// draw next pixel
		asm jmp Line_End;

Down_Left:
		asm neg bx;									// Make DeltaX positive
		asm cmp bx, si;							// is DeltaX>DeltaY
		asm js V_Line2;							// no, so do a Vertical Line

H_Line2:
		asm mov		cx, bx;						// cx = number of pixels in line
		asm jcxz	Line_End;					// jumps if cx=0

		// calc error term values
		asm shl		si, 1;          	// binary shift left ... DeltaY*2
		asm mov		bp, si;						// bp = error term
		asm sub		bp, bx;						// error term starts at DeltaY*2 - DeltaX
		asm shl		bx, 1;						// DeltaX*2
		asm sub		si, bx;						// si = DeltaY*2 - DeltaX*2 ... Error Decrement Value ... used in loop
		asm add   bx, si;						// bx = clever convert bx to DeltaY*2 ... Error Increment Value ... used in loop

H_Line_Loop2:
		asm and		bp, bp;						// see if error term is negative
		asm js		Move_X_Coord2;		// yes, stay at same Y Coord
		// move the Y Coord
		asm add		di, dx;						// increment Y Coord ...  add 320 to pixel address
		asm add		bp, si;						// decrement Error Term with si
		asm jmp		Next_X_Pixel2;
Move_X_Coord2:
		asm add		bp, bx;						// increment Error Term with bx
Next_X_Pixel2:
		asm dec		di;								// minus 1 to X Coord
		asm mov		byte ptr es:[di], al;
		asm loop H_Line_Loop2;			// draw next pixel
		asm jmp Line_End;

V_Line2:
		asm mov		cx, si;						// cx = number of pixels in line
		asm jcxz	Line_End;					// jumps if cx=0

		// calc error term values
		asm shl		bx, 1;          	// binary shift left ... DeltaY*2
		asm mov		bp, bx;						// bp = error term
		asm sub		bp, si;						// error term starts at DeltaY*2 - DeltaX
		asm shl		si, 1;						// DeltaX*2
		asm sub		bx, si;						// bx = DeltaY*2 - DeltaX*2 ... Error Decrement Value ... used in loop
		asm add   si, bx;						// si = clever convert bx to DeltaY*2 ... Error Increment Value ... used in loop

V_Line_Loop2:
		asm and		bp, bp;						// see if error term is negative
		asm jns		Advance_X_Coord2;	// no, so advance X Coord
		// don't advance X Coord
		asm add		bp, si;						// increment Error Term with si
		asm jmp		Next_Y_Pixel2;
Advance_X_Coord2:
		asm dec		di;								// decrement X Coord by 1 pixel
		asm add		bp, bx;						// decrement Error Term with bx
Next_Y_Pixel2:
		asm add		di, dx;						// add 1 to Y Coord ... address + 320 bytes
		asm mov		byte ptr es:[di], al;
		asm loop V_Line_Loop2;			// draw next pixel
		asm jmp Line_End;

Line_End:
		asm pop ds;									// careful end
} // end LineASM

/////////////////////////////////////////////////


Christ Basic is so much easier, well until you run into slow video buffers and dirty rects problems!