[comp.sys.amiga.programmer] 3D stuff & quick line drawing

divineg@prism.CS.ORST.EDU (04/21/91)

	Here's my situation:

I've coded and coded and coded and finally found a way to crudely rotate
3 dimensional objects ... now all of you wizards out there, what's the
quickest way to draw a line?  I'd like to do it with the Blitter (I can
use the processer to calculate while I draw lines) or is it better to use
the 68'?  By the way, I'm using C & asm (pretty original, huh?).
	Please post your responses, I'm interested in what kind of
discussion follows.....

Yenivid Edalg 8^)
(E-Mail me at divineg@prism.cs.orst.edu)

morgan@cory.Berkeley.EDU (Alan Morgan) (04/22/91)

In article <1991Apr21.081925.4722@lynx.CS.ORST.EDU>
divineg@prism.CS.ORST.EDU writes:
>
>	Here's my situation:
>
>I've coded and coded and coded and finally found a way to crudely rotate
>3 dimensional objects ... now all of you wizards out there, what's the
>quickest way to draw a line?  I'd like to do it with the Blitter (I can
>use the processer to calculate while I draw lines) or is it better to use
>the 68'?  By the way, I'm using C & asm (pretty original, huh?).
>	Please post your responses, I'm interested in what kind of
>discussion follows.....

If you haven't already you should pick up a copy of Foley, van Dam,
Feiner, and Hughes _Computer Graphics: Principles and Practice_ 2nd Ed.
which tells you everything you ever wanted to know about 2D, 3D, 9D (haven't
checked, but I'm sure its in there :) ) graphics.  They list a line drawing
method invented by a man named Bressenham which uses no floating point
calculations, only integer multiplications by 2.  Not being a Blitter guru
(or even a Blitter incompetent, my knowledge is far less) I can't tell
you if this is workable, but you should give it a try.

Incidently, if you are trying to get blinding speed you probably don't
want to spend your entire life juicing up the line drawing algorithm
for a coupla reasons:

	1. Other things, such as rotation and clipping are much slower
	   and thus should be accorded more attention

	2. If you do polygon fills (i.e. solid 3D objects) you will
	   only ever need to draw horizontal lines.  *THESE* you
	   can make really fast using the Blitter.

>
>Yenivid Edalg 8^)
>(E-Mail me at divineg@prism.cs.orst.edu)


Alan Morgan

dillon@overload.Berkeley.CA.US (Matthew Dillon) (04/22/91)

In article <1991Apr21.081925.4722@lynx.CS.ORST.EDU> divineg@prism.CS.ORST.EDU writes:
>
>	Here's my situation:
>
>I've coded and coded and coded and finally found a way to crudely rotate
>3 dimensional objects ... now all of you wizards out there, what's the
>quickest way to draw a line?  I'd like to do it with the Blitter (I can
>use the processer to calculate while I draw lines) or is it better to use
>the 68'?  By the way, I'm using C & asm (pretty original, huh?).
>	Please post your responses, I'm interested in what kind of
>discussion follows.....
>
>Yenivid Edalg 8^)
>(E-Mail me at divineg@prism.cs.orst.edu)

    Hmm.  Well, 3D is actually easy if you use standard matrix theory,
    any good graphics book will have it.  It is all extremely general
    and you can do practically *anything* with it (4x4 matrices).  Once
    you get it working in the general sense you can optimize the *ell out
    of the code, remove whole chunks of calculations that do not apply.

    Word to the wise on 3D:  stick with vectors instead of polar
    coordinates if you want to easily code arbitrary view points &
    movement.  You also avoid arctan completely with vectors and sin/cos
    are not only relegated to table lookups, you can precalculate most of
    what you need once per frame instead of for each object.  The problem
    with polar coordinates is that they are not uniform -- for example, the
    direction represented by phi=+/-90 degrees causes theta to go wild
    (theta can become anything without effecting the direction).

    Back to line drawing:  It has been shown that the processor can
    draw short lines much faster than the blitter can due to blitter
    setup overhead.  I believe the breakoff point is somewhere around
    150 pixels.  I'd stick with standard Move/Draw in a modular routine
    until you get to the point where you really need to optimize, unless
    you have already written optimized line drawing routines, in which
    case you just use those.

					-Matt

