8-way scrolling from SD uncompressed demo
Posted: Wed Apr 11, 2018 3:13 am
I had planned on keeping this under wraps before this year's Uzebox Code Contest, but I realized that I need some real-world testing with real SD cards (not emulation) before I can rely on this technique in a finished game.
I started off with the horizontal and vertical scrolling code from my Uzebox Mode 3 with Scrolling Guide, which stored the level uncompressed in PROGMEM, but I quickly realized that I wouldn't be able to store large, or many levels that way.
Level compression always seems to complicate things, and it makes the level format very rigid and tough to quickly add features, and it makes it that much harder for people to understand what's going on without really studying the code.
One of my goals was to be able to get 8-way scrolling working completely from the SD card, without having to use any kind of level compression, so that I could use the extra bits in each tile for things like enemy spawns, or triggers, or any other game extension one might think up. The attached demo is far from optimized, but if it works as it is, that means that I'll be able to squeeze a lot more out of it after optimizations. It's actually reading an extra 384 bytes from the SD card each time you scroll past a tile boundary, so I actually have a crap-ton of room leftover to store additional stuff for the level, or if I don't need to store anything in those extra bytes, I can reduce the size of the data file by a factor of 4.
What I really want to know is when you guys run this on real hardware, does any part of the 4x3 mega sprite flicker as you run and jump around?
The code determines if the camera has scrolled enough to need additional level data loaded into a hidden row and/or column, and then it cue's up the sector containing that level data, by issuing a CMD17, but it doesn't actually look for the data ready token until sometime during the next frame, allowing:
to run while the SD card is busy getting ready to read that sector. The idea is that we can be doing useful work instead of spinning waiting for the data ready token, and then once many tens of thousands of clocks have passed (all those functions listed above), the SD card should then immediately respond with the data ready token and we can clock out the actual data stored in that sector with no delay. Since we are only writing to hidden rows and/or columns, the fact that we don't actually write that tile data out until the beginning of the next frame doesn't make any difference. Those tiles will still get written before they are seen, but we are spreading the work out across multiple frames, and not sitting around waiting for the SD card, which (at least for me with my SD card) allows everything to run at 60fps.
One caveat of this technique is that I needed to make sure that no matter how big the level is, or which of the 8 directions the camera gets scrolled in, I only ever need to read a single sector's worth of data.
That's the theory behind it anyway. Whether it works in practice on more than just my SD card is what I need people to help me test out.
Controls are as follows:
Make sure you hold B to run!
(If you do run this under cuzebox, you'll need to have a cuzebox built with the latest changes as of April 9, 2018; it will run fine with uzem.)
I started off with the horizontal and vertical scrolling code from my Uzebox Mode 3 with Scrolling Guide, which stored the level uncompressed in PROGMEM, but I quickly realized that I wouldn't be able to store large, or many levels that way.
Level compression always seems to complicate things, and it makes the level format very rigid and tough to quickly add features, and it makes it that much harder for people to understand what's going on without really studying the code.
One of my goals was to be able to get 8-way scrolling working completely from the SD card, without having to use any kind of level compression, so that I could use the extra bits in each tile for things like enemy spawns, or triggers, or any other game extension one might think up. The attached demo is far from optimized, but if it works as it is, that means that I'll be able to squeeze a lot more out of it after optimizations. It's actually reading an extra 384 bytes from the SD card each time you scroll past a tile boundary, so I actually have a crap-ton of room leftover to store additional stuff for the level, or if I don't need to store anything in those extra bytes, I can reduce the size of the data file by a factor of 4.
What I really want to know is when you guys run this on real hardware, does any part of the 4x3 mega sprite flicker as you run and jump around?
The code determines if the camera has scrolled enough to need additional level data loaded into a hidden row and/or column, and then it cue's up the sector containing that level data, by issuing a CMD17, but it doesn't actually look for the data ready token until sometime during the next frame, allowing:
Code: Select all
Player_render(&p);
ProcessSprites();
WaitVsync(1);
RestoreBackground();
ReadControllers();
One caveat of this technique is that I needed to make sure that no matter how big the level is, or which of the 8 directions the camera gets scrolled in, I only ever need to read a single sector's worth of data.
That's the theory behind it anyway. Whether it works in practice on more than just my SD card is what I need people to help me test out.
Controls are as follows:
Code: Select all
LEFT/RIGHT = Move
DOWN = Drop through the thin one-way tiles
A = Jump
B = Run
LS = Attack
(If you do run this under cuzebox, you'll need to have a cuzebox built with the latest changes as of April 9, 2018; it will run fine with uzem.)