I don't know how helpful this'll be, but I figured it couldn't hurt to have a tutorial for turning your Artmoney findings into MAME cheats.
If there's any confusion with anything, let me know, and I'll update this post.
What you'll need:
- Artmoney (obviously). You'll also need to know how to apply an offset to your table anytime the emulator crashes for whatever reason.
- MAME-RR (if you're going to use the RAM search method). Otherwise, whatever version of MAME you prefer to use should suffice. I say should, because there might be some issues with getting cheats to work with certain versions of MAME.
- Notepad++ Unless your text editor can easily open large text files, you'll probably want to use this. It's also got some functions that'll make things easier for you (like how to record a macro and play it back. Makes doing huge lists of cheats easier).
- Vim. This is for if you make a dump of the game's memory, and it's too big for Notepad++ to open.
Spoiler: Some set up (click to see content)
So the first thing you're going to want to do (aside from possibly using the command prompt to generate an .ini file so you can enable the cheat options or debugger), is to see if you have a cheats folder in the MAME folder. If you don't, make one. After that, download
Pugsy's cheat collection and unzip the contents into the cheats folder (so you can see if the what you're looking for was already found or not). If you'd rather make your own cheat file, open up a text editor and add this:
Spoiler, click to toggle visibilty
<mamecheat version="1">
<cheat desc="This is a descriptor line. Replace this line with an actual cheat."/>
</mamecheat>
Save it as the name of the rom with the extension .XML and put it into the cheat folder. Make sure you didn't save it as .XML.TXT. You'll obviously have to fill it with some cheats, which brings us to...
Searching for addresses
Spoiler: Artmoney + RAM search (click to see content)
This method's more for someone who wants to ease themselves into finding cheats for MAME. This is what I started out using, because I didn't know how to use the debugger. MAME-RR has some limitations with it's RAM search, and not every game works with either of the two versions. Aside from that, you have a decent chance of finding what you're looking for with it. TBH, you could just use the RAM search, but it was easier for me to use this instead, because I'm more comfortable using Artmoney.
What you'll be doing is using Artmoney to make it so you can do exact value searches in the RAM search.
Here's how to do it:
- Pause the emulator and press Ctrl+F to bring up the RAM Search window. If you've checked the hexadecimal view/edit boxes in Artmoney, click on the Hexadecimal radio button in the Data Type/Display. If not, you're going to have to do this eventually, because the values to the cheats have to be in hexadecimal.
- Set the values in your Artmoney table to whatever you want.
- In the RAM Search Window, where it says Compare To/By, you're going to add the value into the empty field (adjacent to Specific Value:). After doing that, click Search.
- To narrow down the list, change the value in Artmoney and the RAM Search, and Search again. If it's within the address range, it'll show up for you. Copy the addresses, and make them into cheats.
Spoiler: Artmoney + Debugger (value searching) (click to see content)
This method has a couple drawbacks to it, but it's fairly easy to use. Unlike the RAM Search, you don't have the option to search for decimal values.
What you'll be doing is using Artmoney to make it easier to search for values in the debugger. Then, take what you found and create a cheat list file (unless you're looking for less than 5 addresses. In which case, it'll just tell you what the addresses you need to make into cheats are).
Some set up: Go into the .ini and turn on the debugger by searching for debug and changing the 0 to a 1 and save it. Now whenever you run a game, the debugger will pop up. Press F5 to run the game once the debug window pops up.
Searching with the debuggerHere's how to to it:
- Pause the emulator.
- Set your addresses in Artmoney to a specific value. For this, let's say you set it to either 41 (byte), 4148 (word), 41484148 (double word), or 4148414841484148 (quad word).
- In the debugger, add a variant of one of these commands and press enter:
ci ub,00000000,FFFFFFFF,0 <- if you searching for a integer 1 byte valueci uw,00000000,FFFFFFFF,0 <- if you searching for value that's integer 2 bytesci ud,00000000,FFFFFFFF,0 <- if you searching for value that's integer 4 bytesci uq,00000000,FFFFFFFF,0 <- if you searching for value that's integer 8 bytes00000000 and FFFFFFFF are the address range, and 0 is for the cpu I'm searching in. You can set it to 1, 2, 3, 4, and so on to search in other CPUs.
- Add one these commands and press enter:
cheatnext equal,41
cheatnext equal,4148
cheatnext equal,41484148
cheatnext equal,4148414841484148- In Artmoney, change the value to something else. Let's say you set it to, 12, 1212, 12121212, or 1212121212121212.
- In the debugger, add one these commands and press enter:
cheatnext equal,12
cheatnext equal,1212
cheatnext equal,12121212
cheatnext equal,1212121212121212- Unpause the emulator so that the debugger window can update and show you whether or not it found any addresses with values equal to the 2 values you searched for while the emulator was paused. If it didn't find anything, pause the emulator and try searching in another CPU. If you found something, add a variant of this command:
cheatlist NAMETHISWHATEVER.txtYou should now have a text file in your MAME folder containing all of the addresses you found, converted into MAME cheats and possibly not using one of the values you set it to.
But if the list of cheats is small enough and you'd rather not have to deal with the text file,, you could just use cheatlist (minus the NAMETHISWHATEVER.txt part), and it'll list the addresses in the debugger for you.
Alternatively, you could set the value in Artmoney and try seeing if these will yield anything (these will list everything in the current cpu that have the value you specify, so you should probably use the last 2):
find 0x000000,0xFFFFFF,"b.41" <- if you searching for a integer 1 byte value
find 0x000000,0xFFFFFF,"w.4148" <- if you searching for value that's integer 2 bytes
find 0x000000,0xFFFFFF,"d.41484148" <- if you searching for value that's integer 4 bytes
find 0x000000,0xFFFFFF,"q.4148414841484148" <- if you searching for value that's integer 8 bytes
find 0x000000,0xFFFFFF,"HAHAHAHA" <- If you're searching in the ascii column for specific text
If you weren't able to find anything using these 2 methods, then you may end up having to use the next method to try and find it. Moreso if it's a color mod.
Spoiler: Artmoney + Debugger (memory dump) (click to see content)
This one's a little trickier, but I've found color mods with this I couldn't find using the 2 methods above. This method involves using your Artmoney table to make it easier to find the the affected addresses in a memory dump. Be careful using this method, because you can end up with text file with a huge filesize.
Some set up: Go into the .ini and turn on the debugger by searching for debug and changing the 0 to a 1 and save it. Now whenever you run a game, the debugger will pop up. Press F5 to run the game once the debug window pops up. Yeah, I mentioned it twice.
The debugger and memory dumping:What I tend to do is change my cheats in Artmoney to integer 2 bytes, integer 4 bytes, or integer 8 bytes and freeze them to a value that's easier for me to find and/or see in the ASCII column (you'll have to do some experimenting to find a value that works for you. Try 4148. It'll show up as HA in the ASCII column to the debugger.
Once that's done, in the debug window, you'll notice there's a blank text box. You're going to add a command to it that'll make the emulator dump the memory into a text file (bascially taking a snapshot of all the values used at the time you dumped the memory). It'll look something like this:
dump Colors.txt,000000,FFFFFF,2,1,maincpuA breakdown of this command:dump - Self explanatory.
Colors.txt - The name I chose for this one. Make it whatever you want.
000000,FFFFFF - Starting and Ending addresses. Useful if you want a smaller .txt file, or if you know what you're looking for's in a certain address range. If you want to try and get specific address ranges to search in, you may want to check the Combing through address ranges section. Try to not to set the range too wide, or you'll end up with a huge text file (if the filsize is over 100 MB, you may not be able to open it).
2 - Values are displayed as 2 bytes. You can change this to 1, 2, 4, or 8. I use 2 or 4, sometimes 8 if the color value's 3 bytes.
1 - Displays the ASCII column. You can set this to 0 if you want to reduce the filesize.
maincpu - Which memory region you're dumping. To see what can be dumped, press Ctrl+M at the Debug window to bring up a new memory window, and click the drop down menu on the right. It'll be things like maincpu, sub, audiocpu, EEPROM, prot, or cart. You can also edit values in there by clicking on them and typing.
Once you add that, press enter, and you should now have a new .txt file in the MAME folder. Open that file with your text editor of choice (it may take a while if the filesize is too big), and search for whatever addresses have the value you specified.
Spoiler: Combing through address ranges (click to see content)
This needs some refining. It's more of a shotgun approach for finding color addresses, and you'll only sometimes find color mods within the addresss ranges this gives you.
In the prompt to MAME's debugger add this:
memdump changethistowhatever.txt
Press enter, and you should now have a text file that has a list of address ranges and information (This can give you a smaller address range to search around using the previous method). Search for pal (it could be pallete_ram or pal_ram). If it gives you an address range, create a cheat that looks something like this:
<cheat desc="Addresses">
<script state="run">
<action>maincpu.pq@130000=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130008=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130010=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130018=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130020=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130028=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130030=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130038=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130040=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130048=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130050=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130058=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130060=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130068=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130070=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130078=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130080=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130088=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130090=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130098=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300A0=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300A8=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300B0=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300B8=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300C0=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300C8=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300D0=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300D8=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300E0=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300E8=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300F0=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@1300F8=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130100=7C1F7C1F7C1F7C1F</action>
<action>maincpu.pq@130108=7C1F7C1F7C1F7C1F</action>
</script>
</cheat>
The actual cheat you'll use will have more addresses than this. For this particular one, I'd be going from 130000 to 1305FF (find/replace and recording/playing back macros will make this easier). Also, this particular cheat is set up to affect the most addresses/values in the fewest lines. This was just to give you an idea of what it should look as you go through the addresses in the address range.
If you know how this game handles colors, you can also search around that area in a memory dump for the value.
Spoiler: The Bizhawk Method? (click to see content)
As of this edit, Arcade emulation recently became possible on Bizhawk. What this means is you could eventually use the hex editor and RAM Search that comes with it to more easily find what you're looking for if it's not possible now (I don't like how it handles cheats, but making lua files is fairly easy and messing with the Hex Editor's more simpler).
The RAM search is fairly simple to use (you just have to keep in mind what memory region you have it set to) and the Hex Editor lets you easily mess with as many addresses in a memory region that you want (you can highlight multiple address by click-dragging with your mouse, and you can further increase what's selected by holding shift, moving the scrollbar down and then clicking on an adress you think it should stop at. Spacebar freezes/unfreezes adresses. Ctrl+G lets you go to a specific address, Ctrl+P pokes the addres with a custom value, using + or - on the numpad to increase/decrease the value by 1 also works).
Setting up your arcade game to run on Bizhawk:
- Click Tools/Multidisc Bundler
- Click on the top Browse button to specify where you want to save the .xml you're going to use to load the game. Give the file a name and click save.
- Click the box next to System and specify Arcade.
- Click on the 2nd Browse button to search for your Rom and click Open. If it's a parent rom and you don't need any other component files with it (BIOS, chd, qsound, etc), you can ignore the next steps and click Remove which should let you either Save or Save and Run.
- If you're not using a parent Rom, click on the 3rd Browse Window and add that. It's possible Bizhawk will still give you a missing file error with this, in which case try combing the contents of the parent Rom with the Rom you want to use (I had to add the content of sfa3.zip to sfa3us.zip to get it to work).
- If your game requires a BIOS file (like Neogeo, CPS1, CPS2, etc.), either click the 3rd Browse window (or click Add to add a 4th Browse window) and add that. You may get another window that pops up asking what file in the BIOS you want to load.
- If your game requires other component files (like qsound_hle, etc.), click Add to add another Browse window and add that.
- Click Save or Save and Run. If you did everything right, the game should load. If Bizhawk gives you an error, make a note of what the files are and search around (MAME requirements might be different for Bizhawk). If the emulator locks up, Bizhawk probably doesn't support that game yet.
- To load the game in the future, go to where you saved the .xml file and load that.
If you're curious, here's an example of what the inside of the .xml file looks like for my SFA3us:
<BizHawk-XMLGame System="Arcade" Name="sfa3us">
<LoadAssets>
<Asset FileName="..\..\mame\roms\sfa3us.zip" />
<Asset FileName="..\..\mame\roms\cpzn2.zip|coh-3002c.353" />
<Asset FileName="..\..\mame\roms\qsound_hle.zip" />
</LoadAssets>
</BizHawk-XMLGame>
I had to add the combine the parent rom with it and specify a file for the CPS2 BIOS.
One more thing. Currently, you have to map keys for all the inputs (player buttons, player coins/start, service mode, etc.)
A video showing me using the 4 methods. Sorta. For the 4th method, I just show an address range I'd go checking around (I made it before realizing I didn't have to use the map part of the command). I don't use a cheat that affects a large address range to see what I'm affecting or use the memory window to edit the values around it. There's also some jump cuts in the video, because redoing the video meant hard resetting MAME and having to find the offset to get the table working again. :p
Converting addresses to various types of MAME cheats
Spoiler: Here's a simple constant memory write I used, and a break down what you'd need to change for it: (click to see content)
<cheat desc="Infinite Time">
<script state="run">
<action>maincpu.pb@C05000=63</action>
</script>
</cheat>
C05000 - Address
63 - Value
p - Program write. You can also change this to:
m (region write), r (RAM write), o (opcode write), d (data space write), i (i/o space write), or 3 (SPACE3 write).
Starting out, you'll mostly use p, and try to use m or r if p doesn't work. You may find things that'll show up in data space or I/O space, which is what d and i are for. m is for region (Region 'maincpu', for example), and you should be careful with this, because if you mess up, a soft reset won't undo your changes.
b - byte (1 byte). You can also change this to:
w - word (2 bytes)
d - double word (4 bytes)
q - quad word (8 bytes)
I only use q and d either to try and condense cheats that affect a large range of addresses or for color values larger than 2 bytes. Be careful with q and d though, because they don't always work. Not sure if it's because of the address used, or memory type.
Infinite Time - What I filled in for the cheat description. Be careful what special characters you use for it.
run - You can change it to on if you want it to turn on by pressing enter.
maincpu - CPU that's being affected. Can also be changed to audiocpu, prot, sub, or whatever else the game uses.
Spoiler: This one lets you cycle through a custom range of values (I use it for X/Y position mods, so you can place the players wherever you want): (click to see content)
<cheat desc="P1 X Position">
<parameter min="0" max="65535" step="16"/>
<script state="run">
<action>maincpu.pw@FF8410=param</action>
</script>
</cheat>
With this cheat, you don't have "Off" or "On" for choices. You get to increase/decrease the value by 16 through a value range of 0 through 65535. The notable things that can be changed (besides what I mentioned to the previous cheat) are: "0", "65535", and "16".
<cheat desc="P1 X Position">
<parameter min="0x0000" max="0xFFFF" step="0x10"/>
<script state="run">
<action>maincpu.pw@FF8410=param</action>
</script>
</cheat>
And here's a variant of it using hexadecimal values. I didn't realize you actually could do that.
Spoiler: This one's for if you want to increase the value to multiple addresses in different ways (viewing tiles is one way, but I've mainly used it for sound modifiers): (click to see content)
<cheat desc="Replay Sounds"><comment>This should let you replay the last 7-14 sounds that were logged, but some sounds increase the values differently than others. Some sounds may also need to be replayed to hear multiple versions of them.</comment>
<parameter min="2" max="30" step="2"/>
<script state="change">
<action>maincpu.pb@000407=(param-2)</action>
<action>maincpu.pb@000408=(param)</action>
</script>
</cheat>
With this, they'll both increase by 2, but the value to 407 will be 2 less than 408. Comment makes a message pop up when you highlight the cheat in the list.
Spoiler: This one gives you a list of choices with descriptions for them: (click to see content)
<cheat desc="P1 Outit Mod">
<parameter>
<item value="0x3220">Connor 1</item>
<item value="0x3260">Connor 2</item>
<item value="0x32A0">Connor 3</item>
<item value="0x3320">Chief 1</item>
<item value="0x3360">Chief 2</item>
<item value="0x33A0">Chief 3</item>
<item value="0x3420">Javier 1</item>
<item value="0x3460">Javier 2</item>
<item value="0x34A0">Javier 3</item>
<item value="0x3520">Tanya 1</item>
<item value="0x3560">Tanya 2</item>
<item value="0x35A0">Tanya 3</item>
<item value="0x36E0">Mauby 1</item>
<item value="0x3720">Mauby 2</item>
<item value="0x3760">Mauby 3</item>
<item value="0x37A0">Mauby 4</item>
<item value="0x37E0">Nigel 1</item>
<item value="0x3820">Nigel 2</item>
<item value="0x3860">Nigel 3</item>
<item value="0x38A0">Nigel 4</item>
<item value="0x35E0">Toots 1</item>
<item value="0x3620">Toots 2</item>
<item value="0x3660">Toots 3</item>
<item value="0x36A0">Toots 4</item>
<item value="0x3920">Jay-Jay 1</item>
<item value="0x3960">Jay-Jay 2</item>
<item value="0x39A0">Jay-Jay 3</item>
<item value="0x39E0">Pebbles 1</item>
<item value="0x3A20">Pebbles 2</item>
<item value="0x3A60">Pebbles 3</item>
<item value="0x3AA0">Pebbles 4</item>
<item value="0x3AE0">Tiny 1</item>
<item value="0x3B60">Tiny 2</item>
<item value="0x3B20">Tiny 3</item>
<item value="0x3BA0">Tiny 4</item>
<item value="0x3CE0">Boris 1</item>
<item value="0x3D20">Boris 2</item>
<item value="0x3D60">Boris 3</item>
<item value="0x3DA0">Boris 4</item>
<item value="0x3DE0">Sue Lee 1</item>
<item value="0x3E20">Sue Lee 2</item>
<item value="0x3E60">Sue Lee 3</item>
<item value="0x3EA0">Sue Lee 4</item>
<item value="0x3EE0">Li 1</item>
<item value="0x3F20">Li 2</item>
<item value="0x3F60">Li 3</item>
<item value="0x3FA0">Li 4</item>
<item value="0x4020">Kwan 1</item>
<item value="0x4060">Kwan 2</item>
<item value="0x40A0">Kwan 3</item>
</parameter>
<script state="run">
<action>maincpu.rw@FF8E32=param</action>
</script>
</cheat>
This is like the cheat before it in that it's more then simply off/on. But instead of going through a value range, it goes through a list of custom values with custom descriptions for them. 0x must precede the values you'll add to it.
Spoiler: This one only triggers when a condition is met: (click to see content)
<cheat desc="P1 Press P1 Start to reset some of P1's animations">
<script state="run">
<action condition="(maincpu.pw@2051A3C=1000)">maincpu.pb@206A78F=(00)</action>
</script>
</cheat>
The value to address 206A78F will only be set to 00 if the value to address 2051A3C (controls what buttons you press) equals 1000 (P1 Start).
Spoiler: This one only triggers when 2 conditions are met to increase a value: (click to see content)
<cheat desc="DEBUG: Anim Code (experimental)">
<script state="run">
<action condition="(frame % 10 == 0) AND (maincpu.pw@602DABE==0100)">maincpu.pw@60FFFBE+=0001</action>
</script>
</cheat>
The 1st condition, (frame % 10 == 0) is something I used to try and keep the value from being increased every millisecond. Instead, it'll do it after 10 frames. The 2nd condition, (maincpu.pw@602DABE==0100) is for a specific button press. So the condition set is "If the value to address 602DABE is 0100 every 10 frames".
You'll notice something else different: The += before 60FFFBE instead of a =. This causes the value to increase by 1 when the cheat is activated instead of being set to 1. You'll also notice the == to both conditions. I could change those to =, and it'd still work. I left them like that to show you could also set the condiditons to greater than >=, and not equal to !=. I haven't gotten less than to work for some reason. Ok, figured it out.
= equal to
!= not equal to
< Less than
> -or- > Greater than
<= Less than or equal
>= -or- >= Greater than or equal
For more complicated cheats/further information on this, I suggest checking syndromtr's guide. The 2 conditionals cheat I made came from there.
Hope this helps.
Edit: I added some notes on Bizhawk and how to try to get games running on it because they started trying to get MAME working on it. TBH, I didn't know where to put this and I didn't want to make a new thread, but I felt it merited mentioning because it could make making cheats even easier in the future.