--

    Matthew Dillon	    dillon@Overload.Berkeley.CA.US
    891 Regal Rd.	    uunet.uu.net!overload!dillon
    Berkeley, Ca. 94708
    USA

dvljrt@cs.umu.se (Joakim Rosqvist) (04/22/91)

In article <1991Apr21.081925.4722@lynx.CS.ORST.EDU> divineg@prism.CS.ORST.EDU writes:
>
>	Here's my situation:
>
>I've coded and coded and coded and finally found a way to crudely rotate
>3 dimensional objects ... now all of you wizards out there, what's the
>quickest way to draw a line?  I'd like to do it with the Blitter (I can
>use the processer to calculate while I draw lines) or is it better to use
>the 68'?  By the way, I'm using C & asm (pretty original, huh?).
>	Please post your responses, I'm interested in what kind of
>discussion follows.....
>

Here is a part of the source i use when i want *fast* lines.
It uses the blitter and writes directly to the DFF regs
(no flames please, i *did* call Ownblitter first)
There are som things left out, like where how to find the address of the 
bitplane to draw in, and where the coordinates comes from, but that
should be easy to fill in.
/$DR.HEX$


DMACONR=2
BLTCON0=$40
BLTCON1=$42
BLTAMOD=$64
BLTBMOD=$62
BLTCMOD=$60
BLTAPT=$50
BLTCPT=$48
BLTDPT=$54
BLTADAT=$74
BLTBDAT=$72
BLTAFWM=$44
BLTSIZE=$58

OwnBlitter=-456
DisownBlitter=-462

width=80	;80 bytes = 640 pixels



Draw_all_lines:
	move.l	4.w,a6
	move.l	(a6),a6
	move.l	(a6),a6	;get base of Gfxlib
	jsr	OwnBlitter(a6)
	
	lea	$dff000,a6
	move	#$8000,BLTADAT(a6)
	move	#-1,BLTAFWM(a6)
	move	#width,BLTCMOD(a6)
	move	#$FFFF,BLTBDAT(a6)	;$FFFF=draw , $0000=clear
;These values are the same for all lines, no need to tell
;the blitter about them more than once
	
	move.l	<startaddress of bitplane>,a0
	moveq	#<numlines-1>,d7
	bsr.s	drawem
	move.l	4.w,a6
	move.l	(a6),a6
	move.l	(a6),a6
	jmp	DisOwnBlitter(a6)
	

drawem:	move	<X0>,d0
	move	<Y0>,d1
	move	<X1>,d2
	move	<Y1>,d3
	
	moveq	#width,d4
	mulu	d1,d4
;This could be sped up by reading a table with values
;0,width,width*2,width*3 etc.
	moveq	#-16,d5
	and	d0,d5
	lsr	#3,d5
	add	d5,d4
	add.l	a0,d4
	moveq	#0,d5
	sub	d1,d3
	roxl.b	#1,d5
	tst	d3
	bge.s	y2gy1
	neg	d3
y2gy1:	sub	d0,d2
	roxl.b	#1,d5
	tst	d2
	bge.s	x2gx1
	neg	d2
x2gx1:	move	d3,d1
	sub	d2,d1
	bge.s	dygdx
	exg	d2,d3
dygdx:	roxl.b	#1,d5
	move.b	table(pc,d5.w),d5
	add	d2,d2
wait:	btst	#6,DMACONR(a6)
	bne.s	wait
	move	d2,BLTBMOD(a6)
	sub	d3,d2
	bge.s	signn1
	or.b	#$40,d5
signn1:	move	d2,BLTAPT+2(a6)
	sub	d3,d2
	move	d2,BLTAMOD(a6)
	and	#15,d0					
	ror	#4,d0
	or	#$bca,d0
	move	d0,BLTCON0(a6)
	move	d5,BLTCON1(a6)
	move.l	d4,BLTCPT(a6)
	move.l	d4,BLTDPT(a6)
	addq	#1,d3
	lsl	#6,d3
	addq	#2,d3
	move	d3,BLTSIZE(a6)	;GO!
	dbra	d7,drawem	;do next line
	rts
	
table:	dc.b 1,17,9,21,5,25,13,29	

spence@cbmvax.commodore.com (Spencer Shanson) (04/23/91)

In article <1991Apr22.122442.25505@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes:
> [stuff deleted]
>Here is a part of the source i use when i want *fast* lines.
>It uses the blitter and writes directly to the DFF regs
>(no flames please, i *did* call Ownblitter first)

