Gameboy Emulator

Hi everyone,

I wanted to share my Gameboy Emulator that I wrote using Microsoft MakeCode. I took on this project mainly as a challenge and to push the limits of what is possible with MakeCode :slight_smile:

I really love this platform and have used it to work on some games with my 7 year old daughter. It got me thinking about what could be possible. The MakeCode screen (at 160x120) is very similar to the Gameboy screen (at 160x144). So I basically had to squeeze it slightly in the vertical direction but horizontally you don’t lose any pixels.

That being said the emulator itself currently runs pretty slow, averaging around 20-25 frames per second on most games using the simulator. On real hardware it’s even worse at around 2 FPS -

The game included is an unfinished demo I had been working on. In order to load your own roms look at the top of the code for the instructions. Basically you need to convert it to a MakeCode Image for it to work. When I originally started working on the project I stored the rom data as a simple number array but the app would not compile saying the program was too large. This could be some kind of memory constraint. However after encoding it into an image it worked. Possibly this is because the hardware stores images/assets in another part of the memory that is larger? not sure but that is my theory. So the image approach worked fine since each pixel is 4 bits (16 colors) so I used 2 pixels to represent each byte.

Anyway, I’d love to get some feedback. Also any tips on how I can improve the performance would be highly welcome. All of the rendering is done by using setPixel directly to the background image. Though I think just emulating the Gameboy CPU which originally ran at around 4mhz is the main bottleneck. I am relatively new to this platform so would love to hear what people think and if there is some way to squeeze more performance out of it.

Thanks!

22 Likes

wow! this is amazing! this will be AWESOME for my meowbit

you could change the screen size of the simulator using

namespace userconfig {
    export const ARCADE_SCREEN_WIDTH = 160
    export const ARCADE_SCREEN_HEIGHT = 144
}

i did run into an issue, due to the size limit of makcode images some roms dont fit, such as super mario land 2.

3 Likes

You might get better speed using image.setrows instead of setpixel!
Amazing job by the way.

2 Likes

what you can do (i forgot how) is to change the button color to white to match it!

2 Likes

I think @DangerNoodle is referring to [Tutorial] How to Change the Simulator Color

2 Likes

@nbarkhina images, strings, numbers, etc. do indeed get stored in the flash storage of the game rather than in memory which has a lot more available space. declared arrays don’t get the same treatment, so they end up taking memory (and also cause the code generation to be much less efficient).

however, instead of images you might find it easier to use buffers for storing data. the syntax for buffers looks like this:

let myBuffer = hex`0123456789ABCDEF`

data declared this way is also stored in flash, but buffers are much easier to get bytes (and other number types) out of, plus you can put them all on a single line :slight_smile:

for reference, here’s a code snippet that you can use to convert a Uint8Array into the string format that the hex syntax expects: https://github.com/microsoft/pxt/blob/35170650487739b2d029ecdece19e4716e8176d4/pxtlib/util.ts#L966

3 Likes

Very cool! As @brohann said, setRows is very useful, especially combined with a buffer and a renderable

1 Like

This is crazy! I’d never thought I would be playing pokemon inside makecode arcade.


Let alone a full gameboy emulator!

3 Likes

awesome!

1 Like

Really cool !

Sorry to ask, but is there any unnecessary code in here? I’ve been trying to cut down some of the code to use less storage space so that it would fit on my Meowbit. Thanks!