Mega Man greyscale scrolling demo with music!

I’ve made a demo showing Mega Man running to the right against a background! It looks very much like the image above, except fully animated. It’s greyscale (or a flickery attempt at it) with two shades of grey along with black and white. It also plays a two channel song. The graphics and music are both from Mega Man 2, Wily’s Castle stage 1, on the NES. This stage, with this music.

The d-pad changes the display mode. Pressing left is the default, showing two shades of grey. Pressing right shows only one shade of grey (this actually looks worse and more flickery on my dev kit). Pressing up changes it to black and white only, which is incredibly smooth and very pretty. :smile:

The buttons change the sound mode. The A button (the left one) mutes the music, while the B button restarts it. If you turn on the unit while holding A, it will start up muted.

It’s a fairly simple demo but it brings a lot of stuff together to be a good demonstration of what the Arduboy is capable of! Get it here on GitHub.

Video courtesy of @Wozza!

Some technical info:

As of the 5/27/2015 version of this demo,

Sketch uses 18,622 bytes (64%) of program storage space. Maximum is 28,672 bytes.
Global variables use 1,249 bytes (48%) of dynamic memory, leaving 1,311 bytes for local variables. Maximum is 2,560 bytes.

This includes a font that isn’t used which takes up 1,275 bytes of ROM. The song alone is 5,319 bytes. The graphics are 1,536 bytes, which includes Mega Man’s transparency masks, and one repeated sprite in Mega Man’s run animation in order to simplify the code.

An older version of the demo before the music code and data was introduced, and with the font commented out, resulted in this:

Sketch uses 10,030 bytes (34%) of program storage space. Maximum is 28,672 bytes.
Global variables use 1,221 bytes (47%) of dynamic memory, leaving 1,339 bytes for local variables. Maximum is 2,560 bytes.

Music handling is fairly hefty, though we may be able to compress it in the future.

The music code is part of an updated Arduboy library provided to us on IRC by GoatKing, the Arduboy team’s programmer. It’s a modification of a library called playtune, intended for playing music on Arduino with piezo speakers. The author of playtune also wrote a companion program called miditones that converts a midi file to playtune’s format, which I used to create the included song. You can download his software here. Since the speaker has only two channels and the NES has more than that, I had to eliminate some of the channels from the music. I chose to keep the lead and bass, sacrificing the harmony and drums, and it sounds pretty good in my opinion.

I modified the arduboy library’s drawbitmap function to overwrite pixels in the screen buffer instead of ORing them. This way, every frame I could draw the background slices over everything else, “wallpapering” over what was there before, and not needing to clear the screen buffer first. It’s wasteful of some cycles to draw on top of what’s already been drawn, but for a simple demo like this it’s not a huge deal.

I also copied drawbitmap to create a second function, drawmaskedbitmap, which can draw transparent sprites over existing background. First, the mask is ANDed with the background, which creates a black silhouette where the sprite will be drawn and leaves the rest of the background alone. Then the sprite is XORed over the top, which fills in the silhouette with Mega Man, in this case.

11 Likes

Good stuff!, keep it up!

Great unclesporky ! For me, 2 colors version is better than the grey scale one.

I agree. In practice the single shade of grey should run better, so I’m not sure why it looks worse. It’s most likely a timing issue, just drawing the frames at the wrong times to the screen, because we don’t have an ideal way to synchronize our drawing to the screen at the moment. I may try doing it with some calculations later.

Looks amazing. I noticed a slight increase in the flicker when on battery versus USB. I wonder if that is because the processor is taxed or the screen is not getting enough power no idea.

Wow this is already more than we expected to come out so soon! Nice job! And you are right this does almost max out the device, it was never meant to be a full on emulator but this is an incredible tech demo! We will for sure have to put more memory on the next device :smile:

As far as flickering under the battery, the coin cell voltage is technically a little low for the screen.

Nice work!

I think the screen tear isn’t all that bad if the youtube video isn’t making it look any better. It’s definitely something I could learn to deal with quite easily, especially given the benifit of doubling pixil “color” choice.

The video kind of makes it look better than it does in real life. The quick change in amount of light in an area of the screen makes it unbearable to keep watching after a couple of minutes. If that. However the bottom of the screen which used less grey was never a problem, just the top section.

1 Like

With proper timing you can get the Vysnc really really close. I played around with Megaman more with a faster SPI clock (which helps). You can get the sync so close that the you can watch it closely creep up or down the screen… not sure what to do with this info, but it’s interesting. You can find my changes in my repository.

Unfortunately it’d be nigh on impossible to get Vsync just through clever timing, it’s a just a damn shame there’s no Vsync.

Great tech demo though! :slight_smile:

Right, but it’s pretty awesome to see how great it looks when the signal is off the screen. :slight_smile:

Heheh, I can imagine it’d be brilliant for just a moment :wink:

More than a moment. You can get several seconds of perfectness if you’re careful.

1 Like

What a great tech demo :smile:

thanks for sharing, made my eyes ligh up once i flashed it and tried it out!

Just wondering, does Arduboy have a hardware scroll, or do you have to do it all with software?

Mostly software for anything you’d want to do. The hardware scroll is pretty much useless vertically (see PDF). It’s better horizontally but you can’t update the screen while it’s scrolling - so all you could use it for is to draw a large graphic and then scroll that graphic (with no changes) right or left. Couldn’t be used to help you build a side-scroller… the hardware support is really more of a “screen saver” feature than anything else. The hardware does support changing the offset the SSD1306 controllers RAM is rendered from… so you could perhaps take advantage of that… but for most things it’s going to be easier to just think fo the screen as “static” and do it all in software.

Thanks, that’s what I thought.

The hardware itself is WAY more than fast enough for anything you’d want to do with a simple horizontal scroll. I did some very rough math and got like 529 FPS. Vertical is harder on the hardware but also probably also more than fast enough for most uses.

Oh yeah I figured such a small screen would be pretty fast to update.

Awesome work. I know y’all have moved on to even more awesome demos and wicked looking games, but I used this demo as a base for mucking around with arduboy and I modified it to have some decent little platform jumping action going (took me far too long to figure out how you’re using the drawMaskedBitmap and I hacked up the original MaskedBitmap even more because of horizontal draws don’t work well). Anyway, lame video here: :smile:

Lame Platform Video

Just wanted to give thanks for all your great work so far!

3 Likes