Great! But you also need to WaitBlit() after owning the blitter (just to be 
safe), and just before starting to write to any of the blitter registers.

>[stuff deleted]
>	jsr	OwnBlitter(a6)
>	
>	lea	$dff000,a6

** You need to WaitBlit() here

>	move	#$8000,BLTADAT(a6)
> [more stuff deleted]
>wait:	btst	#6,DMACONR(a6)
>	bne.s	wait

** Better to use WaitBlit(), which knows about various Agnus hardware bugs
** (see Autodocs for more details)

-- 
---------------------------------------------------------------------------
Spencer Shanson - Amiga Software Engineer     | email: spence@commodore.COM
                                              | or uunet!cbmvax!spence
All opinions expressed are my own, and do not | "You know my methods. Apply
(necessarily) represent those of Commodore.   | them" -- Sir Arthur Conan
                                              | Doyle - 'The Sign of Four'

dvljrt@cs.umu.se (Joakim Rosqvist) (04/25/91)

In article <20884@cbmvax.commodore.com> spence@cbmvax.commodore.com (Spencer Shanson) writes:
>
>
>In article <1991Apr22.122442.25505@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes:
>> [stuff deleted]
>>Here is a part of the source i use when i want *fast* lines.
>>It uses the blitter and writes directly to the DFF regs
>>(no flames please, i *did* call Ownblitter first)
>
>Great! But you also need to WaitBlit() after owning the blitter (just to be 
>safe), and just before starting to write to any of the blitter registers.
>
>>[stuff deleted]
>>	jsr	OwnBlitter(a6)
>>	
>>	lea	$dff000,a6
>
>** You need to WaitBlit() here

Sorry, I though Ownblitter meant 
'when you have called this function, you own the blitter'

>
>>	move	#$8000,BLTADAT(a6)
>> [more stuff deleted]
>>wait:	btst	#6,DMACONR(a6)
>>	bne.s	wait
>
>** Better to use WaitBlit(), which knows about various Agnus hardware bugs
>** (see Autodocs for more details)

