Mega Man Zero Level Viewer

In October of 2014, I wrote a tool capable of viewing levels from the Mega Man Zero series of games. While this tool was meant to support all four games, it was most tested on Zero 2.



While writing this tool, I decided to take a low level approach with regards to how graphics are drawn onto the screen. Rather than representing tiles as abstract "objects" which can be stored in an array and drawn when needed, I instead decided to represent tiles in their "original" form. I wrote an emulator for portions of the Game Boy Advance graphics hardware, allowing for tiles and background "maps"  to be represented exactly how they were on real hardware. To render a level onto the screen, I would upload it's tile graphics into virtual-VRAM, and then upload each tile map into the respective background layer. Scrolling the screen involved writing to scroll registers and uploading additional portions of the level into the background layers, just like the games do on real hardware. This had several benefits and drawbacks, which I will get into in a moment.

The level viewer was programmed in C, making use of SDL2 for rendering and input. The rendering solution I had used was less than optimal. The Mega Man Zero games made use of 16 color graphics, and SDL did not have support for such a low bit-depth. To get around this, I would convert these graphics from their 4-bit format into 24-bit RGB images on the fly. This was done every single frame by the CPU, and was not very efficient. Furthermore, SDL2 was not taking advantage of the GPU. Graphics were blitted onto the framebuffer via the CPU, rather than taking advantage of hardware accelerated systems such as OpenGL. Overall, this program ran at about 10 FPS on my Intel i5 CPU.

I have not touched this project in nearly two years. If I were to pick it up, there would be several things I would do differently.

First, I would switch the rendering system over to OpenGL and make use of a shader for rendering 16 color graphics. This would allow for the work to be offloaded to the GPU instead of relying on the intensive CPU process.

Second, I would split work across multiple threads; the original code only worked on a single thread. This would allow for multiple CPU cores to be utilized.

Finally, I would remove the GBA emulation layer and instead render the levels with a higher level representation of these tile maps. This would make the rendering process easier to expand, as it would not solely rely on the limitations of GBA hardware.


I will be writing a post about the level format in the future.

Deconstructing Mega Man X4's Sound Archive Format


Mega Man X4 was released by Capcom in 1997 for the Playstation 1 and Sega Saturn. Shortly after, it was ported over to the PC. There are several different files and folders which make up the game. An executable which makes up the game code, a main folder for storing graphics and levels, and several other folders for storing full motion video, sound effects, and background music. With the exception of the background music and full motion video, most assets are stored in archives. These archives pack all relevant assets in a single file, allowing for files to be quickly loaded into memory while reducing the time it would normally take to seek to each file.

The Format

The format used for sound effects consists of two components: a header and a body. 

The Header

The header begins with four bytes which define how many sound effects are in the archive. For each sound effect, there is a 17 byte entry in the header. The first four bytes of this entry tell where the sound file is located in the file. The next 13 bytes give the filename of the sound, with 8 bytes for the name, 4 bytes for the extension, and a single byte for the string terminator. To calculate the size of the sound file, you get the location of the next sound file and subtract it with the location of the current one. If you are decoding the last sound file, then you just read from the sound's location to the end of the archive.

The Body

The body of the archive consists of the sound data of each sound effect packed together side by side. Each sound is a regular wave file. No proprietary sound format was used for the PC version of the game. To extract a sound, you get it's address and size from the header, then read its contents.