Go Penguin WIP platformer for MSX 1

Pagina 1/10
| 2 | 3 | 4 | 5 | 6

Door albs_br

Champion (265)

afbeelding van albs_br

16-02-2021, 00:31

https://www.youtube.com/watch?v=oqkaphJdSPE

This is my first try on a V-Blank Sync'ed game. Here 60 fps (NTSC).
The color borders are a well known method to give a measure of the time running each piece of the code
Yellow: Blit sprite attribute table, from a RAM buffer (128 bytes);
Blue: Blit all of names table, again from a RAM buffer (768 bytes);
Green: loop through bottom third of names table buffer, adjusting tiles to the next pre-calculated scrolled tile when other than black, at each 8 pixels rotate tiles, and load new column at right border;
Purple: idle time: here will be placed all game logic

The green code is taking much time and will be repalced by an entire new strategy.

Aangemeld of registreer om reacties te plaatsen

Van Grauw

Ascended (9817)

afbeelding van Grauw

16-02-2021, 01:14

Nice! Looks like a good start!

A tip I have if you really never want to drop a frame in a vsynced game, is to program everything to always run for the worst case. So e.g. do not perform optimisations on the amount of sprite attribute table writes if you need less than the full amount. Focus any optimisation around reducing the worst case. Then you will keep a predictable frame time (like you have now) which will help you budget time for different elements of the game to ensure you stay under that 16.7 ms mark.

And then only in the last stages of the project you can consider to do best-case optimisations, where if the optimisation occurs there is time free for additional things that are not time-sensitive and do no harm if they’re skipped sometimes, like decorative background animations, or collision checks that do not need frame precision.

For example in Tile² (wip) I always draw background tiles for scrolling on both sides even if it’s not scrolling or only scrolling in one direction. Similarly, I always update all 32 sprite colour tables. Even though they would be easy to optimise, just to keep the worst case budget stable. If I then later I need additional time for something, I can choose to hardcode the order of sprites so I can reduce the colour table changes (keeps budget stable), or I can choose to only allow it while not scrolling (makes budget unstable but still predictable).

Van Bengalack

Champion (384)

afbeelding van Bengalack

16-02-2021, 16:42

Cool! Please let us make more smooth scrolling games on the MSX Smile

And when you're getting taken by the optimization-addiction, like many of us are, use Grauw's profiler script. It's your friend (and saviour). I also recommend VS-Code + https://marketplace.visualstudio.com/items?itemName=theNestr...

And don't forget to show us the progress along the way :)

Van albs_br

Champion (265)

afbeelding van albs_br

17-02-2021, 03:18

Thanks for the support and hints.

Today I made several changes:

-Not using Names table buffer anymore, instead reading the level data and spiting OUTI directly, this way I managed to scroll the entire screen using around 1/3 of one frame time. I think the names table buffer should be a good and straight option for simple games, but when performance is key, custom routines are necessary;

-Pre calculating all the 8 subframes of animation. That was the only way to achieve a good performance. The Z80 is slow even to make a small operation (increment if different than 0) over each 768 bytes of names table;

