Process of Arcade ROM Hacking

  • Published on

  • View

  • Download


Process of Arcade ROM HackingBy Stephen Wylie12.04.2016 (5844 2F70)The Tapper game has plenty of Budweiser branding.How can we change it?ToolsEveryone should have these handy!MAME emulatorGame ROMsEditors (Hexplorer, SciTE Hex)GIMP for new graphics creationPre-built tools for the games platformIf not, I hope you can write code!Hexplorer for Windows is nice for reasons you will see later. (Hint: If you dont get it, its that the Matrix-style color scheme lends well to pattern recognition.)MAME EmulatorDownload and unzip MAMEPut your ROM in the roms folder in its own directoryMAME/roms/tapper/*.binLaunch MAMEmame64.exe -window -verbose -debug -nomax tapperPress F5 to run in Debug modePress F4 for Tile Viewer- Press Enter for more information3. Why use the command line? If theres an invalid checksum with your ROM compared to what MAME thinks is right, this will let you get around that. When you load the ROM through the menu with plain Jane MAME, it will stop on its own ROM checksum mismatch, considering it a fatal error, and wont let you run your creation.-window makes MAME windowed rather than full-screen. Otherwise you could not navigate to other applications without exiting the game. However, the window is still usually very large.-verbose spews lots of other information on the command-line window such as CRC checksums of the ROMs, input & sound devices being loaded, status of initializing the ROMs, etc.-debug launches the debugger.-nomax makes the window the native size of the game, rather than the maximum size your monitor can fit.Around MAME and the ROMsThe Tile Viewer shows the available color palettes, tile artwork, and tile map.Examine the two background files; look for patterns. What matches the Tile Viewer? Discover the encoding and palette scheme.Practice making edits. See if the results are what you expected. Refine and tweak if it did not meet your expectations.Organization of ROM Filestapbg0Background tile palettetapbg1Background tile artworktapfg[0, 7]Foreground spritestappg[0, 3]Game logic, level tile arrangementstapsnda[7, 9], tapsda10SoundGetting Your BearingsDemoStudying & Testing Background ROMs12.04.2016 (5844 2F70)SDthgkkjkjIn this demo, we were looking at the tapbg0 and tapbg1 files in the hex editor. I showed those in conjunction with the tile map and color palette to describe how I deduced the encoding scheme.What we learnedtapbg0 (right) encodes the group of 4 colors (minor palette) for each pixeltapbg1 (left) encodes the color within the minor palette for each pixelThese are two-bit encodings per pixelEach tile is 64 pixelsEach tile offset is 0x10Each tile offset is simply the tile address shifted up 4 bits. Makes it easy to calculate! Just stick a 0 on it in hex and youve got it.Rearranging Tiles On the BackgroundWhere are the tiles?Carefully study tiles in Tile ViewerMatch these to locations on-screenDraw yourself a gridScroll through program ROM until you find one or more tile addressesHow did you know it was the program ROM? Process of elimination ;)Where are the tiles?Carefully study tiles in Tile ViewerMatch these to locations on-screenDraw yourself a gridScroll through program ROM until you find one or more tile addressesSometimes you have to eliminate the distractions, such as row wrappingAnd the Tile Viewer might not be on the correct major palette settingDepending on how wide your hex editor is, you might have one row of tile addresses on more than one line, so that the line is wrapped. In the picture at top right, every other row is actually a continuation of the first row of tiles, thus ignore it.The 50 parts, while not really part of the tile address, is still important. Well discuss that later.Now that the extraneous data has been blacked out, take a look at how the tiles line up between the hex code, the snippet of the game background, and the tile file.And this tile arrangement is easy, because at least the word COMMUNITY is written straight across, even if it is split into the top half and bottom half. The original arrangement of the Budweiser logo made next to no sense at all. Id imagine they were using some sort of Gray code to minimize the number of bits that had to be changed to load each sequential tile, but since MAME doesnt run on hardware from the early 80s, were not concerned with squeezing out every last drop of performance from our graphics engine.Zilog Z80 machine language features opcodes where any byte value from 0 to 255 seems equally likely. However, background tile regions exhibit a pattern. Can you spot where the tiles begin?Think about this in terms of probability or from an entropy perspective. The Zilog Z80 instruction set is comprised of a great many opcodes, making big chunks of code look random and uniform (as in a uniform distribution, where all byte values from 0 to 255 seem equally likely) to someone inspecting the machine code in a hex editor. However, the background tiles will seem to take on much less of a uniform distribution, exhibiting tendencies to repeat the same or very similar numbers many times over. You might also start to see some of the tile addresses called out from the tile viewer. In fact, the 96 just a little bit down from the middle of the slide, in the first column of the 5th grouping of four, is the byte before the beginning of the tile map.DemoSearching For & Editing Background Tiles12.04.2016 (5844 2F70)SDthgkkjkjIn this demo, we opened up tappg1 and navigated to address 0x2211 (relative to the file, not the program space) which is where the background tile order information begins. We changed that byte in the hex editor (any value between 00 and FF will do), then saved it, and watched the ROM blow up because later on in some other program code, the checksum was calculated to be invalid.Substantial ROM EditsFor the checksum to make,thou must giveth and takeROM checksum is calculated by a loop in tappg3Checksum covers game program ROMs, D6, and D7Two strategies to address this:Balance out your changesNOP the checksum routineJust alter it:Must calculate after each code changeChanging the programmed checksum value wont helpUse debugger to find the difference in expected vs. actualPick a byte at the end to subtract this offset fromWhat if the byte you picked gets used for something?Remove the checksum code:Simple to overwrite the conditional branch instruction with NOPs so the processor ignores itShouldnt do any harm on modern computers and emulatorsMaybe you would want it back before writing to real EPROMsConsidering the ChecksumChanging programmed checksum value wont help because if you changed something in ROM 1 to alter its checksum, then you have to change its checksum in ROM 3 where the checksum code lives. However, this in turn changes ROM 3s checksum, which ends up creating a chase your tail kind of situation.Beyond these two solutions, people in class offered additional alternatives:1b. Make a program to alter the checksum for you after you make breaking edits.3. Jim recalled that older versions of MAME for Windows seemed to let you edit the checksum value without having to rewrite the ROM or use the debugger. Then again, this recollection was about 15 or 16 years old.MAME DebuggerUse -debug at the command lineSet breakpoint to pause upon reaching a piece of code:bpset 0xBEEFSet watchpoint to see when one byte of memory is:Read: wpset 0xBEEF,1,rWritten: wpset 0xBEEF,1,wEither: wpset 0xBEEF,1,rw0xBEEF is our hypothetical 16-bit memory address. You can watch a whole range of memory addresses for reads/writes by increasing the middle value from 1 to a larger number.DemoChoking Your Checksum So You Can Really Edit Background Tiles12.04.2016 (5844 2F70)SDthgkkjkjIn this demo, we opened up tappg3 to look for the string ROM ERROR. Luckily it was there encoded in ASCII format. Its in the file at 0xDDF, which translates to 0xCDDF in the program space, thus we set a watchpoint at 0xCDDF because this piece of memory would be copied on-screen to be shown. The first time the watchpoint is hit, we discover its in the midst of a loop where its adding up all the values of the ROM to calculate the checksum. The second time this address is hit, its being used to throw up the message. Instead of letting it get to the second time, let the loops run their course but put a breakpoint at 0xCD86. This statement compares the value of a memory address storing the expected checksum to the accumulator, which will raise the (Z)ero flag if the two numbers are equal. If the Z flag is not raised, it proceeds to continue along running instructions 0xCD89 through 0xCD8F in order to store the ROMs index to a memory address so it can keep a list of which ROMs are bad. Because we dont have physical ROMs going bad, we can simply use the hex editor to replace all the instructions from 0xCD89 through 0xCD8F with 00s (NOPs) so that when it finds invalid checksums, it simply doesnt act on that information.Tile Codes At a GlanceRange: [0, 0x3FF]Little endian0x6F11 = Tile 16F, Palette 1Aliased; higher-order bits affect various settings as described at rightSpecificsBits 15:14 - No apparent changeBits 13:12 - Major palette4 total groups of 16 colorsBit 11 - Flip horizontalBit 10 - Flip verticalBits 9:0 - Tile addressBackground Tile CodesLittle endian means the least significant byte of the two-byte number comes first when you look at it in the hex editor.Consider using flips to save on tiles. Tapper doesnt seem to do this very much.However, despite bits 15:14 werent seen to do anything to the graphics, it should be noted that the vast majority of tile addresses seem to have bit 14 set. The earlier levels tend to use palette 1 throughout their screens, leading to the digit 5 before the tile address. For example, the complete address for tile 0x1F would be 0x501F, or in little endian, 1F 50. Later levels tend to use other palettes more extensively, so looking for these bits changing is a good visual cue for boundaries between screens. Nevertheless, it might be worth investigating the hardware schematics or more documentation to see if bits 15 & 14 are wired up to anything.Editing TilesSucksWithout ToolsTile Tweaking ToolsPlenty of tools at http://www.romhacking.netVast majority geared toward home consoles from VCS to PlayStationCant find one? Write it and submit it!Top left: YY-CHR is a really popular tile editing tool thats been around a long time and has a bunch of presets mostly for home console systems. Note here how its not handling the Tapper background ROMs very well; it seems to be showing them backwards and with a horizontal offset of 4 pixels. This makes it pretty darn difficult to use this tool for your editing purposes.Nevertheless, might have something for you; there are a bunch of decent utilities to check out anyway. You can filter by console/system, your platform of choice (Win/Mac/Linux), level of difficulty for using the tool, etc.The top right is a snippet of code from the Python program I whipped up to take 256-color bitmap files, convert them into the 2-bit encoding required for the background ROMs, and then write them right into the ROM at the desired spot. Someday this will make it up on too, but Id like to give it a GUI before getting serious with it.WalkthroughMy Python Program For Automating Tile Art (MPPFATA: nice ring to it, eh?)12.04.2016 (5844 2F70)SDthgkkjkjIn this walkthrough, I showed the code for my Python program in its entirety and explained how it works. It takes a tile file, a color file, and a bitmap file. The tile file describes the address in the background ROM where the corresponding 8x8 section of the bitmap file should go. A blank address indicates to the program not to write that part of the bitmap anywhere. The color file maps each color in the bitmap image to the particular minor palette and color offset that it corresponds to in order to make the desired graphic. I then took the virgin Tapper ROM set, unzipped it into the ROMs folder in MAME, and turned my Python program loose with another image to replace the big Budweiser logo in levels 1 & 2. It did this with ease, but because the tile map used for Budweiser is not the same tile map as my other logo requires, I then exited MAME and edited part of the tile map quickly by hand. Upon rerunning MAME, it straightened out the new logo so it made sense.Mastering Pixel Art(for the game)Content by Stacy WylieStarting With the LogoUse GIMP from is the ONE TOOL that we need to make our Pixel Art.Load the graphic to convertEnable transparency; make the background color transparentSave as a PNG for nowWhatever youre not going to use color-wise needs to be made transparent, especially if you want to put in a shape that is not rectangular. If you are using a rectangular graphic and want all the colors in your graphic in the game, then you do not need to worry about using transparency.Remove the ExcessFind the largest dimension of your image, then find out the maximum size the image can be along that dimension in the game.To convert Tapper to Community, we must constrain the width to 96 pixels, so we need to remove extraneous details.Steps:Use the Magic tool; clickand delete the borderUse the Eraser to clean up these lines by going over all removed materialImage > Autocrop Ink Well > Get the BlueRemove Beer with the Paint ToolIf your image is wide, then consider the widest spot it can go in the game and how many pixels it needs to be to fit in the desired spot. Then follow the steps as directed.Resize by ScaleImage > Resize> Interpolator cubic Select width of 96 pixelsThen, Image > Mode > Indexed For amount of colors, choose 4 (we will adjust the rest of this manually)For the Community logo shown here, four colors is the number we picked in order to maximize use of the yellows and browns for the wheat plus the rounded rectangle box color while minimizing extraneous colors that wouldnt belong to the palette we are targeting. Not everything will come out perfect, most likely, so be prepared to retouch the colors in the image manually.Color with Your Game Palette Remember you only have use of the 16 colors in one specific major palette, i.e. rows 0, 0x10, 0x20, or 0x30 as pictured above. Recall that previously we described how the major palette gets set by bits 13:12 of the tiles address in the game program ROM. In the Tapper game, palette 1 gets used almost exclusively.You dont necessarily have to make the image colors exactly the same as the palette colors if youre using a tool that will map the color in the image to the desired color in the palette. This is especially true with the tool I designed to import bitmaps right into the ROM.Export to Bitmap (bmp)Insert into the game using a toolThere are a variety of tools you can use. You could use a hex editor and manually overwrite the necessary tiles. The code snippet on the left comes from the tool I wrote that takes a 256-color bitmap and a couple different user-defined mappings. The first map links each color in the bitmap to the desired palette color in the game. The second map defines which 8x8 square of the image will be written to which tile address in the ROM. As of this writing, it has not been made available anywhere yet, but once it gets cleaned up with better documentation and doesnt require you to edit the source code to choose your input files, it will wind up on the error in the command line output comes from some lines of comments that it doesnt know how to parse, so its warning you its ignoring some input.ConclusionWith patience, intuition, the right set of tools, a good understanding of said tools, and a versatile understanding of programming languages from assembly to scripting languages, you too can make a ROM hack all by yourself.But if superior tools already exist and you dont have to worry about the checksum or can handle it without having to know assembly, then writing code isnt required.This might seem a little condescending, as it implies you cant get very far without knowing programming. Well, as a programmer, I can vouch that practicing that skill gives you intuition and the ability to make your own tools to make this process go much easier if you choose to go about doing it yourself. Otherwise, you will find yourself leaning upon major crutches, suffering through documentation you cant understand, finding tools that are either inflexible or have multiple ways to combine options you dont understand, and/or waiting on others to give you answers before you can move on. (All those things still happen to me anyway, but a little less so.) Hopefully this presentation has facilitated hacking and decoding at least one more platform (namely the Midway MCR-III) for non-programmers.ThanksNow go forth and make something cool


View more >