Grauw’s RPG in development

Page 21/25
14 | 15 | 16 | 17 | 18 | 19 | 20 | | 22 | 23 | 24 | 25

By PingPong

Prophet (3833)

PingPong's picture

05-09-2019, 22:10

time ago i've done some experiments. my sprite rotation routine worked in this way:
a screen 5 line is 128 bytes. that is 8 sprite color table. so my rotation issue vdp commands by copying a slice of 8 sprites
frame 0:
no change in sat
every next frame:
scroll an entire line from y+1 to y by three lines. the y+1 line is copied by CPU, then CPU write the SAT.
then after 4 frames all 32 planes are cycled.
At every frame the CPU writes the sat (128 bytes) + one line of SCT (128 bytes). the VDP moves 128x3 = 384 bytes.

Not sure if you can get some suggestion by this... not even sure if i've explained in a clear way the process...

By Grauw

Ascended (10295)

Grauw's picture

05-09-2019, 22:25

Interesting approach to cutting down the overhead of writing the SCT! Those 512 bytes are quite heavy on the CPU to deal with so it pays off to approach it creatively.

My current plan is to avoid sprite flickering so hopefully I won’t need that technique Smile. However I am probably going to need sprite sorting at some point, which is why I do keep in mind the ability to reposition sprites and already rewrite the SCT every other frame to keep the budget reserved.

I think using VDP commands to manipulate sprite data is not obvious at first because it’s not bitmap data, but really powerful once you have it in mind. I also do my character animations with a copy to the sprite pattern table, and absent the ability to separately set the SCT address (since I update it at half speed) I simply copy it from the first into the second SAT+SCT (double-buffered).

By Grauw

Ascended (10295)

Grauw's picture

06-09-2019, 21:59

Inspired by Reidrac’s “Reidrac is coding” series I thought let’s record a coding session of my own! So here I am implementing the first part of this sprite routine optimisation:

https://youtu.be/nOg4X92f7os

Get some insight in my coding style and tools, and enjoy the feeling of anticipation of me finding coding errors that you’ve spotted way before I do! Yes I also noticed afterwards that I’m writing the colour data for the mana sprites twice :).

Intermediate results are not as good as I hoped :), but it’s still going to save several thousands of cycles.

By Manuel

Ascended (18383)

Manuel's picture

06-09-2019, 22:06

Great stuff, thanks for that! Smile

By Thom

Paladin (685)

Thom's picture

07-09-2019, 12:07

Although I didn't watch the full video (but may do so when I've got a bit more spare time), I liked it a lot. I laughed when you were laughing at bugs. I have to admit I have a different style. To me, programming means shouting and moaning until it works.

I noticed you're using a lot of tools I'm using myself as well (though I'm on Windows). I'm also using VS Code, Glass, OpenMSX and the debugger. However, it seems you've managed to get these tools working together way smoother than I have (so far). So, I'd like to see a video about your development set-up and how you made it. I like VS code a lot, but it ain't easy, but that could be me.

By DarkSchneider

Paladin (942)

DarkSchneider's picture

07-09-2019, 13:12

I'd not recommend to go that way. Even in the case it would work, it only would be usable for the very exact case in the future, as it even requires the design to fit. Go for something more flexible so you could design something a bit different in future games without redoing all the stuff.

Also, why do you have a fixed value of CPU cost? It will depends on how many sprites do you draw right? Wink
So, when drawing the full 32 sprites it will take a good ammount, but when drawing only a few, it is a very lightweight task. It is normal that when drawing more sprites to be a heavier task.
So, simply store the color data into RAM, and update only the required ammount of data, that is until the sprite you put at the disable sprites from here Y coordinate.

About overscan, now that I see the case, well you hide vertical borders, but you also have horizontal borders, that cannot be hidden. So:
1) On displays like mine one that barely shows horizontal borders, the vertical ones are really small and don't bother.
2) On displays that shows clearly vertical borders, you also have horizontal borders that cannot be hidden.
3) On displays that always works on PAL-50 resolution, you would have big vertical borders, even if it does not shows horizontal ones with its zoom.
I sincerely only see really effective for the case 3. So I'd not bother much about overscan in cases 1 and 2. In the case 2, the one you put, without overscan OK you have borders, but with a centered visible area, with overscan you have more visible area, but breaking the area aspect ratio. I really have no preference, is more a matter of own preference.

By Grauw

Ascended (10295)

Grauw's picture

07-09-2019, 15:36

Thom wrote:

