<< Blog Index

A Trip Through Memory Lane
January 29, 2025

I was cleaning up my GitHub account recently. I've just hit 100 repositories, and some cleanup was well overdue. For the past week or so I dug through my old Super Nintendo sources including my SNESKIT SDK.

Such a rabbit hole! I decided to rewrite some of the tools in Go while better documenting them.

snesbrr - A BRR codec

This tool has some history. DMV47, a hero of yore, had written a tool to convert between wav and brr. I also had an "improved" version of his code contained in my snesmod converter. However, both versions shared one thing in common: they were unreadable. Tons of little variable abbreviations scattered about with no obvious purpose.

A good senior software engineer wouldn't touch it. If it works it works. However, when I'm working on personal projects, I don't take the "good engineer" role. I take the naive, curious, and enthusiastic programmer role. Ugly code had to go! A couple days later I had a Go port of the code.

To test and make sure it worked, I compared output between the original snesbrr.exe and my new code. Painstakingly I was able to align the outputs. At first I tried to get AI to port the C++ code to Go, but it kept messing up on all of the inane casting rules C++ has (and there were a lot of casts going on).

Okay, so I had a direct port of the codec, but then I wanted to take it a step further - rewrite it. The original codec was still difficult to read. The Go port mimicked much of the original C++ and was equally ugly, peppered with vague variables. Also, I spotted a few curious bugs here and there. I think my C++ copy of the code in smconv fixed those bugs, but I have no recollection of what I really did for the original smconv.

My newer version was based off of the information provided by in Fullsnes. This treasure trove of information wasn't written until years after my original iteration. All glories to Martin Korth and his continued dedication to documenting retro consoles.

Testing was a little more difficult the second time around given I didn't have an exact reference to work with. Codecs are tricky to test, especially if they are lossy, but I managed to make some decent cases.

modlib - A tracker module loader

The overall goal here is to replace the components smconv used with reusable libraries. The second main component was loading IT files. I extracted the functionality here and ported it to Go under a new package modlib.

Over time I hope this package grows to support other formats. It has two subpackages for now, one is a "common" module definition which should support all formats it can load. The other is a direct interface to the Impulse Tracker file structure. One additional improvement I made was supporting the IT sample compression which was missing for the past forever in smconv.

smconv - The SNESMOD music converter

With the last two main components out of the way, this was more achievable, a Go port of my converter. For this final smconv package, the work left was conversion from the common module format into the special SNESMOD format. Thankfully, past me wrote doc/soundbank.txt which was extremely helpful in deciphering the old C++ code.

The only other headache was SPC generation and figuring out how to compile the SPC driver and monkey patch it for the SPC code. The old C++ was a great frame of reference, albeit a little cryptic. Funny how we can completely forget about the internals of systems that we've worked with long ago. Looking at the assembly code of the SPC driver today leaves me in awe.

Cross-platform

Makefiles! Makefiles everywhere. Back in my day I was a Windows user. I still am, but today I put more care into our non-Windows users (especially CI systems). Makefiles are fun to write either way, and I could use more practice with them. I've littered each project with make rules to build out of the box. I put a lot more emphasis on the compilation process these days, given how many struggles I've endured in the past over poorly constructed projects.

One of the reasons I wanted to port the tools to Go is just because of how easy it is to build everywhere. Compiling C++ on Windows and installing MS tools always feels a bit rough. Surely it's better today, but I've had a bad taste left in my mouth from C++ tools.

Some other smaller programs I've also converted to Python for the same reason. Python is my go-to when I want to write a quick tool that can run anywhere.

pmage - An image converter

Okay, so I still wanted to build my example programs out of the box. One last ugly thing was snesgrit. This was a (poorly) modified version of grit with support for the SNES. It worked great back in the day, but I don't like the idea of maintaining a fork of grit.

If I wanted to keep this path of maintaining snesgrit, I'd look for a way to cleanly merge the code into the main repo, to add SNES support with an option. However, after a look at the code, that seems easier said than done, e.g., I saw bit mappings that matched the GBA/NDS bits in headers as opposed to the SNES mappings.

So I decided to write a new tool. Why not? (I mean, I could give you a hundred reasons why not...) I could learn more about Go's image libraries. The goal for this tool would be a conversion process that is easy to understand. Each image file is given a YAML file that describes how to convert it.

The complexity shoots up when you want to support different systems while keeping the conversion rules general between them. My approach is to have a system "profile" that determines specific mappings or formats, and then that is mixed with the per-image metadata to determine the final output.

It's in a very rudimentary stage right now, but hopefully I'll have time to expand it later.

If you're curious about the name, it's "picture mage", i.e., "picture wizard". Primarily a reference to Final Fantasy which also conveniently sounds similar to "image".

Contributions welcome!

I'm not sure how much more I'll add to these over time. This was more of an effort to document the existing work than anything. I also see there is another great collection of tools with pvsneslib, which I would recommend checking out if you're getting into SNES development.

In the end, I'd hope my projects are contributor-friendly, hence my cleanup here. Contributions are always welcome. I think the SNES scene has always struggled a bit, given its difficulty to work with, but it's great to see that people are still having fun with the system. If you find anything difficult to understand in my codebases, feel free to open an issue and we can clarify it.

<< Blog Index