nanogui: Thread: Microwindows for Hercules


[<<] [<] Page 4 of 4 [>] [>>]
Subject: RE: Microwindows for Hercules
From: Chipzz ####@####.####
Date: 20 Jul 1999 15:49:57 -0000
Message-Id: <Pine.LNX.4.10.9907201736100.13596-100000@ace.ulyssis.student.kuleuven.ac.be>

On Fri, 16 Jul 1999, Greg Haerr wrote:

> From: Greg Haerr ####@####.####
> Subject: RE: Microwindows for Hercules
> 
> 
> : I got the VGA mode 13h Bresenham line code here (in asm), which I got from
> : SWAG (SourceWare Archival Group, Pascal Code). I don't know if it's of any
> : use, but I can post it here. If anyone is interested, there is some asm
> : Bresenhams circle code out there too. SWAG is not copyrighted.
> : Just let me know if you're interested.
> : 
> 
> 	I would be interested in seeing the circle code...


Oops, it wasn't asm, it was Pascal... But I guess that's what you wanted
anyway, no asm? It should be easily portable to C, and to asm too. Well,
here goes:

---

Posted on swag by Jason Rennie (no email :-/ )

{

> I can't get the Graphics Programming thingy, so can you explain to
> theory for making circles with the above algorithms?  Is it possible to for
> the sines and cosines and use another method because anything with sines an
> cosines (without a lookup table) would be too slow.

I can give you the Bresenham algorithm adapted to 320x200x256 mode.  The
Bresenham method is very quick and only uses integer math so there are no
complex math functions to slow it down.  Yet it still draws accurate circles.
This code has been tested, but there were a few things I had to modify, so I
can't guarantee it will work.  Mail me back if for some reason it doesn't.
}

Procedure Circle(Cx, Cy, y : integer; color : byte);