I noticed you're using a lot of tools I'm using myself as well (though I'm on Windows). I'm also using VS Code, Glass, OpenMSX and the debugger. However, it seems you've managed to get these tools working together way smoother than I have (so far). So, I'd like to see a video about your development set-up and how you made it. I like VS code a lot, but it ain't easy, but that could be me.

That’s a nice idea! I might do that. Thanks for watching Smile.

By Grauw

Ascended (10295)

Grauw's picture

07-09-2019, 15:44

DarkSchneider wrote:

I'd not recommend to go that way. Even in the case it would work, it only would be usable for the very exact case in the future, as it even requires the design to fit. Go for something more flexible so you could design something a bit different in future games without redoing all the stuff.

Hmm I get your consideration for future games (from the engine mindset), and if it doesn’t fit within the 4 sprite grouping method I would need to change it. E.g. I think a platformer would fit perfectly but a shmup probably not. But that’s a problem for then and this is now, and this approach is still reasonably flexible.

It sure puts some restriction on the sprite use, but it’s better in terms of CPU usage and code structure, so there’s a trade-off. It’s not the only restriction / assumption in the engine either, e.g. SCT/SPT updating and sprite sorting are limited to 30 fps, and latency is higher due to double buffering. I think it’s unavoidable to tailor the game’s design to the system’s limitations, and the engine to the game’s requirements. (Even on modern platforms.)

DarkSchneider wrote:

Also, why do you have a fixed value of CPU cost? It will depends on how many sprites do you draw right? Wink So, when drawing the full 32 sprites it will take a good ammount, but when drawing only a few, it is a very lightweight task. It is normal that when drawing more sprites to be a heavier task.

In a few words: easy performance measurement & tracking.

I have a strict 33.3 ms budget per game loop to avoid frame drops. Because all primary game functions are fully active even when unused (background painting, sprites, etc.), after booting up the emulator I can immediately compare the performance before and after a change, and how much time is left.

Of course I can’t eliminate all variance (e.g. the dialogue box doesn’t have constant overhead), but because there are fewer variables it is much easier to keep a clear picture of the precise usage of the frame budget.

If you only update what’s necessary and have to go to a place with lots of sprites while continuously moving around and collide with as much as possible whilst also opening a dialogue box, it becomes very difficult to do reliable performance measurements.

Now if I want to e.g. do some expensive effect in a specific area of the game, I’m forced to explicitly instruct the engine to e.g. limit the nr. of sprites or disallow movement to make room for it. When the game nears completion I can consider to optimise these cases to use the freed time for something that can dynamically adapt to the time available.

DarkSchneider wrote:

In the case 2, the one you put, without overscan OK you have borders, but with a centered visible area, with overscan you have more visible area, but breaking the area aspect ratio.

Note that the pixel aspect ratio doesn’t change. It just shows bitmap where it would otherwise show the border colour. So there’s no negative flattening type effects. And the display area’s aspect ratio is already variable (240×192, 256×192, 256×212, 248×212, etc.) so there’s really no “correct resolution” (true 4:3 would be 256×218).

DarkSchneider wrote:

3) On displays that always works on PAL-50 resolution, you would have big vertical borders, even if it does not shows horizontal ones with its zoom. I sincerely only see really effective for the case 3.

It is indeed really effective for 50 Hz, but there it also requires more trickery since the screen rolls over (bitmap height is 256 while it displays 294). So to make a really nice proper full screen overscan at 50 Hz you also need a page split. It would be cool if someone did it sometime, but for this game I want to stick to a single 256x256 page.

Example of 50 Hz overscan (pink stuff is missing tile map data):


So many pixels :D.

By DarkSchneider

Paladin (942)

DarkSchneider's picture

07-09-2019, 16:34

But do not make the assumption that can always group into 4 sprites. Even on a platform or RPG, you can get 16x16 multicolor sprite, that are 2 sprites. OK you can always force it to 4 sprites setting 2 of them blank, but in general is not really nice for design with a so strict restriction.
I also though about it, as they are line aligned, but quickly I realized about the huge restrictions it brings for design. It also forces to update all the character animation at blocks, instead frames, a typical example is the character that changes legs but not body, so bye bye to character frame composition possibility too.
That's why I miss something like this
And, it is not only something about cycles, but if between those small commands you can really do something other stuff. In other words if in practice is effective enough.
IMO worrying so much for maybe some possible slowdowns on the base Z80A is not worth compared to all restrictions, extra work and probably lack of portability for future proyects.
At this point I see more worth to think more about the event handling, how to manage that when you get something the dialogues will change, the mission tracking, item system, etc. It is much logic to handle so if something happens at A it changes also things at B and C.

By Grauw

Ascended (10295)

Grauw's picture

07-09-2019, 17:19

DarkSchneider wrote:

But do not make the assumption that can always group into 4 sprites. Even on a platform or RPG, you can get 16x16 multicolor sprite, that are 2 sprites. OK you can always force it to 4 sprites setting 2 of them blank, but in general is not really nice for design with a so strict restriction.

You assume it’s a problem to waste a sprite or two here and there Smile. That is the penalty, but that’s okay! At least for me. And depending on use you could put two of those in the same object (e.g. two shooting orbs circling the player). They don’t need to have the same location, e.g. the rain effect is all over the screen.

DarkSchneider wrote:

I also though about it, as they are line aligned, but quickly I realized about the huge restrictions it brings for design. It also forces to update all the character animation at blocks, instead frames, a typical example is the character that changes legs but not body, so bye bye to character frame composition possibility too.

You can still select individual positions and patterns for each sprite. Just the colours must be pre-set in a table in groups of four, so if the legs change then you just need to update it. This is not something that needs to change every frame, and even if it does then you can put all permutations in VRAM. (Also this isn’t really a common case I think.)

DarkSchneider wrote:

And, it is not only something about cycles, but if between those small commands you can really do something other stuff. In other words if in practice is effective enough.

Not really, setting up a command is 15 OUTIs, to save 16 OUTIs, it does not make sense anymore to do commands.

DarkSchneider wrote:

IMO worrying so much for maybe some possible slowdowns on the base Z80A is not worth compared to all restrictions, extra work and probably lack of portability for future proyects.

Well, we have different priorities. For me a smooth experience is paramount. Portability for future projects is not a concern, if needed I can simply change the code. Likely the sprite code needs revisions anyway because e.g. it can’t handle flickering (which I ab-so-lutely am not going to implement now).

Page 21/25
14 | 15 | 16 | 17 | 18 | 19 | 20 | | 22 | 23 | 24 | 25