marți, 10 august 2010

Wii Remote Speaker Communication Cracked

Carl Kenner is the man when it comes to the Wii Mote. Not only was the he the first person to have a working application for Windows that could read the Wii-Mote, but he did all of the programing with no wii-mote to test with.

Ever since that day he has been the driving force behind many wii-mote hacks featured on this site. His software, GlovePIE is the heart and soul of making the Wii Remote work in Windows, and several sites have started to spring up to host scripts for using the Wii-Mote with various different types of applications. He was one of the first to add Nunchuck support to his app, and his GlovePIE software can also handle multiple Wii-motes.

One of the last pieces of the Wii-Mote to be discovered is it's speaker. Up until now, nobody has been able to successfully communicate with the speaker to produce sounds. Carl made a post today to the WiiLi forums including a script that will bring the Wii Mote's speaker to life. Much of the initial work to find the codes to send to the wii-mote was done by Marcan, so a good chunk of the credit for this discovery should go to him.

Here is the GlovePIE script you will need to test out the Wii-Mote's Speaker from Windows:

// Carl Kenner's Wiimote Speaker Test script! Version 2
// A = start sound, B = stop sound
// Minus = decrease sample frequency
// Plus = increase sample frequency
// It takes a short time to start (due to delays built into Poke)

// Change the next line to set the rate at which sound data is sent
// BUT it must be low enough for the wiimote to respond to the B button
// it may depend on your PC speed. Must be at least 91 for freq 13.
pie.FrameRate = 120 Hz

if not var.initialized then
var.freq = 13 // Set sample rate = 3640 Hz (so computer can keep up)
var.volume = 0x40 // volume = 40 ??? Seems to be about max
debug = var.freq
var.initialized = true
end if

if var.On and (not Wiimote.One) and (not Wiimote.Two) then
// Report 18, send 20 bytes, square wave, 1/4 sample rate freq
WiimoteSend(1, 0x18, 20 shl 3, 0xCC,0x33,0xCC,0x33,0xCC,0x33,0xCC,0x33,0xCC,0x33, 0xCC,0x33,0xCC,0x33,0xCC,0x33,0xCC,0x33,0xCC,0x33)
else if var.On and Wiimote.One then
// Report 18, send 20 bytes, square wave, 1/2 sample rate freq
WiimoteSend(1, 0x18, 20 shl 3, 0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3, 0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3)
else if var.On and Wiimote.Two then
// Report 18, send 20 bytes, square wave, 1/8 sample rate freq
WiimoteSend(1, 0x18, 20 shl 3, 0xCC,0xCC,0x33,0x33,0xCC,0xCC,0x33,0x33,0xCC,0xCC, 0x33,0x33,0xCC,0xCC,0x33,0x33,0xCC,0xCC,0x33,0x33)
end if


if pressed(Wiimote.A) then
// Enable Speaker
Wiimote.Report14 = 0x04 | Int(Wiimote.Rumble)
// Mute Speaker
Wiimote.Report19 = 0x04 | Int(Wiimote.Rumble)
// Write 0x01 to register 0xa20009
WiimotePoke(1, 0x04a20009, 0x01)
// Write 0x08 to register 0xa20001
WiimotePoke(1, 0x04a20001, 0x08)
// Write 7-byte configuration to registers 0xa20001-0xa20008
WiimotePoke(1, 0x04a20001, 0x00)
WiimotePoke(1, 0x04a20002, 0x00)
WiimotePoke(1, 0x04a20003, 0x00)
WiimotePoke(1, 0x04a20004, var.freq)
WiimotePoke(1, 0x04a20005, var.volume) // 40
WiimotePoke(1, 0x04a20006, 0x00)
WiimotePoke(1, 0x04a20007, 0x00)
// Write 0x01 to register 0xa20008
WiimotePoke(1, 0x04a20008, 0x01)
// Unmute speaker
Wiimote.Report19 = 0x00 | Int(Wiimote.Rumble)
var.On = true
end if

if pressed(Wiimote.B) then
var.On = false
Wiimote.Report19 = 0x04 | Int(Wiimote.Rumble) // Mute Speaker
Wiimote.Report14 = 0x00 | Int(Wiimote.Rumble) // Disable speaker
end if

if pressed(Wiimote.Plus) then
var.freq--
debug = var.freq
// Mute Speaker
Wiimote.Report19 = 0x04 | Int(Wiimote.Rumble)
// Write 0x01 to register 0xa20009
WiimotePoke(1, 0x04a20009, 0x01)
// Write 0x08 to register 0xa20001
WiimotePoke(1, 0x04a20001, 0x08)
// Write 7-byte configuration to registers 0xa20001-0xa20008
WiimotePoke(1, 0x04a20001, 0x00)
WiimotePoke(1, 0x04a20002, 0x00)
WiimotePoke(1, 0x04a20003, 0x00)
WiimotePoke(1, 0x04a20004, var.freq) // max volume?
WiimotePoke(1, 0x04a20005, var.volume)
WiimotePoke(1, 0x04a20006, 0x00)
WiimotePoke(1, 0x04a20007, 0x00)
// Write 0x01 to register 0xa20008
WiimotePoke(1, 0x04a20008, 0x01)
// Unmute speaker
Wiimote.Report19 = 0x00 | Int(Wiimote.Rumble)
end if

if pressed(Wiimote.Minus) then
var.freq++
debug = var.freq
// Mute Speaker
Wiimote.Report19 = 0x04 | Int(Wiimote.Rumble)
// Write 0x01 to register 0xa20009
WiimotePoke(1, 0x04a20009, 0x01)
// Write 0x08 to register 0xa20001
WiimotePoke(1, 0x04a20001, 0x08)
// Write 7-byte configuration to registers 0xa20001-0xa20008
WiimotePoke(1, 0x04a20001, 0x00)
WiimotePoke(1, 0x04a20002, 0x00)
WiimotePoke(1, 0x04a20003, 0x00)
WiimotePoke(1, 0x04a20004, var.freq) // max volume?
WiimotePoke(1, 0x04a20005, var.volume)
WiimotePoke(1, 0x04a20006, 0x00)
WiimotePoke(1, 0x04a20007, 0x00)
// Write 0x01 to register 0xa20008
WiimotePoke(1, 0x04a20008, 0x01)
// Unmute speaker
Wiimote.Report19 = 0x00 | Int(Wiimote.Rumble)
end if

This is a huge accomplishment and you can bet that soon enough the hackers will be streaming all kinds crappy 4 bit sounds to their wii-motes. Let the fun begin!!!
Once again Carl, great work!

Next up is integrating the Speaker functionality into the other Windows Wii-Mote apps, as well as the Linux and OSX wii-mote programs. Developers will want to check out the WiiLi wiki for information on how to initialize the wii-mote speaker and send sounds to it.

Source: WiiLi.org
Distribuie

Niciun comentariu:

Trimiteți un comentariu