MSX2 - 8 ways smooth scrolling SCREEN 5

Página 2/8
1 | | 3 | 4 | 5 | 6 | 7

Por Grauw

Ascended (10306)

Imagen del Grauw

19-03-2014, 12:04

Hrothgar wrote:

Some ideas:

  • Sprites will often only move 1 or 2 px in a direction each interrupt so only a fraction of a 16×16 area has to be restored, unless again you have very transparent sprites.

Personally I was thinking in terms of a player character like Gilian from SD Snatcher. He doesn’t have that many solid pixels in him.

Also, be aware that relatively speaking small copies aren’t that much faster because you waste a lot of time setting them up, and the VDP is slow at moving to the next line (wide copies are faster than narrow copies). If you’d replace one large 16x16 copy with four smaller copies on each side of the character, it is most likely slower.

For this reason, 16x16 tiles are also quite a bit faster than 8x8 tiles.

Hrothgar wrote:
  • No need to 'back up', all parts can be restored by HMMM from your page containing all tiles, or even by YMMM from a corresponding tile in the same or the alternate swap page in at least 50% of cases, often more.

I thought of this, however this is only an optimisation if the sprite is exactly on a single tile. If he’s moving from one tile to the next, you will need to redraw up to four tiles to erase the sprite.

So you may think, “ok that’s slower, but you don’t need to redraw the entire tiles”. While true, because of the relative overhead of small copies and setting up four in stead of one, I don’t think that actually gains you (much) performance. Because these effects are harder to quantify, I stuck with the back-up method for this calculation.

But, you’re probably right in that it’s a better approach. Saves some memory. Seems cleaner, less assumptions about existing state.

However I think there’s an even better one: in stead of restoring with copies from the tile map, you could also restore with a copy from the back buffer. Of course this back buffer is being drawn to as well, so sometimes you need to do two copies. But still it’s not too bad.

Hrothgar wrote:
  • You don't have to restore backgrounds first for areas where a solid sprite part will be drawn. Many sprites have large solid parts, see e.g. Core Dump that uses this technique.
  • Depending on the level design, a great part of the screen might also be restored by a fill command (not in this particular demo with more elaborate tiles, but certainly in a MegaMan or Mario-kind of levels).
  • Again, depending on the surrounding background, you might be able to move the entire sprite by one copy command including a slice of its homogeneous background. That eliminates all separate restoring by issuing one copy command of e.g. 18×16 px for horizontal movement.
  • Much of the background shouldn't need wholesale copying by 16px if you have many repeating tiles, which is the case in a vast majority of games. This take a lot of VDP burden away (by adding some CPU burden).

This all will require some checks for each copy instruction. But comparing games such as Blade Lords or Core Dump, it seems you can achieve quite high frame rates with these tricks.

I am aware of these techniques, but the thing is, for a smooth scroll there is a strict limit on how much you can do each frame. If you miss only one frame it will be perceived as a very visible hitch. So, optimisations like this aren’t so useful because it doesn’t improve the worst case.

The only way it would work if you really incorporate this into the core of your level design. Make some check-tool that can prove to you that at all times, moving in all directions in any place, there will be a sufficient number of optimised tiles on screen.

For optimum results, you would have to spread these out evenly across all 16 steps before page-flipping. In stead of copying a column of 1/16th of the screen, rather copy 1/16th of the tiles that need changing. Maybe also count in a factor for blank (HMMV) tiles. My biggest concern here is, this needs to be calculated ahead of time, and between all those small back-to-back 16x16 copies you’ll be doing, there isn’t much time left. Maybe it can be precalculated.

So it could be made to work, but it’s tricky. And even though you save VDP time, the number of (moving) software sprites that can be drawn on screen would be limited. Although, of course if you’d want to use the freed-up VDP time to enable some extra animations in a specific area, you could specifically design the level around it for that to be highly optimisable.

However, it’s worth considering whether all of this would really be worth it. If you just implement for the worst case, you don’t have any restrictions in the level design, and you save a lot of programmer and CPU time by not having to implement all these optimisations. You can compensate for the lack of remaining VDP time by using hardware sprites for the moving parts.

I mean, programming this kind of engine and tools for it sounds like it would take quite a bit of time. Also level designs would take longer to complete. You may wonder whether it’s not worthwhile to spend less time on the engine, and more time on the game itself Smile. I’ve done many projects where I’ve had lots of fun programming the engine, but in the end never released anything because I spent too much time on the engine and not enough time on the actual game.

Hrothgar wrote:

Many blocky scrollers on MSX had much lower frame rates than 30fps and were deemed acceptable.

Yes but they’re moving in 8 pixel increments, so that’s not really a fair comparison Smile.

The thing I’d be most worried at 30fps about is movement speed… you don’t want the player to get frustrated because moving from A to B is so slow. E.g. Ys is perfect (it uses many techniques also used in Parallax games), but SD-Snatcher is sometimes frustrating Smile. Also, 60fps simply looks smoother, prettier.

