Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to draw sprites?

70 views
Skip to first unread message

skolpo...@yahoo.se

unread,
Jan 4, 2009, 4:38:58 PM1/4/09
to
Hello

I'm searching for information how monochrome sprites were drawn to
screen.

I would like to know about how the sprites were rotated, masked and so
on, and if some special tricks were used.

I have found some short info about rotation tables and pre calculated
screen row address tables to speed things up.

Any information or links?

Thank you :-)

OwenBot

unread,
Jan 5, 2009, 8:12:29 AM1/5/09
to
Try searching for Alvin Albrecht's Sprite lib for z88dk.

jgharston

unread,
Jan 6, 2009, 7:02:55 AM1/6/09
to
skolpojke wrote:
> I'm searching for information how monochrome sprites were drawn to
> screen.

See the Jet Set Willy code at http://mdfs.net/Software/JSW/JGH/Docs/jsw48.asm

--
JGH

skolpo...@yahoo.se

unread,
Jan 9, 2009, 12:28:49 PM1/9/09
to
Thank you all. Jet Set Willy was interesting.


A9...@hotmail.com

unread,
Feb 15, 2009, 8:19:25 PM2/15/09
to

A more complicated approach can be found in SP1, the sprite engine
included in z88dk. It's been used for several recent(ish) games
including Cannon Bubble, Phantomas Infinity, etc.

It avoids screen flicker by never erasing anything and speeds things
up by only drawing characters on the screen that have changed between
updates. If a character cell is drawn, all graphics in that character
cell are drawn into an 8-byte buffer using the painter's algorithm
(background first, then lowest priority sprite, etc) and then that
completed 8-byte buffer is copied to the screen. Sprites are software-
rotated by look-up table and many different sprite types are
supported: masked, ored, xored, load, etc.

Source code for drawing one character of a sprite into that 8-byte
buffer for all the various sprite types can be found in this directory
(and browsed online):
http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/sprites/software/sp1/spectrum/sprites/draw/

As an example, the code for drawing a software-rotated masked sprite
into that 8-byte buffer is here:
http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/sprites/software/sp1/spectrum/sprites/draw/SP1_DRAW_MASK2.asm?revision=1.1&view=markup

The entry point is "SP1_DRAW_MASK2" with registers loaded as follows:

hl = graphic definition address for 8-bytes defining this sprite
character cell (mask/graph pairs)
ix = graphic definition address for 8-bytes defining the sprite
character cell to the left of this one (mask/graph pairs)
bc = graphic offset
a = amount of rightward horizontal rotation + MSB for base address of
rotation tables

The code checks for the special case where no rotation is necessary
and if so jumps to an alternate draw routine that does no shifting
(SP1_DRAW_MASK2NR).

When graphics are shifted right by the table, graphics from the sprite
cell to the immediate left of the current character are looked up
through IX. Graphics for the current cell are looked up through HL.

BC offset allows for animated sprites. By adding this offset an
alternate sprite graphic frame can be selected at draw time. An
offset is also generated to enable vertical shifting of the sprite
within a character cell, though this doesn't need to be understood to
see how the code works.

The main function for updating the screen is sp1_UpdateNow:
http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/sprites/software/sp1/spectrum/updater/sp1_UpdateNow.asm?revision=1.1&view=markup

Its purpose is to iterate through all the character cells on screen
that have changed since the last update and redraw them. The actual
redrawing of a character cell is handled by SP1DrawUpdateStruct:

http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/sprites/software/sp1/spectrum/updater/SP1DrawUpdateStruct.asm?revision=1.2&view=markup
(you'll have to scroll down in the source to find the
"SP1DrawUpdateStruct" entry point)

In this code you'll see special cases selected for drawing background
tile only, not drawing background tile (some sort of occluding sprite
is present), skipping sprites if they are overlapped by an occluding
sprite, etc. Code from lines 171-177 is where the jump to the sprite
draw code is made. This first jump is to code embedded in a sprite's
sprite structure that sets up registers concerning horizontal
rotation, etc, and then that code jumps into the sprite code for
drawing a specific character cell, an example of which for masked
sprites was shown above. The return point from the sprite character
cell draw code is "SP1RETSPRDRAW" at line 253.

0 new messages