>32 sprites without hblank?

Page 1/2
| 2

Par jbikker

Resident (45)

Portrait de jbikker

12-05-2023, 22:02

Hello!

I am trying to get more than 32 sprites on the screen, and was hoping to do so without a hblank interrupt: basically by having a pretty predictable workload until halfway the screen. I want to display two sets of sprites and they are pretty far apart, so this should work right? I even change the border color to verify that I indeed get a stable position halfway the screen.

However:

When I reposition sprites to the bottom half, they disappear from the top half. I don't get it... I'm running at 60hz, this should work right? Is >32 sprite rendering limited to screens with hblank enabled?

- Jacco.

!login ou Inscrivez-vous pour poster

Par Sandy Brand

Champion (309)

Portrait de Sandy Brand

13-05-2023, 02:12

Yes that should work, sprite rendering is completely decoupled from any interrupt handling.

"When I reposition sprites to the bottom half, they disappear from the top half"
Do you mean switching to a completely different sprite attribute table, or just sprites moving from the top to the bottom part of the screen?

Do you still revert the sprite attribute table VDP registers during the V-blank?

Par Micha

Expert (110)

Portrait de Micha

13-05-2023, 10:07

It could work; Maybe you forgot to move the sprites back to the upper half of the screen each frame during VBlank ?

Par jbikker

Resident (45)

Portrait de jbikker

13-05-2023, 11:39

Thanks for the replies.
The sprites form an oval mask consisting of 32 sprites for a scrolling backdrop and are thus positioned every frame. 8 of the top 16 sprites are vertically far apart from the 8 lowest sprites, so I was hoping to reuse those 8 sprite planes for something else.
I thus do a RAM->VRAM copy twice per frame to the sprite attribute table, but I must be doing the update for the top 8 sprites too late. I'll revise my timing. Smile
Glad to know that theoretically this can work!

- Jacco.

P.S.: this effect: https://twitter.com/j_bikker/status/1656282702356574212
I'm looking to add title sprites to it.

Par Sandy Brand

Champion (309)

Portrait de Sandy Brand

13-05-2023, 12:36

What you are trying to achieve is definitely possible.

Best approach would probably be to do double buffering with 2 sprite attribute tables in VRAM. Then the switching of upper and lower masks is just changing of a couple of VDP registers and should be visually stable enough.

What you currently seem to want to do is modifying a single sprite attribute table in VRAM on the fly? That can also work, but is probably quite a bit harder with all sorts of timing issues and might give slightly different results on some MSX machines (e.g.: R800 or 7 Mhz CPU, and I think there might be machines with extra wait-states injected when writing to the VDP).

Is there a specific reason why you don't want to use line-interrupts? They are not that hard to setup and might actually make your problem simpler? Smile

Par aoineko

Paragon (1140)

Portrait de aoineko

13-05-2023, 13:51

I agree with the use of the line interruption, even if, with the vertical scrolling, you will have to change the interruption line at each frame.
I also agree with the use of 2 SAT in VRAM: The first SAT with your first 16 mask sprites and 16 gameplay sprites of the upper part, and the second SAT with the other 16 mask sprites and gameplay sprites of the lower part.
Switching SAT is very fast (1 VDP register to modify) and you can easily execute it during the horizontal break.

Par jbikker

Resident (45)

Portrait de jbikker

13-05-2023, 20:36

It worked! Thanks for the help. Cool

Par Sandy Brand

Champion (309)

Portrait de Sandy Brand

14-05-2023, 01:51

Looks great! Smile

Par sd_snatcher

Prophet (3675)

Portrait de sd_snatcher

14-05-2023, 02:49

It's a great trick, but why not use the hblank interrupt? Without it, you risk to have race condition problems with MSX models that have different variations of the hardware. I.e.:

  • slightly different clock (PAL and PAL-M comes to mind)
  • machines where the CPU clock is not generated by the VDP.
  • machines that have extra waitstates when accessing the VDP
  • machines with turbo

Par jbikker

Resident (45)

Portrait de jbikker

14-05-2023, 13:19

@sd_snatcher : yeah good question... My code currently uses only a vblank and catches it with a simple "Halt();" (MSXgl). To use the hblank I need to change that to an actual interrupt callback function (I guess?) which then interprets the origin of the interrupt. Considering the large room for error in this case I was hoping to get away with it. Smile Beyond the title screen the game won't need anything but a vsync.

- Jacco.

Par aoineko

Paragon (1140)

Portrait de aoineko

15-05-2023, 13:10

I really think you should use synchronization with line interrupts.

And you should not rely on halt (this will cause a problem if another device than the VDP sends an interrupt signal). It's good for a simple sample program but for a game to be published you should use more robust synchronization mechanism. You can check MSXgl's s_sprite sample for a use case of "clean" v-blank synchronization and using of h-blank to change sprite render parameter (size and scale in this sample).

https://webmsx.org/?ROM=https://github.com/aoineko-fr/MSXgl/...

Depending on your target format, you also have options to add MSXgl specific ISR code that is optimized for games and ensures identical behavior on any machine.

Page 1/2
| 2