Por anonymous

incognito ergo sum (116)

Imagen del anonymous

19-03-2014, 12:10

Grauw wrote:

optimisations like this aren’t so useful because it doesn’t improve the worst case.
*snip*
If you just implement for the worst case, you don’t have any restrictions in the level design, and you save a lot of programmer and CPU time by not having to implement all these optimisations.

You're one of the few programmers I know that *gets this*. Most ppl optimize for the average case, or even the best case (hi wouter!). Doing that will make sure that when things get busy, it will fail a lot harder.

Like you say, optimising for the worst case will keep it acceptable, and at the same time will make the average case work well too. The best case usually doesn't need optimization to begin with. In other words: don't make a slow thing slower just to make a fast thing even faster.

Por Grauw

Ascended (10306)

Imagen del Grauw

19-03-2014, 12:27

Grauw wrote:

The only way it would work if you really incorporate this into the core of your level design. Make some check-tool that can prove to you that at all times, moving in all directions in any place, there will be a sufficient number of optimised tiles on screen.

Actually now that I think of it, it’s not so bad. Vertical scrolling is pretty much free, after all. So you only need to check movement in horizontal directions.

But, I must say, you have piqued my interest Smile. I might spend some time digging up my old code, and seeing if I can try out some of the optimisation ideas. I can tell you in advance though that this is just for fun and will not lead to an actual game! Smile

Por Grauw

Ascended (10306)

Imagen del Grauw

19-03-2014, 12:27

GuyveR800 wrote:

Like you say, optimising for the worst case will keep it acceptable, and at the same time will make the average case work well too. The best case usually doesn't need optimization to begin with. In other words: don't make a slow thing slower just to make a fast thing even faster.

Yeah, and because this is a smooth scrolling 1-pixel-per-frame engine, it’s extra critical that you never miss a frame, because it would stick out like a sore thumb.

Also losing oneself in unnecessary optimisation is a very tempting thing that one must develop natural resistance against Smile.

Por AxelStone

Prophet (3064)

Imagen del AxelStone

19-03-2014, 13:14

Very nice work Wink . However I think that a 30fps scroll is nice too if it allows you to handle more sprites Smile

Por Hrothgar

Champion (479)

Imagen del Hrothgar

19-03-2014, 13:20

I know all of these thoughts also have their drawbacks and limitations. It is one of the things inevitable in developing for such an ancient and restricted machine, you need to make all restrictions combine in something that fits. This makes your comment about incorporating the level design in advance ever so true.

About precalculating incremental copying: Check whether tile A = tile B 32px further, scanning horizontally the entire level map, and store the results as single bits on a per-tile basis in the level map attributes. Seems a 1 second task.

Having done this will allow:
- Easily scanning the maximum number of 'dirty' tiles per page flip to be encountered anywhere in the game (adjust the level design proactively if needed.)
- Easily summing and pre-storing the copy burden of any page flip, giving you a rather exact indication of current VDP stress (copies / 16 for every frame) and thus spare time for non-essential animation effects.

Por Grauw

Ascended (10306)

Imagen del Grauw

19-03-2014, 14:08

Hrothgar wrote:

- Easily summing and pre-storing the copy burden of any page flip, giving you a rather exact indication of current VDP stress (copies / 16 for every frame) and thus spare time for non-essential animation effects.

That’s a nice idea… to do environment animations when the VDP load allows it.

For animations which run at say ~4 fps, a few frames of delay won’t be noticed. And some types of animations are already erratic in nature, e.g. think of a squirrel looking around. Worst case something will only animate when you’re standing still.

(Btw, note that tile-based animations need to be rendered twice, once to the foreground and once to the back buffer.)

Por Hrothgar

Champion (479)

Imagen del Hrothgar

19-03-2014, 14:24

Grauw wrote:

(Btw, note that tile-based animations need to be rendered twice, once to the foreground and once to the back buffer.)

Hardly, the animated tile in the back buffer only needs updating if
1) it is imminent to be flipped into view AND
2) its current state isn't an acceptable transition from the alternate page that is about to be flipped out of view.

Knowing the copy burden and thus the available space for X animation transitions in advance can even allow you to plan to *avoid* having to update the back buffer tile during page flip.

Por anonymous

incognito ergo sum (116)

Imagen del anonymous

19-03-2014, 14:41

So have you ever implemented your ideas, or are you just telling other people what do do? Wink

Por Hrothgar

Champion (479)

Imagen del Hrothgar

19-03-2014, 14:51

I'm sharing thoughts, some of which might be sane and feasible and might assist interested people in their endeavours. I hope that's regarded as constructive feedback in a discussion forum, and on-topic w.r.t. the original post - but feel free to disagree.

Página 2/8
1 | | 3 | 4 | 5 | 6 | 7