Here’s an image of Mario, drawn using the machine code for Super Mario Brothers. Created using C++, the EasyBMP library and the GIMP. Source code after the break.
This program reads in a ROM file, and creates an image out of it using the specified aspect ratio. Each byte is drawn as a column of 8 pixels, which are arranged into rows and then columns to fill the space. Once the image is generated, I created the color overlay in GIMP by resizing and placing a sprite from the game in a separate layer, with mode set to ‘Screen’.
#include <iostream> #include <fstream> #include <cmath> // for square root #include <sys/stat.h> // For file size #include "easybmp/EasyBMP.h" int main(int argc, char** argv) { // Rom info char fileName[] = "smb.nes"; // Desired aspect ratio float aspectRatio = 1.333; // Determine the file size int romByteSize = 0; struct stat results; if (stat(fileName, &results) == 0) { romByteSize = results.st_size; } else { std::cout << "Sorry, could not determine file length!" << std::endl; return 1; } // Determine the height and with to achieve the proper aspect ratio // we know: // h/w = aspectRatio/8 // h*w = romByteSize // So: // h = aspectRatio*w // h = romByteSize/w // w^2 = romByteSize / (aspectRatio/8) int imageWidth = (int)(sqrt(romByteSize / (aspectRatio/8))+.5); int imageHeight = (aspectRatio)*imageWidth - (int((aspectRatio)*imageWidth)%8) + 8; std::cout << "romByteSize=" << romByteSize << " imageWidth=" << imageWidth << " imageHeight=" << imageHeight << std::endl; // Open the binary std::ifstream myFile (fileName, std::ios::in | std::ios::binary); if (!myFile) { std::cout << "Sorry, couldn't open file for reading!" << std::endl; return 1; } // Create a bitmap to hold the image BMP Output; Output.SetSize( imageWidth, imageHeight ); Output.SetBitDepth( 1 ); // Copy the image data over, byte by byte RGBApixel blackPixel = {0,0,0,0}; for (int pos = 0; pos < romByteSize; pos++) { char byte; if (!myFile.read (&byte, 1)) { std::cout << "read error, bailing. pos=" << pos << std::endl; return 1; } int Col = pos%imageWidth; int baseRow = (pos/imageWidth)*8; for (int i = 0; i < 8; i++) { if ((byte >> (7-i)) & 1) { Output.SetPixel( Col, baseRow + i, blackPixel ); } } } // Then write it to a file Output.WriteToFile( "rom_image.bmp" ); return 0; } |