Post subject: Viewing memory contents?
Player (87)
Joined: 2/10/2006
Posts: 113
Location: US
I was wondering if there's an easy way to monitor the contents of particular locations in memory. For example, say I want to be able to see 009B and 0600 every frame while I'm recording a movie.
Use the force
Post subject: Re: Viewing memory contents?
Emulator Coder, Skilled player (1310)
Joined: 12/21/2004
Posts: 2687
Luke wrote:
I was wondering if there's an easy way to monitor the contents of particular locations in memory. For example, say I want to be able to see 009B and 0600 every frame while I'm recording a movie.
As FCEU is currently, no, not if the locations you're interested in don't all fit on one page of the memory viewer (unless you don't mind scrolling back and forth). Maybe isolating the addresses in the cheat finder would work better (then alt, n, c to bring up cheat finder and click to dismiss it each frame) but that's still not terribly convenient.
Hoe
Joined: 7/31/2004
Posts: 183
Location: USA
I wrote a program for exactly this reason a while ago. No one found it useful, though :( http://www.red-stars.net My page apears to be down (it happens in prime time some days), but if you need me to compile you a version with your specific needs, let me know the names of the values, the game, and the offsets. Edit-- You can view a screen shot of it here: http://www.red-stars.net/EmuRead/emuread-b2-fin.png
Former player
Joined: 10/27/2004
Posts: 518
something like this would be useful for FF3j and determining how potions are aquired by winning battles, but i couldnt begin to tell you the addresses since i have no idea what im looking at in a memory viewer.
Player (87)
Joined: 2/10/2006
Posts: 113
Location: US
Yeah if you could generalize this tool, so that we could input our own values to look at, this could be an amazingly useful program. Right now I don't know enough memory locations to make it worth recompiling. Even Bisqwit has been modifying FCEU to show values for his megaman runs, so I think there is a demand for this sort of tool (or just better support in FCEU ) Imagine for racing games (e.g. RC Pro-Am), monitoring your velocity would make recording sooo much easier. Right now I was considering redoing a Deadly Towers run, and I was looking at some of the memory contents to see if I could get any hints how the game works. And plus, it's just fun hacking ) There is a ton of luck manipulation in this game, and I still don't fully understand how it's affected, so I was just hoping if I could find out where the random numbers come from, I could control luck manipulation without using dozens of rerecords for every enemy. Anyway, if you're curious, a few addresses I found are 00BC is your x position. (2 bytes) 00BE is your y position. (2 bytes) 009A is life (this is pretty useless since it's on screen) 009B is gold aka ludder 0520-053F is a bad guy's life, 1 byte each. Must go below 0 to die. 070B is knife x position on screen 0708 is knife y position on screen (F0 = no knife) It was cool seeing the HP of some enemies, and how much damage your sword does. Monitoring enemy HP is useful vs. bosses to be sure I'm hitting them, and not just wasting knives on hitting their fireballs. At 0569 and 056A some weird stuff was happening. They changed erratically, the former only when you're walking diagonally, and the latter only when a knife was flying. Hmm.
Use the force
Hoe
Joined: 7/31/2004
Posts: 183
Location: USA
Luke wrote:
Yeah if you could generalize this tool, so that we could input our own values to look at, this could be an amazingly useful program. Right now I don't know enough memory locations to make it worth recompiling. Even Bisqwit has been modifying FCEU to show values for his megaman runs, so I think there is a demand for this sort of tool (or just better support in FCEU :) Imagine for racing games (e.g. RC Pro-Am), monitoring your velocity would make recording sooo much easier.
One of my design goals was to make it extremely simple to modify the code base. I've thought about making it so it took data in from a datafile, but I turned that idea down. That prevents flexability and takes development time that I'd rather use to even further simplify usage of the code base. There was several things I wanted to do in addition, but the guy who was recompiling the emulators for me ran off. I wanted to allow hooks to specific PC addresses, as well as allow for control input (adding the ability to make bots). I will recompile it with the new offsets for you and post here or edit this.
Player (87)
Joined: 2/10/2006
Posts: 113
Location: US
That'd be great if you could do that. Here's a summary of interesting addresses I've found so far:
    0057 current movement direction 1-8 (0= not moving) 00A2 frames you have been taking damage (0=not taking damage, 1-1F is taking damage) (this is actually useful since the taking damage animation isn't visible until 1 frame after you've been hit) 00A3 direction while taking damage 1-8 00BC is X position. (2 bytes) 00BE is Y position. (2 bytes) 009A is life 009B is ludder (ie gold) 0321-... enemy x
      hp from 0x520 matches with 0x321 (so you can figure out the offset) (note: I am not sure where the high byte is for the enemies' x position.)
    0361-... enemy y
      hp from 0x520 matches with 0x361 (so you can figure out the offset)
    04A0 is knife on screen 04A4 frames knife has been on screen 04A6 current direction you're facing 0520-053F is a bad guy's hp, 1 byte each 0541-... what's been dropped by a dead enemy
      0=nothing, 1=1ludder, 3=heart, 5=5ludder 0x520 matches 0x541 (so a 0x21 offset from hp)
    070B is knife x position on screen 0708 is knife y position on screen (F0 = no knife)
Edit: I think I figured out what's going on at 0569. It keeps track of the fractional pixels you've moved when going diagonally. Or, simply, it keeps track of whether you'll advance a pixel the next frame you move diagonally. Sadly it looks like randomness is the combination of many variables, and it might even be different among enemy types. I suppose knowing these addresses are enough to write a bot, though :) Anyway, knowing your x and y, gold, and enemies' hp would all be useful. Movement is a little quirky sometimes, so being able to watch your x and y could shave a few frames here and there (and who knows, maybe there are wobbling tricks a la LoZ:LttP that are waiting to be discovered...) Gold is useful because I always have to hit Select to see how much I picked up, and enemy hp is useful so I don't have to guess how many more knives I have to use.
    Use the force
    Hoe
    Joined: 7/31/2004
    Posts: 183
    Location: USA
    http://www.red-stars.net/EmuRead/EmuRead-030806-deadlytowers.rar For additional information about the program, as well as the required FCEU version, visit http://www.red-stars.net/content/EmuRead/ I know nitsuja considered implimented shared memory into the main release of FCEU rerecording, but it does not apear this happend. My implimintation of reading the bad guys stuff in Deadly Towers is pretty messy, but it gives the info.
    Hoe
    Joined: 7/31/2004
    Posts: 183
    Location: USA
    Luke, I've got a few additional offsets for you. $01B7 stores the sword level in it's top 2 bits. $0098 stores the damage your sword will do. The damage your sword does based upon level is loaded from the following table: $D257:06 09 $D259:10 18 Level 2 to level 3 seems like a rip :) I did a complete trace of the cpu between the time the bad guy dies and when the item is dropped (to memory). http://www.red-stars.net/others/deadly_towers-hittodrop-tracelog.zip [720kb, 9mb unzipped] I havn't had a huge chance to look it over just yet.
    Joined: 4/6/2004
    Posts: 74
    Location: California
    It might be a little late for this, but FCEUXD (a version with some nice debugging additions) has a window that lets you edit/view the contents of NES memory in real time (not a list of disconnected addresses, though, which would also be nice). That might make a great addition to the customized versions of the emulator used here. The source code is out there (at Zophar's, for instance) if anyone thinks it's a good idea and wants to give it a shot.
    Active player (286)
    Joined: 3/4/2006
    Posts: 341
    I've studied that trace (and learned 6502 in the process). The RNG is stored at $0008, and depends on the amount of work the CPU does in each frame. More precisely, each frame is handled by an interrupt sequence, and $0008 is changed between interrupts as follows: $FD56:E6 08 INC $0008 $FD58:E6 08 INC $0008 $FD5A:E6 17 INC $0017 $FD5C:E6 08 INC $0008 $FD5E:4C 56 FD JMP $FD56 and so forth until the next interrupt. When a drop occurs, the game adds the RNG value to the enemy number (00-14), drops all but the bottom 4 bits, and chooses an item from the following list: 01 00 05 00 05 00 00 03 03 00 01 00 00 01 00 01. (0 gives 01, 1 gives 00, 2 gives 05, etc.)
    Player (87)
    Joined: 2/10/2006
    Posts: 113
    Location: US
    Thanks a bunch for all the work guys. That's a really tricky way to handle random numbers--seems like it'd also be very dependent on emulator timing. The good news is, it seems to be very manipulatable, so it shouldn't require too many frames to affect it. So that knowledge should save some work for future attempts. And yes, I would also love to see more sophisticated debugging tools (and maybe in the future, bot support) put into Nitsuja's version. I downloaded the source, but it's so large and uncommented that I had a hard time figuring it out.
    Use the force
    Hoe
    Joined: 7/31/2004
    Posts: 183
    Location: USA
    Luke wrote:
    I would also love to see more sophisticated debugging tools (and maybe in the future, bot support) put into Nitsuja's version. I downloaded the source, but it's so large and uncommented that I had a hard time figuring it out.
    I agree. I believe an external client would be the best way, because of the flexability this would give. The problem is that, to my knowledge, interthread/process communications are not very portable. I have been having large amounts of trouble with the FCEU code base my self, not fully stemming from my lack of understanding for the C libraries. It follows little/no coding convention, and is in general a rather large mess. VirtuaNES, from the small amounts of time I've messed with it, has nice and clean OO code.
    Nitrodon wrote:
    and so forth until the next interrupt. When a drop occurs, the game adds the RNG value to the enemy number (00-14), drops all but the bottom 4 bits, and chooses an item from the following list: 01 00 05 00 05 00 00 03 03 00 01 00 00 01 00 01. (0 gives 01, 1 gives 00, 2 gives 05, etc.)
    Aw crud. That's the most messed up PRNG I've seen :) I can't brute force 'frames until X drops Y' with one like that. Thank you for your work.
    Player (87)
    Joined: 2/10/2006
    Posts: 113
    Location: US
    Whew... I had a day off today, so I tried to get FCEU to compile. I was a tad annoyed to get MinGW etc. when I have Visual C++, but eventually I was able to get it working. I've been looking at the source, and it's really messy in a lot of places. The 6502 emulation core is disgusting... belongs in an obfuscated C contest, IMHO. But at least there are some simple functions for many things, so I think adding features like memory watch would not be so hard. So anyway, I'm excited, and I'll try some coding in my free time )
    Use the force
    Hoe
    Joined: 7/31/2004
    Posts: 183
    Location: USA
    Luke wrote:
    Whew... I had a day off today, so I tried to get FCEU to compile. I was a tad annoyed to get MinGW etc. when I have Visual C++, but eventually I was able to get it working. I've been looking at the source, and it's really messy in a lot of places. The 6502 emulation core is disgusting... belongs in an obfuscated C contest, IMHO. But at least there are some simple functions for many things, so I think adding features like memory watch would not be so hard. So anyway, I'm excited, and I'll try some coding in my free time :)
    binary: http://ikebo.hypermart.net/fceu-0.98.12-blip-shm.zip source: http://ikebo.hypermart.net/emu-shm/files/fceu-0.98.12-blip-shm.src.zip (Source modified and compiled by Ike) You can mess around with that source. That's the binary/source that my program requires. It uses shared memory for the interprocess stuff. If you could get gamepad button presses being sent I'd love you :P I'm working on bettering the Deadly Towers support- still need to take care of a bit more reverse engineering. Even if you don't know C#, the software should be extreamly simple to modify and you can use the free Visual C# Express Edition to compile. http://red-stars.net/EmuRead/emuread_deadlytowers.gif Is produced by the following code, http://pastebin.com/615083
    Player (87)
    Joined: 2/10/2006
    Posts: 113
    Location: US
    Cool, I'll look at the shared memory FCEU code, too. However I can't make any promises, since I've never done any inter-process stuff before.
    Use the force
    Player (87)
    Joined: 2/10/2006
    Posts: 113
    Location: US
    I put in the shared memory into 98.15nitsuja (although the version number is wrong in the program; I'll look how to fix that later). Let me know if you find any bugs. It wasn't much more than a bunch of cut and pasting. (I also used better programming practice, and #ifdef'd all the memory sharing code, so shared memory can be disabled when compiling.) http://lukeg.50webs.com/fceu-sm.exe.hah delete the "hah" at the end (50webs wouldn't let me upload an .exe lol) Ok now I have a question for you (or anyone who knows about this): Can you write to the shared memory? I'd assume yes, unless that privelege is reserved for FCEU? If you can write to the shared memory, that would be an easy way to send messages to FCEU, and then custom-made bots would be nice to make :) The code for allocating the memory is:
    mapRAM = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 0x800,"fceu.RAM");
    RAM = (uint8 *)MapViewOfFile(mapRAM, FILE_MAP_WRITE, 0, 0, 0);
    Use the force
    Hoe
    Joined: 7/31/2004
    Posts: 183
    Location: USA
    Luke; Yes, your copy of FCEU with shared memory works perfictly :) Thank you. Shared memory is writable, but I can't seem to get it to write properly from an external client. Going by this example, he seems to use FILE_MAP_ALL_ACCESS. I'm not sure if that's the solution to my problem or not. I'll experiement with it all later and see if that fixes it. Nitrodon; Mind looking at the code I linked to above? My random drop item calculations seem to be off.
    Active player (286)
    Joined: 3/4/2006
    Posts: 341
    Hoe wrote:
    Nitrodon; Mind looking at the code I linked to above? My random drop item calculations seem to be off.
    I can't see any code in that link, but there are two possibilities I can think of: 1) The enemy number starts at 0. 2) $4000+X. This number starts at 0x00 and increases by 1 each frame after the enemy is dead. The drop occurs at 0x10 (and disappears at 0xF0). 3) (edit) Something which has been bugging me about the trace: it starts by hitting and killing enemy 3 (and checking additional enemies up to 0x12), and ends with a drop from enemy 5 (and checking additional enemies up to 0x14). The item drop routine treats the enemy number as 5 in this case.
    Emulator Coder, Site Developer, Former player
    Joined: 11/6/2004
    Posts: 833
    What provisions, if any, are in place to prevent two copies of FCEU (running at the same) from destroying each other as they run? (Siamese twins joined at the RAM)
    Hoe
    Joined: 7/31/2004
    Posts: 183
    Location: USA
    DeHackEd wrote:
    What provisions, if any, are in place to prevent two copies of FCEU (running at the same) from destroying each other as they run? (Siamese twins joined at the RAM)
    None :) They'll both go wacky. Luke; I can't seem to get writing to anouther processes shared memory working. One possible solution for a message system would be each end of the line makes it's own outbox, and it's the responsibility of the other program to pole for it. For example, client's shared memory: press up client loop's until fceu's message memory responds with an ack of sorts. client clears shared memory client loops until fceu responds with a clear ack to achnoledge that message is over.
    Player (87)
    Joined: 2/10/2006
    Posts: 113
    Location: US
    EDIT: Hoe, I think I found your problem. I see in your code "file = NTKernel.OpenFileMapping(4, false, ramMapPrefix + ramMap);" The "4" means FILE_MAP_READ, i.e. read-only. Try replacing it with a 983071=FILE_MAP_ALL_ACCESS. And in "MapViewOfFile(file, 4, 0, 0, 0); " try replacing the "4" with a 2=FILE_MAP_WRITE. Hi--sorry I'm a little slow at answering FCEU questions, but I've been busy in real life. The next FCEU I post will not use shared memory if another FCEU is open (it's just a matter of replacing MapViewOFFile with malloc, I've just been lazy). But yeah, right now having 2 open will just behave weirdly. I'm pretty sure the shared memory works right now. True, a duplex situation like you described is better, but as it is, it should work. Here is an executable that will open the memory and write a few values: http://lukeg.50webs.com/bottest.exe.foo It will tell you what errors it gets opening the memory. Be sure that you check the Tools--UseExternal Input option. Right now FCEU won't look for bot input unless you tell it to.
    ...
    	HANDLE mapBotInput;
    	unsigned int * BotInput;
    
    	mapBotInput = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, "fceu.BotInput");
    
    	if(!mapBotInput)
    	{
    ...Error report
    	}
    	
    	
    	BotInput = (unsigned int *) MapViewOfFile(mapBotInput, FILE_MAP_WRITE, 0, 0, 0);
    	
    	if(!BotInput)
    	{
    	...Error report
    	}
    
    	BotInput[1] = 65536;
    	BotInput[2] = 1;
    	BotInput[3] = 2;
    	BotInput[4] = 4;
    	BotInput[5] = 8;
    	BotInput[6] = 16;
    	BotInput[0] = 6;
    
    	UnmapViewOfFile(mapBotInput);
    	CloseHandle(mapBotInput);
    	BotInput = NULL;
    
    Use the force