-This leads to a HUGE use of data for each level. Supposing 20 screens: 20 x 32 columns x 24 lines x 8 animation frames = 122kb PER LEVEL ! Compressing is not a good idea, as the 16kb of RAM (Msx Dev rules) will only fit a small part of level and uncompressing will stop the action (maybe using something as Mario entering the pipe to mask this time, it's an idea). I will have to use MegaROM;

-I discovered that unrolled OUTI's works well on MSX 2 but ruins the screen on MSX1 (of course everone knows that, but as Morpheus said: "now you know the difference between to know the path and to walk the path").

Many work for a day, but small visible results. Hopefully creating the foundations for more progress over the next days.

Van santiontanon

Paragon (1390)

afbeelding van santiontanon

17-02-2021, 03:43

Very interesting progress!! I just want to emphasize what Bengalack said: that profiling script from Grauw is a must for optimization Smile I use a customized version of one of the very first versions Grauw posted, but that is enough for me. It's super useful to know exactly how many CPU ticks each of your functions is using Smile

Van albs_br

Champion (265)

afbeelding van albs_br

18-02-2021, 04:10

https://youtu.be/r1bG3q6Xnkc

Update: now working full screen
Scroll to right is a bit faster because I'm using unroled OUTI's on the first 16 lines and the slower OUTI's on the last 8. There are two different routines for left and right scrolls because they have a bit different algorithm and speed is crucial, not space, so there will be some code repetition. It's ubly, but for a good reason, and I'm sure many professional game resort to this kind of thing.

That's the all work I've done on the 5 days of carnival holyday. It's far less than I expected. Almost all kinds of work looks easier than they really are...

Van albs_br

Champion (265)

afbeelding van albs_br

19-02-2021, 22:50

I was doing some calculations (TMS 9918 Screen 2):

3.58 MHz / 60 frames = 59,667 cycles / frame

divided by 256 lines = 233 cycles / line

visible screen = 192 lines = 44,750 cycles
v blank = 64 lines = 14,917 cycles

Are these numbers right?

Van Grauw

Ascended (9817)

afbeelding van Grauw

19-02-2021, 23:10

There are 262 lines on NTSC and 313 lines on PAL. Each line takes exactly 228 CPU cycles if the VDP and CPU are clocked by the same clock crystal. Consequently, a frame takes 262 × 228 = 59736 CPU cycles on NTSC and 313 × 228 = 71364 CPU cycles on PAL. The precise display frequency is therefore 59.92 Hz on NTSC and 50.16 Hz on PAL.

You can find the specification of this in appendix section 7 of the V9938 application manual and in section 3.6 of the TMS9918 application manual.

Van albs_br

Champion (265)

afbeelding van albs_br

28-02-2021, 04:18

Grauw wrote:

There are 262 lines on NTSC and 313 lines on PAL. Each line takes exactly 228 CPU cycles if the VDP and CPU are clocked by the same clock crystal. Consequently, a frame takes 262 × 228 = 59736 CPU cycles on NTSC and 313 × 228 = 71364 CPU cycles on PAL. The precise display frequency is therefore 59.92 Hz on NTSC and 50.16 Hz on PAL.

You can find the specification of this in appendix section 7 of the V9938 application manual and in section 3.6 of the TMS9918 application manual.

Thanks Grauw, very informative.

Van albs_br

Champion (265)

afbeelding van albs_br

28-02-2021, 04:25

These days I have been involved on the creation of a set of tools for making the animated tiles and the pre calculated tiles map of levels easier. Hopefully this work pays off when doing the levels.

Now using MegaROM, 96kb per level (!!!) for a level 16 times the screen size (as a reference, world 1-1 of SMB is 14 times the screen size). Will be a fat game. There is no other way, this must be pre calculated as I fear there will be no available time to decompress it during gameplay, and no RAM to decompress all at the level start (16kb constraint).

After 1 week and more than 40 commits finally there are some visible progress to show you guys:

https://youtu.be/PqPOFZmZ9V4

Next week, I will put the player sprite (the classic Penguin) and some basic game play (never made a platformer before).

Van santiontanon

Paragon (1390)

afbeelding van santiontanon

28-02-2021, 05:07

Very cool progress!!!

As for the size of the level, I am sure it can be decompressed in real time Smile There's lots of techniques that you could use. For example, the two easiest ones:
- Use RLE encoding. Given maps typically have a lot of empty background space, this would probably cut the map size by 8-10 easily. RLE is extremely fast to "decompress" (and often you don't even need to decompress it, and you can directly put the RLE decoding routine into the function that copies data to the VDP). If I remember correctly, that's what Reidrac's Uchusen Gamma game uses to reduce map size.
- Another option is to compress it in chunks (so you don't need to decompress the whole thing at once). That's what I did in my game The Menace from Triton (16-tile wide chunks decompressed to a circular buffer).

But in any case, it's up to you if you want to fight for cartridge size. If that doesn't matter to you, then having the maps directly in the ROM is totally fine Smile

Pagina 1/10
| 2 | 3 | 4 | 5 | 6