Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using screen lookup tables
#1
It occurs to me that a lot of game programmers would use screen address lookup tables - I've included one in with several library routines at this point.

I think we need to standardize this important library, to be honest.


1> It should be easily includable, and documented on its use. And only let itself be included once! Perhaps setting some parameter, such that the compiler includes it in automatically?
- it must, of course, be aligned. (which is another topic - the align code should be really clever about not wasting bytes, if it can squeeze some other code up in the "missed space"

2> It should be used, if available, by other ZX Basic functions - I'm thinking in particular of plot and draw, which use the ROM routine PIXELADD. Very important this. If we're willing to give up memory for a table, lets have everything use it!

3> It should be user-replaceable, if they follow the structure - so that they can define their own screen buffer, and fast-lookup screen addresses in the buffer, instead.
Reply
#2
do you think this would allow large sprites to be used quickly?
Reply
#3
Not in and of itself - but it's part of the standard techniques that form the basis for that sort of thing.

Working with the screen on the spectrum is unfortunately not simple, owing to the rather unusual design of the screen memory.
Reply
#4
britlion Wrote:2> It should be used, if available, by other ZX Basic functions - I'm thinking in particular of plot and draw, which use the ROM routine PIXELADD. Very important this. If we're willing to give up memory for a table, lets have everything use it!

Stuff like DRAW, CIRCLE (and PFILL as you saw :-) ) are always plotting a point above, below, to the left or to the right from the last point plotted. A fast implementation should not be computing screen addresses from pixel coordinates for each point plotted but instead should be modifying an existing screen address and pixel mask for the next point plotted. This is much, much quicker.

Eg,
If HL holds a screen address and A holds a pixel mask then moving one pixel right can be done with this code (minus out of bounds error detection):

rrca
jr nc, +1 ;; skip 'inc hl'
inc hl

or (hl) ;; now plot the point
ld (hl),a


Compare that to running any table look up or screen address subroutine.

I decided not do table lookup in z88dk (and indeed, so did the predecessors who wrote the gfx lib) for this reason because pixel address computation is usually a one-time thing at the beginning of a graphics primitive.


Even if you accept all the disadvantages of pointing the stack into a table of screen addresses for fast computation of screen addresses when moving up or down a pixel, a POP gets you the next screen address in 11 cycles whereas the usual screen address modification <!-- m --><a class="postlink" href="http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/spectrum/display/zx_saddrpdown.asm?revision=1.1&view=markup">http://z88dk.cvs.sourceforge.net/viewvc ... iew=markup</a><!-- m --> does it in about 45 cycles on average (including call). I don't think that cost is comparatively high and it is the much preferred method considering interrupts would have to be disabled the entire time a line or circle was drawn when using the stack that way.

For sprite drawing, I suppose it depends but I actually don't think many sprite routines do a stack calculation. sp1 doesn't do any screen calculations at run time (it's all done at initialization).
Reply
#5
AlcoholicsAnonymous Wrote:
britlion Wrote:2> It should be used, if available, by other ZX Basic functions - I'm thinking in particular of plot and draw, which use the ROM routine PIXELADD. Very important this. If we're willing to give up memory for a table, lets have everything use it!

Stuff like DRAW, CIRCLE (and PFILL as you saw :-) ) are always plotting a point above, below, to the left or to the right from the last point plotted. A fast implementation should not be computing screen addresses from pixel coordinates for each point plotted but instead should be modifying an existing screen address and pixel mask for the next point plotted. This is much, much quicker.
This is exactly what ZX BASIC DRAW routine is doing plus using Bresenham's algorithm for faster coordinates computation. I also tried at first lookup tables, but the speed gain was low comparing and the memory space requires was high. I couldn't find a better approximation than this one.

ZX BASIC CIRCLE also uses Bresenham's (much faster), but calculates only 1/4 of circle and plot the other 3 quarters by reflection (so the plotted pixels are not in a contiguous sequence and this method cannot be used). The result is pretty fast, anyway.

DRAW3 was really problematic. To mimic the ROM DRAW x, y, z behaviour I ended up copyting the ROM routine and removing the parsing code within. So it's slow and takes memory, but other than that, it woks almost identical to the original one (with all pixels shifted down 16 scan lines).
Reply
#6
I think my point is that if the programmer decided they want screen tables in for another reason, such as sprites, we may as well use them - and using ifdef, we can work out optional assembly depending if it's there or not.

The usual version is page aligned hi/lo bytes.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)