Giter Site home page Giter Site logo

unitygb's Introduction

UnityGB

UnityGB allows you to run a Game Boy ROM inside your Unity project. It has been written in C# and is only using Mono allowing you to export the project to any platform supported by Unity.

UnityGB became the main subject of several articles like CNET, Gameboy emulator on the Oculus Rift: Gameception.

UnityGB is still in alpha version, many bugs and glitches can occur. Also, the code is far from being perfect and needs a lot of optimization. Any and all help welcome! Please feel free to contribute to this project.

Please also take some time to take a look at our other applications on our website Takohi.com and our other Unity assets. ๐Ÿ‘

Compatibilities

What is supported

  • Game Boy games with cartridge <= MBC5
  • Input
  • Sound
  • Save (save files are compatible with Visual Boy Advance and other emulators)

Planned features

  • Game Boy Color compatibility
  • Link Cable
  • Oculus Rift

Known issues

  • Sound synchronization
  • Pokemon Yellow: Pikachu voices are not played
  • Some glitches with sprites order

Demonstrations

Hilarious Gameboy Emulator with Leap Motion in Unity, by Pierce Wolcott
Gameboy Emulator with Leap Motion in Unity

Oculus Rift Gameboy Emulator in Unity, by Shane O'Brien
Oculus Rift Gameboy Emulator in Unity

UnityGB4BB10, GameBoy Emulator for BlackBerry 10
UnityGB4BB10

Official Web Demo, by Takohi
Official Demo

Usage

UnityGB can work in several ways. What you have to do is to make your own implementation about how to manage inputs (controls) and outputs (video and sound). In the Unity package and the sources, you will already find one classic scene outputing the video in a classic texture, the audio trough the OnAudioFilterRead method, and joypad input from the keyboard.

Joypad

An example of how to implement the controls can be found in DefaultEmulatorManager.cs.

When you want to emulate an input from the player into the game, you just have to call the SetInput method from the emulator reference:

void SetInput(Button button, bool pressed);

Button is an enum with these values:

public enum Button {Up, Down, Left, Right, A, B, Start, Select};

For example, if you want to press the button start when the player is hitting the space button:

if(Input.GetKeyDown(KeyCode.Space))
    Emulator.SetInput(EmulatorBase.Button.Start, true);
else if(Input.GetKeyUp(KeyCode.Space))
    Emulator.SetInput(EmulatorBase.Button.Start, false);

Video

An example of how to implement the video can be found in DefaultVideoOutput.cs.

In order to output the video from the emulator or in other words, to display the Game Boy screen, you will have to make your own class implementing the IVideoOutput interface.

This interface has only two methods:

void SetSize(int w, int h);
void SetPixels(uint[] colors);

The SetSize method will be called after the rom is loaded. It will tell you what is the size of the screen in pixels (160x144, it should never change) so you can initialize your way to display.

The method SetPixels will be called every time the frame has been updated. As parameter, an array of colors that corresponds to the color of each pixel. The size of the array will be width x height.

Here is a method to convert a uint color into a Unity color:

private Color UIntToColor(uint color)
{
    byte a = (byte)(color >> 24);
    byte r = (byte)(color >> 16);
    byte g = (byte)(color >> 8);
    byte b = (byte)(color >> 0);
    return new Color(r / 255f, g / 255f, b / 255f, a / 255f);
}

Audio

An example of how to implement the audio can be found in DefaultAudioOutput.cs.

With Unity, the only way to dynamically produce audio is by using the method OnAudioFilterRead(float[] data, int channels) from a MonoBehaviour object.

In the package, we already provide a way to produce the audio trough the DefaultAudioOutput class. If you want to use it, just attach that script to a game object and add to it an AudioSource component.

If you still want to make your own implementation for outputing audio, you will have to make a class that implements the interface IAudioOutput.

This interface has three methods:

int GetOutputSampleRate();
int GetSamplesAvailable();
void Play(byte[] data, int offset, int count);
  • GetOutputSampleRare() has to return the sample rate (44100Hz, ...).
  • GetSamplesAvailable() returns the number of samples to return during the next step.
  • Play(byte[] data) gives you the samples to play.

Samples are interleaved (%0 = Left, %1 = Right). This means for each sample: data[i] = left sample, data[i + 1] = right sample.

Save

An example of how to manage save files can be found in DefaultSaveMemory.cs.

In order to manage save files, you will have to make your own class implementing the ISaveMemory interface.

This interface has only two methods:

void Save(string name, byte[] data);
byte[] Load(string name);

The Save method is called when the user stops the game, and the Load method is called when the game is loaded. The name parameter is the name of the game that is currently played.

Globally, when the Save method is called, you simply have to store somewhere the byte array given as parameter, then load and return this same byte array when the Load method is called for the same game.

Make the emulator run

An example of how to use the emulator can be found in DefaultEmulatorManager.cs.

The code below is a simple way showing how to initialize and make run UnityGB with a MonoBehaviour script.

First, we create an instance of the emulator and load the ROM in the Start method.

void Start()
{
    // Load emulator
    IVideoOutput drawable = ...; // Reference to your IVideoOutput implementation.
    IAudioOutput audio = ...; // Reference to your IAudioOutput implementation.
    ISaveMemory saveMemory = ...; // Reference to your ISaveMemory implementation.
    Emulator = new Emulator(drawable, audio, saveMemory); // Instantiate emulator.

    byte[] rom = ...; // Load ROM binary.
    Emulator.LoadRom(www.bytes); // Load ROM into emulator.
}

Then we make the emulator running during the Update method of the MonoBehaviour. We also use this method to manage inputs from the user and send them to the emulator.

void Update()
{
    // Input
    if(Input.GetKeyDown(KeyCode.Space))
        Emulator.SetInput(EmulatorBase.Button.Start, true);
    else if(Input.GetKeyUp(KeyCode.Space))
        Emulator.SetInput(EmulatorBase.Button.Start, false);
    ...

    // Run
    Emulator.RunNextStep();
}

Don't forget to attach the previous MonoBehaviour to a game object in order to make it run.

Reference Material

unitygb's People

Contributors

konsomejona avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unitygb's Issues

Nintendo 3DS

Hey I have a bit of a strange request, im learning Unity but using my modded 3DS and building for that system witha developers license. I got a pretty cool surfing game working, and I put this on a arcade machine in the surf shop and its awesome on PC

When I try to run on Nintendo 3DS hardware i just get a black screen. Its quite limited and very comparably to developing for iphone with no jit support and uses il2cpp when compiling. It also cannot support standard shaders or programmable pixel shaders. But otherwise it quite strong and not too aware of any other limitations.

Any idea why its black screening, or things I can comment out that could help out?

PSVITA

Hey, im trying to run unity gb on vita with bad luck.
i changed few lines of code , specificaly this part
(the part of loading the rom)

	string path = Application.streamingAssetsPath + "/" + filename;
		Debug.Log("Loading rom at " + path);
		WWW www = new WWW(path);
		yield return www;

On Editor it works tho on vita i get " Error during loading the ROM.Unsupported Protocol "

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.