Sprites and line 216

Page 1/3
| 2 | 3

By Grauw

Ascended (8515)

Grauw's picture

23-07-2017, 22:34

When a sprite is placed on y-coordinate 216, it and all lower-priority sprites are hidden. Normally this is in the border region, but when the screen scrolls vertically it can be in the visible area, causing a big flicker when you cross this line.

I can think of a couple of solutions:

1. When a sprite is positioned on line 216, move it up or down by 1 line.
2. Only use even y-coordinates (e.g. increased movement speed).
3. Use a secondary pattern shifted 1 line up or down when on this line.
4. Use a scrolling method which never shows line 216.

Option 1 may be ok for fast-moving things like particle effects or enemy waves in a shmup. I think Aleste does this. But when I try it on a 16x32 player character which is static on a scrolling background it looks a little glitchy; on 2 lines the character compresses, not a big fan.

Option 2 can actually be a very acceptable, elegant solution I think, if it is possible. I need to test if it does not make the character movement speed too fast. And there will often still be cases remaining where you do want to move by single pixels.

Option 3 will always work, but it reduces sprite height by 1 and doubles the pattern data. For main character animation I was thinking of updating the patterns using the VDP YMMM command, I could include it in that system.

Option 4 would be simple in screen 4, but in the other screen modes it seems very heavy. Maybe there’s some cheap trick using screen splits or name table mirroring or something?

Any other creative suggestions?

Login or register to post comments

By ricbit

Champion (438)

ricbit's picture

23-07-2017, 23:42

Use only 15 lines of each sprite, this way you can always move them 1 line up/down.

By bore

Expert (115)

bore's picture

24-07-2017, 00:23

Option 3 but leave a couple of patterns at the end for it.
When a sprite is about to be placed on 216, copy it to a spare pattern but shifted one line and use it.
That way you won't need to keep double patterns around.
If too many sprites are on line 216 they won't be visible anyway so you wouldn't need many spare patterns for this.
If you want to use the full height you can make them use 2 sprites when they hit line 216 but I suspect that it won't be very noticeable if the bottom line flickers when it moves over 216 and it feels like the extra work wouldn't be worth it.

By Manel46

Champion (462)

Manel46's picture

24-07-2017, 00:45

The origin of the sprites in an odd number, and we move them vertical, of 2 in 2 pixels. Also the scroll has to be 2 in 2 lines.
That option is valid.

By NYYRIKKI

Enlighted (5398)

NYYRIKKI's picture

24-07-2017, 07:49

How about scrolling with R12h instead of R17h in case of Y=216?

Edit: Sorry, forget... Thinking again it doesn't work quite like that...

By ARTRAG

Enlighted (6279)

ARTRAG's picture

24-07-2017, 08:42

Unless you do not use sprites integrated in the background, moving one pixel off the sprites that fall at y=216 does not look that bad (it is almost not noticeable).
Anyway you can always avoid to roll the full screen using double buffering. If you have animated elements you need to double buffer the screen in any case, so just avoid to make y=216 cross the active window.
In certain games you can move all the sprites on odd coordinates without any noticeable impairment

By Manel46

Champion (462)

Manel46's picture

24-07-2017, 15:51

Friend ARTAG. We are talking about multicolored sprites, which are several superimposed, and if they are formed by the union of several, with different Y, the thing is much more complicated.
Explain a little as you would do to skip the Y = 216, with double buffe, please.

By Manel46

Champion (462)

Manel46's picture

24-07-2017, 15:59

NYYRIKKI.
It may be possible to combine the use of the 2 registers. The one of "set adjust" with the one of vertical scroll by harware.
We tended to see how we do it.

By DarkSchneider

Paladin (880)

DarkSchneider's picture

24-07-2017, 18:04

You should think about using HMMM instead YMMM. Having all the animations y-aligned can limit much the design, and problems with the usage of VRAM. For copying small ammounts of data is not noticeable. OK in this case is fine as is exactly 128 bytes for 1 line of SC5 data. But if you want to use it in the future and improve (not limited to exactly 4 sprites composed characters) then think about it.

The problem of option 3 is that doubles the space used for sprites only for avoiding 1 pixel. Think that for other sprites, those placed in static places (the sprite gfx table) you can't correct them by the vdp command, so a new full table should be used.

Also, remember that for composed sprites you have to look for all of them, not only the character position. In a 16x32 you have 2 possibilities of putting a sprite on y = 216, not only one.

Option 2 is fine, for games at 30 fps, but have also to think you can reach the line 216 when colliding. The way to avoid it is always apply a bit operation to y coordinate of each character before composing its frame to ensure the odd (is odd not even as 216 is even and we want to avoid it) position.

It's really a problem. If helps, the official programmer manual is okay with sprite displacing, so it could be considered as acceptable.

Quote:

Note that if Y is equal to 216 (D8h), all lower priority sprites will not be displayed. It is important to know that when using vertical offset register R#23 to scroll the visible area of the screen, sprite with the Y-coordinate of 216 will not be displayed and in order to display sprite in this area on the scrolled screen programmer should use Y=coordinate equal to 215 or 217.

