Stage2 is approaching: Redsteel2/WiiSportsResort is now working with Motionplus&Nunchuk, and the controls for the nunchuk are working now as well.

Apparently, motionplus games are very strict on calibration data checksums, they don't like invalid/0x00'd checksums(this is trackable via 0x01 writes to the active extension register at 0xA400F3). I'll keep all motion plus related stuff that I've discovered on my blog: http://snzgoo.blogspot.com
Next time I'll fix the disconnects, which are most likely caused by the sent motionplus empty/dummy data.
So stage2 might come sooner than u guys thought. Let me hear u scream;)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5522 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
snzgoo 2010-05-28 02:45:10 +00:00
parent 5663872c7c
commit 58d64625f9
3 changed files with 23 additions and 8 deletions

View file

@ -118,6 +118,7 @@ static const u8 EepromData_16D0[] = {
0x33, 0xCC, 0x44, 0xBB, 0x00, 0x00, 0x66, 0x99,
0x77, 0x88, 0x00, 0x00, 0x2B, 0x01, 0xE8, 0x13
};
//I'll clean this up, we don't need the whole register
static const u8 motionplus_register[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@ -145,9 +146,22 @@ static const u8 nunchuck_calibration[] =
0x80,0x80,0x80,0x00, // accelerometer x, y, z neutral
0xb3,0xb3,0xb3,0x00, // x, y, z g-force values
0xff, 0x00, 0x80, 0xff, // 0x80 = analog stick x and y axis center
0x00, 0x80, 0xee, 0x43 // checksum on the last two bytes
0xff, 0x00, 0x80, 0xff, // 0xff max, 0x00 min, 0x80 = analog stick x and y axis center
0x00, 0x80, 0xee, 0x43 // checksum on the last two bytes
// In fact, this checksum is invalid. Games that validate this checksum will write 0x01
// to register 0xA400F3 when invalid) snzgoo
// However, as long the game doesn't care about the checksum(98% doesn't, RedSteel2/Wii SportsResort does tho., probably most MotionPlus games), it won't matter.
};
//This is real calibration data with a proper valid checksum.
static const u8 nunchuck_calibration_valid[] =
{
0x7d, 0x80, 0x80, 0x1a,
0xb1, 0xb2, 0xb4, 0x08,
0xe5, 0x1c, 0x80, 0xde,
0x21, 0x7c, 0x07, 0x5c
};
static const u8 wireless_nunchuck_calibration[] =
{
128, 128, 128, 0x00,
@ -179,7 +193,6 @@ static const u8 motionplus_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x04, 0x05 };
static const u8 motionplusnunchuk_id[] = { 0x00, 0x00, 0xa6, 0x20, 0x05, 0x05 };
//initial control packet for datatransfers over 0x37 reports
static const u8 motionpluscheck_id[] = { 0xa3, 0x62, 0x45, 0xaa, 0x04, 0x02};
static const u8 motionpluscheck_id2[] = { 0x39, 0xcd, 0x3f, 0x9a, 0x4b, 0x02};
// The id for nothing inserted
static const u8 nothing_id[] = { 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e };
// The id for a partially inserted extension

View file

@ -519,12 +519,13 @@ void UpdateExtRegisterBlocks(int Slot)
memset(g_RegMotionPlus[Slot],0,sizeof(g_RegExt[0]));
memcpy(g_RegMotionPlus[Slot], motionplus_register, sizeof(motionplus_register));
memcpy(g_RegMotionPlus[Slot] + 0x20, motion_plus_calibration, sizeof(motion_plus_calibration)); //reg 32bytes 0x20-3f;
memcpy(g_RegMotionPlus[Slot] + 0x40, nunchuck_calibration, sizeof(nunchuck_calibration));
memcpy(g_RegMotionPlus[Slot] + 0x40, nunchuck_calibration_valid, sizeof(nunchuck_calibration_valid));
memcpy(g_RegMotionPlus[Slot] + 0xfa, motionplusnunchuk_id, sizeof(motionplusnunchuk_id));
memcpy(g_RegExt[Slot] + 0x20, nunchuck_calibration, sizeof(nunchuck_calibration));
memcpy(g_RegExt[Slot] + 0x30, nunchuck_calibration, sizeof(nunchuck_calibration));
memcpy(g_RegExt[Slot] + 0x20, nunchuck_calibration_valid, sizeof(nunchuck_calibration_valid));
memcpy(g_RegExt[Slot] + 0x30, nunchuck_calibration_valid, sizeof(nunchuck_calibration_valid));
memcpy(g_RegExt[Slot] + 0xfa, nunchuck_id, sizeof(nunchuck_id));
g_MotionPlus[Slot] = 0;
}
g_MotionPlusReadError[Slot] = 0;

View file

@ -1249,13 +1249,14 @@ void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
pass-through mode supported for MotionPlus+Nunchuk */
void FillReportMotionPlus(wm_extension& ext, bool extension){
//sending initial control packet, this must be sent first, its some kind of verifiation, all control bits are set to 0!
//sending initial control packet, this must be sent first, its some kind of verification, all control bits are set to 0!(mp-mode only)
if ((g_MotionPlusReadError[g_ID]) && (g_RegExt[g_ID][0xFE] == 0x05) && (!extension)) {
// wont be not needed anymore, ill remove this if so next time
memcpy(&ext, motionpluscheck_id, sizeof(motionpluscheck_id));
//g_MotionPlus[g_ID] = (extension) ? 1 : 0;
g_MotionPlusReadError[g_ID] = 0;
} //nunchuk inserted
else if (extension == 1) {