Jump to content
IGNORED

So how exactly does one draw a sprite?


Recommended Posts

So I've been trying to figure out how to draw sprite in 6502... my main problem is that either it doesn't show the sprite at all, or if I'm trying to follow a tutorial it doesn't work since it's NTSC and I'm using PAL.

I'm really confused as to how it works so if anyone could shed some light on it, that would be much appreciated.

Link to comment
Share on other sites

8 hours ago, its-a-feature said:

So I've been trying to figure out how to draw sprite in 6502... my main problem is that either it doesn't show the sprite at all, or if I'm trying to follow a tutorial it doesn't work since it's NTSC and I'm using PAL.

I'm really confused as to how it works so if anyone could shed some light on it, that would be much appreciated.

For PAL you need to adjust the # scanlines drawn, so that your TV is happy.  Typically NTSC are about 262 and PAL about 312.

If you don't understand how to do that, then you probably need to go back and read the tutorials about how to draw a playfield properly.

As to drawing a sprite, it's simply a matter of (a) positioning the X of the sprite so it's onscreen, and (b) writing appropriate data to GRP0 or GRP1 at each scanline, and (c) making sure the sprite colour is not the same as the BG and/or playfield colour so that you can actually see it.

Each of these requires a bit of learning. To start with, I'd just put 255 into GRP0, also COLUP0, and then see if you get an 8-pixel wide vertical band on the screen. That's the sprite 0.  Next, learn how to position it horizontally. This is tricky and needs a lot of understanding.

Once you have that, then you position it vertically by changing the graphics data you write on each scanline.  0 if you don't want it to be seen, otherwise the appropriate line of the shape you're drawing. Again, this needs some understanding. There are quite a few techniques to do it.

 

 

 

 

  • Like 1
Link to comment
Share on other sites

I'm curious as to what "doesn't work".  We write PAL60 games all the time - the games use NTSC timing, so they output 262 total scanlines, but use PAL color values.  

 

If you use NTSC colors they'll look wrong, but still be recognizable. Same goes in reverse, here's the PAL game Bobby is Going Home in emulation:

1761269011_BobbyIsGoingHome(1983)(BitCorp)(PAL).thumb.png.d27d19bd59d8f49e96d6bbcb1d0a4bb6.png



And here it is running on my NTSC 2600 - colors are strange, but everything still works.

 

(IMG_0978D.thumb.jpg.9f3e35f4a7aae0e07579f0a113abb6a8.jpg

(fading at top is due to camera)

 

IMG_0977D.thumb.jpg.5e472fc757e169806888e2c6363c4d74.jpg

(fading at bottom is due to camera)

 

There are many ways to draw the players (sprites) on the 2600.  My tutorial covers one way in Step 4; though its better to work your way through Step 1, 2, and 3 first as the later parts build upon the prior parts.

Link to comment
Share on other sites

Andrew Davie's advice is probably the best one: start simple, understand each of the steps, and progress.

Take a very simple kernel, e.g., the one attached here, understand what it is doing.

The one suggested here uses timers for VBLANK and overscan, so you've only to worry about counting the visible kernel scanlines.

Also, it can be configured for NTSC and PAL (already preconfigured), showing that there really isn't much difference (it's just about the extent of the three parts, VBLANK, kernel, overscan).

 

Try inserting code, start – as already suggested – by editing the kernel so that a full sprite (where ever it will appear on the screen) is displayed. Maybe try different patterns. Maybe, you'll want to try to move that band incrementally using HMOVE (insert this before the kernel once per frame, don't forget to rest HMOVE values). Then try to make the sprite just on a single scanline, or on a certain vertical position for a given height. Try changing the pattern for each of the scanlines it's visible. Use patterns stored in a table for a real 2D sprite.
Finally, implement some code for horizontal positioning. (This is the most tricky part, since it can be done only by timing and the CPU is slower than the beam/TIA. So there'll has to be compensation for fine adjustment.)
 
There are well known routines to achieve this, e.g., the "Skipdraw" routine for vertical drawing, or the Battlezone routine for horizontal positioning (in various flavors).
Have a look at various tutorials or at http://www.qotile.net/minidig/tricks.html. Copy just the code you actual need and integrate it into what you already have. Understand it and make it your own!
 
If you're more the reading type, read it up (again, see tutorials, etc), and, again, understand it and make it your own.
 
So, here's a simple kernel to start with:

playfieldstarter.asm

Edited by NoLand
Link to comment
Share on other sites

Maybe worth mentioning: The TIA is all you have (apart from the RIOT chip for a few things like timers and reading input), it's all there is. It's your only friend. Don't rush things, understand them. The TIA is much like an operating system on modern computers, strobing and setting registers is like calling OS routines. However, the TIA is also a rather tacit friend, it won't talk back regarding any errors (unlike an OS). Instead, there's immediate visual feedback. Part of the art is also, guessing from the visual feedback what may have gone wrong.

 

Some of this may seem tedious, but it's really a quite ingenious design, given the (cost) constraints. Part of these constraints is (a) the TIA "knows" nothing about vertical images, it just does scanlines, over and over again, as currently configured. Hence, we're counting scanlines, etc. (b) It uses linear feedback shift registers internally for counting, rather than counting by ordinary numbers. These shift registers progress by unique values, like normal counters, but non-sequentially, out of sequence. This is why we have to communicate horizontal sprite positions by timing. This is too coarse for an exact position at most of the pixels, but there are also HMOVE and the corresponding horizontal movement registers. These can be used either for moving an object by a certain offset to the left or right, or for fine positioning. This is, where the more arcane code, like the one in the Battlezone routine comes to help. Thankfully, this has been figured out long ago…

 

Combining all those things in the tiny amount of time provided by a single scanline (often, we want most of this already be set in HBLANK, which is just 22 CPU cycles) in the right order is the high art. (This is, what caught me somewhat by surprise: reading it up, it seems just simple, there are that and that constraints and that and that recipes to do it, fair enough. But then you realize, you must be ready by the end of HBLANK, if you want to show a sprite at the left side of the screen. Maybe, you'll have to tweek your game design, maybe you'll have to become inventive with your code. Maybe, reordering code helps. Again, making copied code your own by thoroughly understanding it helps enormously.) Maybe start with looser constraints, i.e. a two-line kernel, which provides you double the time at the cost of vertical resolution.

Edited by NoLand
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...