Skip to content

DWoC Contributor's Guide

venkat24 edited this page Nov 6, 2019 · 6 revisions

Delta Winter of Code

Introduction for prospective contributers

This is intended as a guide to help you get started with contributing to this project as part of the Delta Winter of Code event. Welcome!

I realize that the process of reading someone else's code can be daunting. I've tried my best to keep it clean but it can be difficult to understand such a project without some context about Emulators and the architecture of the GameBoy.

The fastest way to crashcourse through the GameBoy architechture is to watch this video - it's a great in-depth yet short talk about all the components that power the GameBoy.

The Ultimate GameBoy Talk

The Ultimate GameBoy Talk

If you have any questions about anything here, please don't hesitate to shoot me an email at venkat24@outlook.com.

What is tvp?

tvp is a simple emulator for the Nintendo GameBoy. It lets you play game ROMs on your computer by simulating the same operations that the GameBoy's processor and other hardware components carry out, much like every other emulator out there.

Why is tvp special?

It's not, actually. There's hundreds if not thousands of GameBoy emulators already out there, and in every programming language imaginable, and that's probably because it's a fun exercise. Understanding a hardware system and how it runs assembly code is a rewaring experience!

In fact, if you really want to learn about emulators, the best thing you can do is to try to build your own emulator. You can start with a simpler system like the CHIP-8 if you'd like, but the GameBoy is also quite simple to understand. There's plenty of guides, videos, and books about how to build an emulator - in fact there's a (reasonably active) subreddit r/EmuDev for emulator programming beginners and enthusiasts.

With that said, if you're still looking to dive quickly into an existing project and code something up, go on ahead!

How complete is tvp?

tvp is by no means 100% done. Nothing is ever done, really, but that's not the point. There are still a lot of compatibility issues and performance issues, and some entire features (like sound!) are non-existent. It's also not the easiest thing to setup and run.

This is where you might be able to help!

Potential Ideas

I'd like to add as a note here that the difficulty levels listed for each idea are rather subjective. Feel free to explore an interesting idea even if it may seem difficult!

Button Configurator

image

The example above is from an XBOX emulator, but the concept is the same. Customization is an important part of emulation, and allowing the user to remap their button and control scheme woul greatly enhance the user experience.

This feature would let the user set their own key mappings for the various gameboy buttons through some graphical interface. Even if a GUI seems difficult to achieve, a CLI for the same would still greatly aid the process.

Difficulty: Medium

Joystick Support

Console and handheld games are always best played on their native platform, and the best thing an emulator can do is try to come close. Hence, such games are often best played on a joystick or controller with a D-Pad.

Adding support for an external joystick would be a great feature, and is aided by SFML's built in support for external input devices. This feature would also very well in tandem with the next one.

Difficulty: Medium

Integrated Debugger

Any emulator works by reading machine instructions from the ROM file from the location where the Program Counter points, and continues executing subsequent instructions. Often, when developing a new game or when trying to fix a bug in the emulator itself, it is useful to be able to see what instructions are being executed, and how the system memory is being affected in real time. It's also useful to able to place breakpoints, and ask the program to stop at a specific line so that you can snoop around with the memory.

image

Other emulators allow the user to not just pause and view the contents of the registers and memory, but even edit them and continue execution. This makes the process of figuring out where the program is crashing significantly easier.

If you're considering working on a debugger, it doesn't necessary have to be GUI-based like this one in the example above. It could be a command line debugger, where you enter commands to place breakpoints and examine memory.

In terms of code, creating a debugger will involve building a system for an external object to be able to stop and start the CPU, and play with the contents of the Memory object at any tick of the CPU.

Difficulty: Medium

Play/Pause and Keyboard Shortcuts

There's no Pause/Play feature currently, so building one would be handy. Mapping these to keyboard bindings seems useful as well.

As for the implementation, the emulator runs on a main loop in the main.cpp file, where it calls the video module to tick every turn. When this module ticks, we can check if a pause/play button command is given, and return a true/false state back to main, which can hold the loop.

Difficulty: Easy

Audio System

This is currently a very sad, soundless emulator. The original GameBoy featured an audio system, responsible for producing game music and sound effects through the inbuilt speaker in the console. To emulate this feature, we must build the sound system's registers, which each control the settings for different wave generators. The developer can use these generators to produce the classic 8-bit audio effects.

image

Emulating the sound hardware is pretty tedious work, and would also require a reasonable understanding of basic waves and signal processing.

However, the nice thing about working on an old and well documented system like the GameBoy means that it is easy to study existing material and implementations of the sound system. The SFML sound library should be pretty simple to use, so this could be a very fun task if you find this interesting.

Difficulty: Hard

Extending Game Compatibility

Currently, Tetris is the only supported game. This is largely because there isn't an implementation for memory-banking yet, and so games larger than this base size of 32KB will not work.

More about the memory banker - it is responsible for switching which parts of the game cartridge are accessible at any one time. This is necessary because the GameBoy can only address or use 32KB of memory at any one time. Hence, when the game cartridge is larger than this size, the developer must choose at runtime which chunk of memory he wants to use.

Another aspect of game compatibility, is the presence of game specific hardware bugs. For example, the game Dr.Mario makes use of a bug in the way interrupt ordering is processed, and hence this game will not work unless this bug is implemented in the code. Sometimes, a bug really is a feature!

Difficulty: Medium

Save States

Games are hard. Older games are even harder. With save states, the user can record the state of the game at any point of time, and load and resume the game in the exact frame in the future. Save states are almost essential to playing classic games, and are the bread and butter for speedrunning.

Implementing save states involves freezing the entire internal state of the emulator at one point in time, and saving all that data to a file. We must be able to load the file and reconstruct the state of the memory and CPU exactly as it was when saved.

This requires building a method that can query the state of every module, and serialize that data and write it to a file. All modules must also have methods for reconstruction from this data so that the game can be resumed. Protobuf could be used as a way to serialize the objects.

If you don't want to touch the UI and would like to work on a more core feature, you can try this one out.

Difficulty: Medium