Just a quick post from me, presenting you some motionplus communication dumps:
Redsteel2_motionplus_and_nunchuk_raw_communication_dump.txt
http://www.mediafire.com/download.php?2zkmmweeteq
Wii_Sports_Resort_motionplus_raw_communication_dump.txt:
http://www.mediafire.com/download.php?djtzraqhojw
Sunday, June 13, 2010
Dynamic MotionPlus (WMP,WM+) Calibration - Part 2: Reversing calibration data at a40050h
I'm not completely done with it, but this is what I got so far. This was reverse engineered by me and megazig. Megazig even reverse engineered the checksum algo, but I won't publish it, since it is of no practical use to us. I will just add that the mechanism involves summing up bytes with constant table lookups and following xor'ing, which gets done a couple of times. Apart from that a big thanks to crediar for helping us out with the necessary input.
4x16 Bytes within the active motion plus register starting at 0xA40050. Data is interleaved,
starting with a 28 byte long structure for fast motion and following 28 bytes for slow motion.
8 Byte orientation blocks consist of 2 single-precision floats, former represent zero- and later scale-values.
The yellow block represents a 32bit signed integer, which is not fully understood yet.
This is how the game splits the data at 50h into a data structure, which is 28 bytes long. After the game has copied those values to the corresponding structure/datatype, a few floatpoint calculations which I haven't completely reversed yet, will be applied on those values. The data itself most likely just represents a simple orientation matrix. Note: I don't think yaw has to be set to an exact value at the beginning, since we only want to move relative to a fixpoint. So it's possible to just set it to a pseudo-random value, and move relative to it, as soon we have visual contact to the sensorbar to adjust the yaw. More later.
Tuesday, June 8, 2010
Dynamic MotionPlus (WMP,WM+) Calibration - Part 1: Shaking some hands.....
You might have wondered yourself how to toggle MotionPlus dynamic calibration. Well, here we go.
Part 1 will be about the handshake and part 2 will be dedicated to the 64bytes long data structure at register 0xA40050. If you would like to know anything else, just drop a comment.
As soon as a game has verified that a MP is active, which was done by reading from the active extension register at 0xA400F0-FF, hardcoded calibration data will be read from register 0xA40020-3f. Afterwards a controlflag at 0xA400F7 will be checked. This flag can contain values like 02,06,08,0A,0C,0E or 1A.
Every value represents a different initiation state of the MP extension. For instance if the flag is below a certain state, data reports will contain invalid or 0xFF'ed MP extension data or certain actions are not able to be done. The default(inactive) is 0x10. When the MP gets activated, the flag will be reseted to 0x02 (maybe even to zero but you wont be able to read this value since it would just change too fast to catch it) and will be gradually increased until it reaches 0x1A, which represents an activate state with accomplished dynamic recalibration(doesn't matter if the recalibration was successful or not).
When there is an extension connected to the MP, the game will read 3 more bytes by reading 4 bytes from 0xA400F6. Those 3 bytes will be always 0xx00 when there's an extension connected to the MP, else they are defaultwise 0xFF. There is no direct need to read them. At this point our controlflag usually will be already 0x0C/0x0E. For the next step however its important to be at least in state 0x08.
The next step toggles dynamic calibration. It is done by writing 0x00 to 0xA400F2. Data at 0x50-0x8f will now start to change until a second 0x00 write to 0xA400F2 is issued to stop the calibration. So it would be smart to keep track of extension data reports to make sure to trigger the routine not too early, since it might be still moving. The game will read out the initiation state flag again and verify that it's at least 0x0E. Then the calibration data will be read out twice to make sure the routine wasn't still running in between. After this is done the game will check if the data is reasonable, and write either 0x00 or 0x01 to register 0xA400F1. A write to this register will change the calibration data again, which seems to me is just some sort of correction or update. As soon as the game verified that the calibration was accomplished by simply checking the initiation state, which should read 0x1a now, it will read out the calibration data twice again from 0xA40050-8f. This data represents a rotation matrix
Stay tuned for part 2.
I hope this was of any help to ya chaps. If you like it, link it.
Best regards
Sanchez
Part 1 will be about the handshake and part 2 will be dedicated to the 64bytes long data structure at register 0xA40050. If you would like to know anything else, just drop a comment.
As soon as a game has verified that a MP is active, which was done by reading from the active extension register at 0xA400F0-FF, hardcoded calibration data will be read from register 0xA40020-3f. Afterwards a controlflag at 0xA400F7 will be checked. This flag can contain values like 02,06,08,0A,0C,0E or 1A.
Every value represents a different initiation state of the MP extension. For instance if the flag is below a certain state, data reports will contain invalid or 0xFF'ed MP extension data or certain actions are not able to be done. The default(inactive) is 0x10. When the MP gets activated, the flag will be reseted to 0x02 (maybe even to zero but you wont be able to read this value since it would just change too fast to catch it) and will be gradually increased until it reaches 0x1A, which represents an activate state with accomplished dynamic recalibration(doesn't matter if the recalibration was successful or not).
When there is an extension connected to the MP, the game will read 3 more bytes by reading 4 bytes from 0xA400F6. Those 3 bytes will be always 0xx00 when there's an extension connected to the MP, else they are defaultwise 0xFF. There is no direct need to read them. At this point our controlflag usually will be already 0x0C/0x0E. For the next step however its important to be at least in state 0x08.
The next step toggles dynamic calibration. It is done by writing 0x00 to 0xA400F2. Data at 0x50-0x8f will now start to change until a second 0x00 write to 0xA400F2 is issued to stop the calibration. So it would be smart to keep track of extension data reports to make sure to trigger the routine not too early, since it might be still moving. The game will read out the initiation state flag again and verify that it's at least 0x0E. Then the calibration data will be read out twice to make sure the routine wasn't still running in between. After this is done the game will check if the data is reasonable, and write either 0x00 or 0x01 to register 0xA400F1. A write to this register will change the calibration data again, which seems to me is just some sort of correction or update. As soon as the game verified that the calibration was accomplished by simply checking the initiation state, which should read 0x1a now, it will read out the calibration data twice again from 0xA40050-8f. This data represents a rotation matrix
Stay tuned for part 2.
I hope this was of any help to ya chaps. If you like it, link it.
Best regards
Sanchez
Subscribe to:
Posts (Atom)