The issue here was fast lines, if I could consider calling a ROM-routine
I could just as well have called 'drawline' (or sth, I've never used it)
in gfxlib in the first place.

BTW, i read in another article that using the blitter on short lines
should be a disadvantage because of the long setup-time. The breakoff
was given to about 150 pixels. I don't know what processor was intended
but I made a little test in the following environment:

Program ran from fastmem, 68000 used, 1 bitplane 640x256 shown and
no interrupts enabled.
With the blitter i got 738000 pixels/second and 23 microsecond startup-time
which equals 17 extra pixels on every line. Lines between 1..25 pixels
all take the same time. The is beacuse the setup-time was really 58 micros
but for longer lines some of this could be done while the blitter was
drawing the previous line.
With the 68000 i could get about 150000 pixels/sec and 24 micros 'setup'
(I clocked a MAC SE/30 using quickdraw to 110000 pix/sec  giggle..)
This means that the breakoff(=the number of pixels where using the blitter
or the 68000 would take the same time) would be at 5 pixels.

/$DR.HEX$

elg@elgamy.RAIDERNET.COM (Eric Lee Green) (04/26/91)

From article <1991Apr24.203219.22776@cs.umu.se>, by dvljrt@cs.umu.se (Joakim Rosqvist):
> Sorry, I though Ownblitter meant
> 'when you have called this function, you own the blitter'

Right. The system will no longer try to use the blitter. However, the
blitter might still be doing something itself. The fact that OwnBlitter
doesn't try to WaitBlit means that you can overlap some of your own
processing with the blitter's operation, i.e. do all your calculations
before calling WaitBlit().

>>** Better to use WaitBlit(), which knows about various Agnus hardware bugs
>>** (see Autodocs for more details)
> The issue here was fast lines, if I could consider calling a ROM-routine

WaitBlit() isn't *THAT* bad!

> BTW, i read in another article that using the blitter on short lines
> should be a disadvantage because of the long setup-time. The breakoff
> was given to about 150 pixels. I don't know what processor was intended
> but I made a little test in the following environment:
>
> Program ran from fastmem, 68000 used, 1 bitplane 640x256 shown and
> no interrupts enabled.
> With the blitter i got 738000 pixels/second and 23 microsecond startup-time
> which equals 17 extra pixels on every line. Lines between 1..25 pixels
> all take the same time. The is beacuse the setup-time was really 58 micros
> but for longer lines some of this could be done while the blitter was
> drawing the previous line.
> With the 68000 i could get about 150000 pixels/sec and 24 micros 'setup'

Note that using the blitter to draw lines into a four bitplane screen takes
four times longer than into one bitplane. Four times the setup. Four times
the drawing. Meanwhile, extending your one-bitplane CPU-driven whatzit to
four bitplanes basically consists of putting in three more BSET
instructions into your loop. Which does NOT increase the overhead by four
times, and affects setup time very little (basically have to MOVEM four
bitplane pointers into address registers, rather than a single bitplane
pointer). You might end up with, say, 170000 pixels/second + 92 microsecond
setup time for the blitter version, and 130000 pixels/sec with 25 us setup
for the CPU version. The tradeoffs, for short lines, then become much more
obvious, though the blitter is still fastest for long lines on
unaccellerated Amigas. (on accelerated ones, no way!).

I *DO* assume that you're using assembly language for all of this?

And you can also unroll loops for faster drawing. But I suspect you already
knew that.

So -- if you're drawing into one bitplane, the speed advantage is obvious
for all line lengths. If you were drawing into 4 or more bitplanes, though,
things become quite different. I think Jez San has done some timings on BIX
of the 4-bitplane situation. I'll try to fetch them for you.

--
Eric Lee Green   (318) 984-1820  P.O. Box 92191  Lafayette, LA 70509
elg@elgamy.RAIDERNET.COM               uunet!mjbtn!raider!elgamy!elg
 Looking for a job... tips, leads appreciated... inquire within...

spence@cbmvax.commodore.com (Spencer Shanson) (04/26/91)

In article <1991Apr24.203219.22776@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes:
>In article <20884@cbmvax.commodore.com> spence@cbmvax.commodore.com (Spencer Shanson) writes:
>>
>>
>>In article <1991Apr22.122442.25505@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes:
>>> [stuff deleted]
>>Great! But you also need to WaitBlit() after owning the blitter (just to be 
>>safe), and just before starting to write to any of the blitter registers.
>>
>>** You need to WaitBlit() here
>
>Sorry, I though Ownblitter meant 
>'when you have called this function, you own the blitter'
>

You do own the blitter, but that does not mean that the last blit has finished
yet. This will be especially true on a faster CPU and a large blit. Even your
own code does its final blit and then disowns it.

>>** Better to use WaitBlit(), which knows about various Agnus hardware bugs
>>** (see Autodocs for more details)
>
>The issue here was fast lines, if I could consider calling a ROM-routine
>I could just as well have called 'drawline' (or sth, I've never used it)
>in gfxlib in the first place.
>

That's up to you, just don't expect the code to run on every Amiga. At the
very least, take into account the hardware bugs described in the
autodocs.

>BTW, i read in another article that using the blitter on short lines
>should be a disadvantage because of the long setup-time. The breakoff
>was given to about 150 pixels. I don't know what processor was intended
>but I made a little test in the following environment:
>
>Program ran from fastmem, 68000 used, 1 bitplane 640x256 shown and
>no interrupts enabled.
>With the blitter i got 738000 pixels/second and 23 microsecond startup-time
>which equals 17 extra pixels on every line. Lines between 1..25 pixels
>all take the same time. The is beacuse the setup-time was really 58 micros
>but for longer lines some of this could be done while the blitter was
>drawing the previous line.
>With the 68000 i could get about 150000 pixels/sec and 24 micros 'setup'
>(I clocked a MAC SE/30 using quickdraw to 110000 pix/sec  giggle..)
>This means that the breakoff(=the number of pixels where using the blitter
>or the 68000 would take the same time) would be at 5 pixels.
>

You don't say if the lines are arbitrary direction. Sure, for short horizontal
lines, you would be better off using the CPU, but I doubt that's the case for
lines of any angle of more than a few pixels.

>/$DR.HEX$
-- 
---------------------------------------------------------------------------
Spencer Shanson - Amiga Software Engineer     | email: spence@commodore.COM
                                              | or uunet!cbmvax!spence
All opinions expressed are my own, and do not | "You know my methods. Apply
(necessarily) represent those of Commodore.   | them" -- Sir Arthur Conan
                                              | Doyle - 'The Sign of Four'

dvljrt@cs.umu.se (Joakim Rosqvist) (04/28/91)

>>BTW, i read in another article that using the blitter on short lines
>>should be a disadvantage because of the long setup-time. The breakoff
>>was given to about 150 pixels. I don't know what processor was intended
>>but I made a little test in the following environment:
>>
>>Program ran from fastmem, 68000 used, 1 bitplane 640x256 shown and
>>no interrupts enabled.
>>With the blitter i got 738000 pixels/second and 23 microsecond startup-time
>>which equals 17 extra pixels on every line. Lines between 1..25 pixels
>>all take the same time. The is beacuse the setup-time was really 58 micros
>>but for longer lines some of this could be done while the blitter was
>>drawing the previous line.
>>With the 68000 i could get about 150000 pixels/sec and 24 micros 'setup'
>>(I clocked a MAC SE/30 using quickdraw to 110000 pix/sec  giggle..)
>>This means that the breakoff(=the number of pixels where using the blitter
>>or the 68000 would take the same time) would be at 5 pixels.
>>
>
>You don't say if the lines are arbitrary direction. Sure, for short horizontal
>lines, you would be better off using the CPU, but I doubt that's the case for
>lines of any angle of more than a few pixels.
>
Of course, I gave you the figures to show that there really is no point
in using the 68000. The value 150000 corresponds to an 22-degree line
Lines that are 0 or 90 degress will be the fastest and 45 deg the slowest
so i used 22 as an in-between. 
And.. the 68000 will always win over the blitter for horisontal lines.
This is because it can do a:

label:  move.l d7,(a0)+
	dbra   d0,label

Where a0 is a pointer in the bitplane and d7 is $FFFFFFFF.
The poor blitter would read a word, set a bit, write it back then read
it again.. 16 times without knowing it's the same word :-(

/$DR.HEX$

dvljrt@cs.umu.se (Joakim Rosqvist) (04/29/91)

>WaitBlit() isn't *THAT* bad!

The instructions    jsr waitblit(a6) and the rts in the end of that
routine takes 6 us to execute all by themselves and I had 23 us setup-
It would at least double my setup-time to use waitblit.
(I'll disassemble and see what it really does)

>> With the blitter i got 738000 pixels/second and 23 microsecond startup-time
>> all take the same time. The is beacuse the setup-time was really 58 micros
>> but for longer lines some of this could be done while the blitter was
>> drawing the previous line.
>> With the 68000 i could get about 150000 pixels/sec and 24 micros 'setup'
>
>Note that using the blitter to draw lines into a four bitplane screen takes
>four times longer than into one bitplane. Four times the setup. Four times
>the drawing. Meanwhile, extending your one-bitplane CPU-driven whatzit to
>four bitplanes basically consists of putting in three more BSET
>instructions into your loop. Which does NOT increase the overhead by four
>times, and affects setup time very little (basically have to MOVEM four
>bitplane pointers into address registers, rather than a single bitplane
>pointer). You might end up with, say, 170000 pixels/second + 92 microsecond
>setup time for the blitter version, and 130000 pixels/sec with 25 us setup
>for the CPU version. The tradeoffs, for short lines, then become much more
>obvious, though the blitter is still fastest for long lines on
>unaccellerated Amigas. (on accelerated ones, no way!).
>
>I *DO* assume that you're using assembly language for all of this?
>
Is there anything else :-)

Interesting with 4-bitplane lines.. I find 738000/4=185000 pix/sec
And for the CPU it will slow down much more than you say, ironically
enough the reson is that the routines is so optimized that the BSET is
actually a quite large piece in the inner loop. As for now I have about
45 cycles per pixel (292 degrees) It would increase to about 80 in
4 bitplanes giving 86000 pix/sec. Still big advantages using the blitter.

Here is my inner loop:
    BSET  d7,(a0)     ;Plot pixel.  12 cycles
    ADD   d6,a0       ;Go to the next scanline. 8 cycles
    SUB   d3,d5       ;This routine always goes one pixel down and sometimes
		      ;(every second time for 292 deg) one pixels right.
		      ;d3 is MIN(dx,dy) that is dx in this case.  4 cycles
    BPL.S over        ;See if it is time to go right. 9 cycles
		      ;(8 or 10 depending on wheter it branches)
    ADD   d4,d5       ;d4 is MAX(dx,dy)=dy in this case.  4/2=2 cycles
    SUBQ  #1,d7       ;One pixel right  4/2=2 cycles
    BPL.S over        ;If 0<d7<6 do next pixel 10/2=5 cycles
    MOVEQ #7,d7       ;restart from bit 7.  4/2/8=0.25 cycles
    ADDQ  #1,a0       ;go to next byte.  8/2/8=0.5 cycles
over:
Then the same code repeated 3 more times + 1 dbra = 10/4= 2.5 cycles
Total sum of 45.25 cycles. At 7.16Mhz this would be 158000 pix/sec but i said
150000 due to Murphy's law...

Anybody knows what 2.0 thinks of this? 
Like "hmm.. this machine 's got a 25MHz '030 so I'll use that instead of
the blitter to draw lines" Or are they just waiting for a new
25MHz blitter to show up?  I'd want one.

/$DR.HEX$

<BGT101@psuvm.psu.edu> (05/01/91)

Hi all

I need some fast filled-polygon drawing functions, and was wondering if it's
possible to write one that is considerably faster than the ones in ROM such
as AreaDraw() or Flood().  If so, does anybody have some code that they
wouldn't mind sharing?  (I will probably be using 4 bit-planes)

Thanks
blaise

chrisg@cbmvax.commodore.com (Chris Green) (05/01/91)

In article <1991Apr29.110534.10198@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes:
>Here is my inner loop:
>    BSET  d7,(a0)     ;Plot pixel.  12 cycles
>    ADD   d6,a0       ;Go to the next scanline. 8 cycles
>    SUB   d3,d5       ;This routine always goes one pixel down and sometimes
>		      ;(every second time for 292 deg) one pixels right.
>		      ;d3 is MIN(dx,dy) that is dx in this case.  4 cycles
>    BPL.S over        ;See if it is time to go right. 9 cycles
>		      ;(8 or 10 depending on wheter it branches)
>    ADD   d4,d5       ;d4 is MAX(dx,dy)=dy in this case.  4/2=2 cycles
>    SUBQ  #1,d7       ;One pixel right  4/2=2 cycles
>    BPL.S over        ;If 0<d7<6 do next pixel 10/2=5 cycles
>    MOVEQ #7,d7       ;restart from bit 7.  4/2/8=0.25 cycles
>    ADDQ  #1,a0       ;go to next byte.  8/2/8=0.5 cycles
>over:

	Another good optimization for CPU driven lines is to do further examination of
the slope. For instance, suppose you are drawing a near vertical line.
	If DX<DY/n, then there are at least n-1 vertical steps (I think I've got this
right..I don't have the code here) between each horizontal step. So, you can do, say
2 vertical steps at a time with no check in between:

	BSET d7,(a0)
	ADD d6,a0
	BSET d7,(a0)
	SUB	d3,d5			; d3 contains twice the dx!
	BPL.s	over

	The end conditions are a little hairy, but you can still win by doing this.

	For lines that are near horizontal or vertical, and are long, you win by
doing a divide (at least on the 80xxx, you do), and using quick horizontal or vertical
fills between each transition.

	-- 
*-------------------------------------------*---------------------------*
|Chris Green - Graphics Software Engineer   - chrisg@commodore.COM      f
|                  Commodore-Amiga          - uunet!cbmvax!chrisg       n
|My opinions are my own, and do not         - killyouridolssonicdeath   o
|necessarily represent those of my employer.- itstheendoftheworld       r
*-------------------------------------------*---------------------------d

rda184s@monu6.cc.monash.edu.au (Richard Jones) (05/03/91)

BGT101@psuvm.psu.edu writes:

>Hi all

>I need some fast filled-polygon drawing functions, and was wondering if it's
>possible to write one that is considerably faster than the ones in ROM such
>as AreaDraw() or Flood().  If so, does anybody have some code that they
>wouldn't mind sharing?  (I will probably be using 4 bit-planes)

>Thanks
>blaise

Me too please. I have an abundance of faast line drawers, but I have been
looking for a fast polygon drawing routine for ages! It should be able to 
handle *at least* 3 bit planes, but 4 would be nice.

Thanks also
Richard