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 how I draw graphics 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.