Work in Progress

Sprite Draw


McPepic 2022-01-01 17:32 (Edited)

I’m currently working with sprites to draw more complex images on the screen.

This is a work in progress at the moment for a larger project.
The project was inspired by Nathaniel Babiak, so a huge thank you to him.

What I’ve added so far:
Double buffer page-flipping
A sprite pool for cycling between sprites (this can be reset and works per-row)
A horizontal line-drawing subprogram that clips with the edges of the screen
A triangle drawing algorithm
Dithering to simulate lighting (values 0-4)

The program now uses less tokens and character memory.
Each row only has 10 sprites available. When it runs out of sprites, the line will be cut short.

You can test different configurations of triangles using the arrow pad. This will move one of the corners of the triangle and will update the screen in real time.

Sprite Draw.nx | Open in app
2022-02-12 20:16
Sprite Draw.nx | Open in app
2022-02-11 17:39
Sprite Draw.nx | Open in app
2022-02-11 15:56
Sprite Draw.nx | Open in app
2022-02-08 16:11
Sprite Draw.nx | Open in app
2022-01-28 18:44
Sprite Draw.nx | Open in app
2022-01-12 16:57
Sprite Draw.nx | Open in app
2022-01-10 18:40
Sprite Draw.nx | Open in app
2022-01-01 17:32

was8bit 2022-01-01 17:34


G-9 2022-01-02 09:40

kool :)

was8bit 2022-01-12 17:00

Step by step, looking good :)

SP4CEBAR 2022-01-20 09:12


nathanielbabiak 2022-01-27 06:16 (Edited)

Hey, you mentioned "the right edge sometimes comes out jagged for some reason, rather than as a straight line". If you upload a sample that shows this specifically, I'll take a look and let you know what's up. :-)

Good work too!

nathanielbabiak 2022-12-08 04:11 (Edited)

I figured out what you meant that the right edge comes out jagged. You've got two subprograms, TopTri and BotTri, these step through the triangle and track the left-edge of the pixels to draw on a scanline, and also track the length of the pixels to draw on the scanline. It's an issue with the fact that the algorithm uses floating point numbers, but doesn't consider precisely when it needs to cast everything to integers. (Since you can't display only a portion of a pixel, right?)

You need to revise the algorithm to track the pixel position of the left-edge and right-edge separately. After this revision, you can kind'a determine the length of the pixels to draw with simple subtraction between the right and left edges, but you'll still have the jaggies.

To (finally) fix the jaggies, make sure the right edge is rounded with the INT instruction, so your algorithm will look like this: L=xLeft-INT(xRight).

I'll post an update to the sprite library soon that shows this more clearly. (And unrelated: that update will make the sprite library example ten times easier to follow, and around twice as fast.)

nathanielbabiak 2022-12-08 21:20 (Edited)

It's updated. There's a subprogram, S_HORZ that's got this line in it:

FOR WIDTH = INT( PX2 ) - INT( PX1 ) + 1 TO 32 STEP -32

That line needs to round the right coordinate (PX2) to the nearest pixel before determining width, otherwise you'll get a bunch of off-by-one errors in the line drawn.

(Unrelated: it rounds the left coordinate (PX1) so that the evaluation after the for-next loop will work out, but that's not related to the off-by-one pixel width issue.)

(Strictly, the INT stuff should've been done in the triangle subprograms before the call to S_HORZ, but it's more robust just to have the INT stuff happen for all calls to S_HORZ.)

By the way, I really like that you've got two copies of the dithered character data (so you can display horizontal lines in a checkerboard pattern no matter the starting/ending row). That's an excellent touch!

Log in to reply.