Also, for option 1:

Quote:

on 2 lines the character compresses, not a big fan

You have to check first if any of the sprites of the frame composition is placed at 216, and then move the whole character, not only that sprite, 1 line up or down. Then your character will not be compressed.

By ARTRAG

Enlighted (6279)

ARTRAG's picture

24-07-2017, 20:27

Manel46 wrote:

Friend ARTAG. We are talking about multicolored sprites, which are several superimposed, and if they are formed by the union of several, with different Y, the thing is much more complicated.
Explain a little as you would do to skip the Y = 216, with double buffe, please.

For composed objects you need to displace of one pixels the y of all the sprites composing the logical object.

About double buffering, the idea is simple:
- scroll vertically e.g. max 32 pixels
- use the 32 frames to build in the hidden page a new screen moved of 32 pixels
Swap the pages and reset the scroll register

By Grauw

Ascended (8515)

Grauw's picture

25-07-2017, 00:12

Hey all, thanks for your input! Lot of replies below.

bore wrote:

Option 3 but leave a couple of patterns at the end for it.
When a sprite is about to be placed on 216, copy it to a spare pattern but shifted one line and use it.
That way you won't need to keep double patterns around.
If too many sprites are on line 216 they won't be visible anyway so you wouldn't need many spare patterns for this.
If you want to use the full height you can make them use 2 sprites when they hit line 216 but I suspect that it won't be very noticeable if the bottom line flickers when it moves over 216 and it feels like the extra work wouldn't be worth it.

It’s good to realise there’s an upper bound to it. Too bad I can’t simply use a VDP command to do the shift due to the pattern layout (A, C, B, D). Using the CPU it takes exactly 2 scanlines to write a new pattern.

Another consideration, since I’m using a 16x32 sprite with 4 layers, I would ideally move both quadruplets of patterns, otherwise the sprite height would be restricted to 16x30, and the overlapping line would have 8 sprites on it (other sprites near that line will hit the 8 sprite limit).

Indeed I agree if the bottom line flickers it won’t be very noticeable, in my sprites it’s only a few blob shadow pixels, so I could use the full 16x32 height (nice!).

Manel46 wrote:

The origin of the sprites in an odd number, and we move them vertical, of 2 in 2 pixels. Also the scroll has to be 2 in 2 lines.

And since the sprite location is specified as y-1, the sprites actually move on even pixel locations.

NYYRIKKI wrote:

How about scrolling with R12h instead of R17h in case of Y=216?

Nice idea! I see two buts: 1. you get a jiggle at the top and bottom of the screen, and 2. what if there’s e.g. a sprite on lines 215, 216 and 217, offset by more? I reckon the jiggle can be avoided by a blanking screensplit.

Manel46 wrote:

We are talking about multicolored sprites, which are several superimposed, and if they are formed by the union of several, with different Y, the thing is much more complicated.

Actually! Since the OR overlay sprites only show on lines where the first sprite is active, there is no point in using a different Y offset for the individual parts, so this shouldn’t be a concern.

DarkSchneider wrote:

You should think about using HMMM instead YMMM. Having all the animations y-aligned can limit much the design, and problems with the usage of VRAM. If you want to use it in the future and improve (not limited to exactly 4 sprites composed characters) then think about it.

Point taken Smile. Though even with HMMM there are restrictions. No BMLL command on V99x8 unfortunately.

DarkSchneider wrote:

The problem of option 3 is that doubles the space used for sprites only for avoiding 1 pixel. Think that for other sprites, those placed in static places (the sprite gfx table) you can't correct them by the vdp command, so a new full table should be used.

I don’t really understand that last bit, what do you mean by a new table should be used? I’m in principle assuming I re-write the full sprite attribute table every frame.

DarkSchneider wrote:

Option 2 is fine, for games at 30 fps.

Hey, why not for 60 fps? Secret of Mana, Chrono Trigger, Phantasy Star IV, all move at 2px / 60fps. Also for platformers it could be a nice fast speed.

DarkSchneider wrote:

You have to check first if any of the sprites of the frame composition is placed at 216, and then move the whole character, not only that sprite, 1 line up or down. Then your character will not be compressed.

Yes, I use a simpler implementation atm which is not aware of composite sprites. It would look a little better. More importantly, right now I have 8 sprites on that one overlapping line, that’s not nice at all.

ARTRAG wrote:

About double buffering, the idea is simple:
- scroll vertically e.g. max 32 pixels
- use the 32 frames to build in the hidden page a new screen moved of 32 pixels
Swap the pages and reset the scroll register

Like how you scroll horizontally on MSX2+. One 8x256 copy per frame. Not compatible with double buffered animations though, right, because those need to alternate buffers at a fixed rate for each animation step.

Anyway for tile animations you don’t necessarily need a double buffer, since there’s no background restore step, so no flicker, just possibly a little tearing, which isn’t a huge problem.

Page 1/3
| 2 | 3