{ Draws circle with center (Cx, Cy) and radius y }
{ Bresenham's circle algorithm implemented }
{ Edge-of-screen clipping implemented }

const              { various and sundry lookup tables for efficiency }
  Change : array[0..1, 0..7] of integer =
    ((1-SW, -1-SW, 1+SW, -1+SW, SW-1, SW+1, -SW-1, -SW+1),
     (1, -1, 1, -1, SW, SW, -SW, -SW));
  ChangeY : array[0..1, 0..7] of integer =
    ((-1, -1, 1, 1, 1, 1, -1, -1),
     (0, 0, 0, 0, 1, 1, -1, -1));
  ChangeX : array[0..1, 0..7] of integer =
    ((1, -1, 1, -1, -1, 1, -1, 1),
     (1, -1, 1, -1, 0, 0, 0, 0));

var
  i, D, x : integer;  {int i, D = 3 - (y << 1);}
  TempNeg : Boolean;  {int x, tempneg;}
  RealX, RealY : array[0..7] of integer;  {int realx[8];}
                                          {int realy[8];}

  TempAddr : word;
  Addr : array[0..7] of word;  {unsigned int tempaddr, addr[8];}
  ch : char;

begin
  D := 3 - (y shl 1);                  { initialize decision variable }
  for i := 0 to 3 do begin             { set up coordinates of symmetry }
    RealX[i] := Cx;                    {    ___    }
    RealY[i+4] := Cy end;              {   /3\   }
  RealX[6] := Cx+y;                    {  /7\|/6\  }
  RealX[4] := RealX[6];                {  |-----|  }
  RealX[7] := Cx-y;                    {  \5/|\4/  }
  RealX[5] := RealX[7];                {   \1/   }
  RealY[1] := Cy+y;                    {    ---    }
  RealY[0] := RealY[1];
  RealY[3] := Cy-y;
  RealY[2] := RealY[3];

  for i := 0 to 7 do                   { set up coordinate addresses }
    Addr[i] := RealX[i] + SW*RealY[i];

  asm
    mov ax, $A000
    mov es, ax                            { set up segment }
    xor di, di
  end;

  x := 0;                              { start with relative x = 0 }
  while (x <= y) do begin              { keep it up until octants meet }

    TempNeg := (D < 0);                { is decision var negative? }
    for i := 0 to 7 do begin           { process all eight pixels }

      if ((RealX[i]>=0) and (RealX[i]<=XMax) and           { clipping }
          (RealY[i]>=0) and (RealY[i]<=YMax)) then begin
    TempAddr := Addr[i];           { temp var for asm compatibility }
    asm                            { display pixel }
      mov di, TempAddr
      mov bl, Color
      mov es:[di], bl
        end end;

      addr[i] := Addr[i] + change[ord(tempneg)][i];        { update address }
      realx[i] := RealX[i] + changex[ord(tempneg)][i];     { update x }
      realy[i] := RealY[i] + changey[ord(tempneg)][i] end; { update y }

    if TempNeg then                   { if decision var is negative }
      D := D + (x shl 2) + 6          { D := D + 4*x + 6 }

    else begin                        { if decision va ris nonnegative }
      y := y - 1;                         { decrement y }
      D := D + ((x - y) shl 2) + 10; end;    { D := D * 4*(x-y) + 10 }

    x := x + 1; end
end;

---


One comment on the code though:

It won't generate the same circles as Borlands C/Pascal Graphics units.
I'm not sure anymore, but Borland generated circles with an ODD width,
while this procedure generates circles with an EVEN width. (Or the other
way around) (IIRC that is).

> 	Also, some very fast non-bresenham horizontal line code would be interesting
> to look at for the various pc video adapters.  (I have included one asm version
> in microwindows for reference, but it's not normally compiled in)
> 
> Greg

Chipzz AKA
Jan Van Buggenhout

--------------------------------------------------------------------------
                  UNIX isn't dead - It just smells funny
                  ####@####.####
--------------------------------------------------------------------------

Subject: RE: Microwindows for Hercules
From: Greg Haerr ####@####.####
Date: 20 Jul 1999 17:36:39 -0000
Message-Id: <01BED2A3.AD6DA9A0.greg@censoft.com>

: Procedure Circle(Cx, Cy, y : integer; color : byte);
: 
: { Draws circle with center (Cx, Cy) and radius y }
: { Bresenham's circle algorithm implemented }
: { Edge-of-screen clipping implemented }
:
	[snip]

A turtle-graphics-bresenham circle-drawer.  What do ya know?
It's a kindof interesting algorithm.  I'll compare it to the current one
I use.  One point, though, the nano-X algorithm uses an algorithm
that will draw a circle or an ellipse with the same code.  If the circle
code won't draw an ellipse, then we get to duplicate a bunch of stuff.

Greg
Subject: RE: Microwindows for Hercules
From: Greg Haerr ####@####.####
Date: 20 Jul 1999 18:14:35 -0000
Message-Id: <01BED2A9.0024F2C0.greg@censoft.com>

: Nod. I was afraid of that too :-/. But maybe we can integrate Bresenhams
: line into this in some way ( <g> ) and get ellipses too ;-)
: But since it is all integer, it is a way to get the floating point library
: out of nano-X, which is good for a) space and b) performance.

	There's no floating point in nano-X or MicroWindows.
The 3d graphics library that I added to MicroWindows uses floating point,
but it's entirely optional and none of the line drawing routines use it.



: Anyway, I suggest you take a look at SWAG. There's A LOT of interseting
: stuff in there - a lot of BS too unfortunately... I think the EGAVGA.SWG
: and GRAPHICS.SWG are what you need. Maybe you can get some idea's there to
: write other drivers too... It has some code for a 3840 color ModeX (hehe),
: it does this by storing the red value (1-15) on one page and the green and
: blue on the other page, and then perform fast page swapping...
: 
	Where is SWAG again?

Greg
[<<] [<] Page 4 of 4 [>] [>>]


Powered by ezmlm-browse 0.20.