Category : Files from Magazines
Archive   : PJ-VGA.ZIP
Filename : CIRCLE3.C

 
Output of file : CIRCLE3.C contained in archive : PJ-VGA.ZIP
/* *** Listing 3 ***
*
* Draws a circle of the specified radius and color, using a fast
* integer-only & square-root-free approach.
* Compiles with either Turbo C 2.0 or MSC 5.0.
* Will work on VGA or EGA, but will draw what appears to be an
* ellipse in non-square-pixel modes.
*/

#include

/* Handle differences between Turbo C & MSC. Note that Turbo C accepts
outp as a synonym for outportb, but not outpw for outport */
#ifdef __TURBOC__
#define outpw outport
#endif

#define SCREEN_WIDTH_IN_BYTES 80 /* # of bytes across one scan
line in mode 12h */
#define SCREEN_SEGMENT 0xA000 /* mode 12h display memory seg */
#define GC_INDEX 0x3CE /* Graphics Controller port */
#define SET_RESET_INDEX 0 /* Set/Reset reg index in GC */
#define SET_RESET_ENABLE_INDEX 1 /* Set/Reset Enable reg index
in GC */
#define BIT_MASK_INDEX 8 /* Bit Mask reg index in GC */

/* Draws a pixel at screen coordinate (X,Y) */
void DrawDot(int X, int Y) {
unsigned char far *ScreenPtr;

/* Point to the byte the pixel is in */
#ifdef __TURBOC__
ScreenPtr = MK_FP(SCREEN_SEGMENT,
(Y * SCREEN_WIDTH_IN_BYTES) + (X / 8));
#else
FP_SEG(ScreenPtr) = SCREEN_SEGMENT;
FP_OFF(ScreenPtr) =(Y * SCREEN_WIDTH_IN_BYTES) + (X / 8);
#endif

/* Set the bit mask within the byte for the pixel */
outp(GC_INDEX + 1, 0x80 >> (X & 0x07));

/* Draw the pixel. ORed to force read/write to load latches.
Data written doesn't matter, because set/reset is enabled
for all planes. Note: don't OR with 0; MSC optimizes that
statement to no operation */
*ScreenPtr |= 0xFF;
}

/* Draws a circle of radius Radius in color Color centered at
* screen coordinate (X,Y) */
void DrawCircle(int X, int Y, int Radius, int Color) {
int MajorAxis, MinorAxis;
unsigned long RadiusSqMinusMajorAxisSq;
unsigned long MinorAxisSquaredThreshold;

/* Set drawing color via set/reset */
outpw(GC_INDEX, (0x0F << 8) | SET_RESET_ENABLE_INDEX);
/* enable set/reset for all planes */
outpw(GC_INDEX, (Color << 8) | SET_RESET_INDEX);
/* set set/reset (drawing) color */
outp(GC_INDEX, BIT_MASK_INDEX);
/* leave the GC Index reg pointing to
the Bit Mask reg */

/* Set up to draw the circle by setting the initial point to one
end of the 1/8th of a circle arc we'll draw */
MajorAxis = 0;
MinorAxis = Radius;
/* Set initial Radius**2 - MajorAxis**2 (MajorAxis is initially 0) */
RadiusSqMinusMajorAxisSq = Radius * Radius;
/* Set threshold for minor axis movement at (MinorAxis - 0.5)**2 */
MinorAxisSquaredThreshold = MinorAxis * MinorAxis - MinorAxis;

/* Draw all points along an arc of 1/8th of the circle, drawing
all 8 symmetries at the same time */
do {
/* Draw all 8 symmetries of current point */
DrawDot(X+MajorAxis, Y-MinorAxis);
DrawDot(X-MajorAxis, Y-MinorAxis);
DrawDot(X+MajorAxis, Y+MinorAxis);
DrawDot(X-MajorAxis, Y+MinorAxis);
DrawDot(X+MinorAxis, Y-MajorAxis);
DrawDot(X-MinorAxis, Y-MajorAxis);
DrawDot(X+MinorAxis, Y+MajorAxis);
DrawDot(X-MinorAxis, Y+MajorAxis);
/* Advance (Radius**2 - MajorAxis**2); if it equals or passes
the MinorAxis**2 threshold, advance one pixel along the minor
axis and set the next MinorAxis**2 threshold */
if ( (RadiusSqMinusMajorAxisSq -=
MajorAxis + MajorAxis + 1) <= MinorAxisSquaredThreshold ) {
MinorAxis--;
MinorAxisSquaredThreshold -= MinorAxis + MinorAxis;
}
MajorAxis++; /* advance one pixel along the major axis */
} while ( MajorAxis <= MinorAxis );

/* Reset the Bit Mask register to normal */
outp(GC_INDEX + 1, 0xFF);

/* Turn off set/reset enable */
outpw(GC_INDEX, (0x00 << 8) | SET_RESET_ENABLE_INDEX);
}




  3 Responses to “Category : Files from Magazines
Archive   : PJ-VGA.ZIP
Filename : CIRCLE3.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/