No description, website, or topics provided.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
PokemonTheme Add the pre-encoded Pokémon Theme Aug 30, 2015
doc_images
.gitignore gitignore Aug 30, 2015
GBEncode.atn Photoshop Pre-encoder action Aug 30, 2015
How It Works.md Added "How It Works" page Aug 31, 2015
LICENSE Added license Sep 1, 2015
Makefile Created Makefile Aug 30, 2015
README.md Update README.md Jun 9, 2016
convert.py Initial Commit Aug 30, 2015
gbhw.asm
itt.py Created Makefile Aug 30, 2015
music.itt Initial Commit Aug 30, 2015
png.py Initial Commit Aug 30, 2015
video.asm Initial Commit Aug 30, 2015

README.md

Player

This is a technical demo demonstrating how the Gameboy LCD controller can be hacked to make a Gameboy Color play a full motion video in color, together with music. It is inspired by 8088 Corruption and 8088 Domination.

tl;dr

Here's a video of a Gameboy Color playing the Pokémon TV Opening. You can get the ROM at the releases page and run it on your Gameboy Color with a flash cart or an emulator with good accuracy like BGB. You will need to turn on inter-frame blending in the emulator for accurate results.

Technical Specifications

The player itself, due to the high optimization requirements and CPU cycle counting, is written in Z80 assembly. The video encoder has two stages, with the first one being a batch script run by Photoshop, and the other being a python script. The music is written in an OpenMPT-style textual format, which is later converted to a compact binary format which is easy to play.

The Gameboy Color uses a 8MHz Z80 8-bit processor, which effectively runs at 2MHz (Since the CPI of each instruction is a multiple of 4). To play the Pokémon theme in a good quality (I.e. not too many frame skips) it requires a 7.6MB ROM, which is huge in Gameboy terms. The LCD controller (OAMs are ignored by the player) is designed to output, in 60 FPS, a 160x144 image, composed of a map of 32x32 tiles size 8x8, each can have a 4-color palette from a selection of user-defined 8 palette. It does not allow direct pixel access. Since the player uses less than 20 bytes of RAM (slight stack use and a very small state), memory is not an issue.

There's an article explaining How It Works.

The video format has the following properties:

  • Effective frame resolution of 40x144 pixels, resized to fill the 160x144 Gameboy screen
  • Effectively up to 528 different colors per frame
  • 30 Frames per second
  • Can repeat a single frame for up to 127 times, allowing the encoder to skip similar frames
  • The player and the encoder have a buggy (and disabled) support for what I call a row-back-reference compression. Any type of in-row compression simply can not work because there aren't enough free CPU cycles to decompress it.

Hardware support

Any MBC5-capable cart that is big enough to store the ROM should be enough. It was tested only on an original Gameboy Color (And only one to be honest), but will probably work on a Gameboy Advance too.

Emulator support

Due to exploiting hardware hacks and very precise timing, the player works only on a few emulators. BGB was the first one capable of reasonably emulating the player, and it's still wasn't perfect. Additonally, Higan 0.97 and SameBoy now support it too. During development, there used to be another emulator (forgot its name, sorry!) that could run it; however, I had to make a choice between supporting it and supporting BGB, as a single opcode change (removing or adding a nop in the STAT interrupt) would break it for one and fix it for the other, and the other emulator did not have any debugger. For best results, use an emulator that support inter-frame blending.

Compilation

You will need rgbds. To compile a player playing the Pokémon TV Opening, run:

make VIDEO_SRC_FOLDER=PokemonTheme

To convert your own video, split it into a sequence of PNGs, and batch run the included GBEncode Photoshop Action on all of them. The output images should be named 0.png, 1.png, ..., n.png and be placed on a folder of their own. Then run:

make VIDEO_SRC_FOLDER=MyVideoFolder