[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]

{
>Can someone post code for drawing a circle in Mode-X?

Here is a Circle procedure that will work in all Graphic modes (it's
even pretty fast...), as long as you have a putpixel procedure that
works.  It only works up until a radius of 50 or so, after that holes
start appearing.  I know why it happens, but I'm too lazy to fix it.

(This code is just cut and pasted from other units, so I have not
tested it.  It should work though...).
}

Unit Circle;

Interface

 Const
{ Fixed Math Const }
  ShiftFixed = 16;

{ Mode X (320x240) PutPixel Const }
  PlaneWidth = 80;     { Width of each plane in bytes        }
  ScreenSeg  = $A000;  { Segment of Display Memory In Mode X }
  MapMask    = $02;    { Index in SC of Map Mask register    }
  SCIndex    = $03C4;  { Sequence Controller Index           }

 Var
  SinTable,                             { Sin Table with 16 bits of Accuracy }
  CosTable : Array[0..360] Of FixedT;   { Cos Table with 16 bits of Accuracy }
  Color    : Byte                       { Color of Circle to be drawn        }

 Procedure PutPixel;                    { PutPixel Procedure from DDJ }
 Procedure Circle(X, Y, Radius : Word); { My Circle Procedure         }

Implementation

 Procedure InitSinCosTables;
  Var
   I      : Word;
   Radian : Real;
  Begin
   For I := 0 To 360 Do
    Begin
     Radian := I * 3.1415926535 / 180;
     SinTable[I] := Trunc(Sin(Radian) * 65536);
     CosTable[I] := Trunc(Cos(Radian) * 65536);
    End;
  End;

 Procedure PutPixel(X, Y : Word); Assembler;
  Asm
   Mov  AX, PlaneWidth
   Mul  [Y]                { offset of pixel's scan line in page         }
   Mov  DI, [X]
   ShR  DI, 2              { X/4 = offset of pixel in scan line          }
   Add  DI, AX             { offset of pixel in page                     }

   Mov  AX, ScreenSeg
   Mov  ES, AX             { point ES:DI to the pixel's address          }

   Mov  CL, Byte Ptr [X]
   And  CL, 011b           { CL = pixel's plane                          }
   Mov  AX, 0100h+MapMask  { AL = index in SC of Map Mask reg            }
   ShL  AH, CL             { set only the bit for the pixel's plane to 1 }
   Mov  DX, SCIndex        { set the Map Mask to enable only the         }
   Out  DX, AX             { pixel's plane                               }

   Mov  AL, [Color]
   Mov  ES:[DI], AL        { draw the pixel in the desired color         }
  End;

 Procedure Circle(X, Y, Radius : Word);
  Var
   XC, YC : Word;
  Begin
   For I := 0 To 360 Do
    Begin
     XC := X + (Radius * CosTable[I] ShR ShiftFixed);
     YC := Y + (Radius * SinTable[I] ShR ShiftFixed);
     PutPixel(XC, YC);
    End;
  End;

Begin
 InitSinCosTables;
End.


[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]