/mceXInput

XBox 360 Controller on a Media Center Edition PC using XInput

http://www.brains-N-brawn.com/mceXInput 11/28/2005 casey chesnut

comment(s) 

Introduction

this is a real quick article about writing a MediaCenter AddIn to control a Media Center Edition (MCE) PC with a Wired XBox 360 Controller connected to the MCE PC (using the new DirectX XInput API). been kicking myself the last couple days for not pre-ordering an XBox 360 console. instead of coming back empty handed, i ended up buying a Wired XBox 360 Controller for my PC. when i hooked up the controller, i immediately started trying to use it to control the OS and different applications ... but nothing happened. also assumed that it would be able to control Media Center Edition (Update Rollup 2), since it can be used to control MCE when the XBox console is being used as an Extender ... but that didn't work. so i decided to write a MediaCenter AddIn that would make it controllable with the XBox 360 controller. this provides a seamless experience whether the controller is connected to an XBox 360 console being used as an extender or directly to an MCE PC. the side benefit being that the code provides a pInvoke wrapper for the XInput API.

Wired XBox 360 Controller on a PC

the controller i bought did not come with a driver CD, but the driver can be downloaded from microsoft.com/hardware/. the drivers added a 'Game Controllers' icon to the Control Panel that you can use to calibrate the joystick. NOTE i originally had problems finding buttons 9 and 10. ends up those buttons are activated by pressing down on the thumb controls. NOTE that is your clue that i'm not a gamer. the last console i owned was a mod'd PlayStation 1. the only games i played on it were Metal Gear Solid and some dragon that flew around burning sheep.

an unexpected treat was that when you plug the headset into the joystick, the PC will recognize the new hardware! this will allow game developers to provide almost identical game control experiences between the console and the PC. the problem with this headset is that its crappy quality. i need better sound quality from stereo (fuck mono) headphones, a noise canceling mic, and a behind the neck band.

NOTE the Wireless XBox 360 Controller does not currently work with a PC. even if you have the 'Play and Charge' cable connected, because that cable is only used for charging and does not transmit controller data. i hope that PCs get a dongle that allow them to use the Wireless controllers in the future.

XInput

XInput is the new DirectX API for working with the XBox 360 Controller (instead of DirectInput). its a part of the DirectX SDK October CTP. it can be coded against with C++ or the Managed DirectX Beta for .NET 2.0. the new Managed DirectX namespace is Microsoft.DirectX.XInput. the problem is that the October CTP only works with .NET 2.0 Beta 2. i've already installed VS2005 RTM so that is not an option. also, i want to use this with MediaCenter, and MediaCenter currently only supports .NET 1.1. to get around this i had to write my own managed wrapper by pInvoking the native xinput9_1_0.dll. this was real simple because it only exposes 4 methods (below). so you can use this library for both .NET 1.1 and 2.0 applications, with or without Managed DirectX

XInputGetState is the call to get the current joystick state, and this is what it returns

here are some code examples for how to use the new wrapper. first how to see if the 'A' button is pressed.

uint controllerId = 0; //0-3 for max of 4 controllers
XInput.GamePadState gps = XInput.GetState(controllerId);
if(gps.AButton == true)
{
	//do something
}

the next line is for controlling vibration

uint controllerId = 0;
ushort leftEngineSpeed = XInput.constMaxEngineSpeed;
ushort rightEngineSpeed = XInput.constMaxEngineSpeed;
XInput.SetVibration(controllerId, leftEngineSpeed, rightEngineSpeed);

and this code shows how to do audio playback through the connected headphone using DirectSound. with more code you can use DirectSound to capture from the mic as well

uint controllerId = 0;
if(XInput.IsVoiceCapabile(controllerId))
{
	if(XInput.IsVoiceAvailablecontrollerId))
	{
		Guid headphoneGuid;
		Guid micGuid;
		XInput.pInvokeGetDSoundAudioDeviceGuids(controllerId, out headphoneGuid, out micGuid);

		Device headphoneDev = new Device(headphoneGuid);
		headphoneDev.SetCooperativeLevel(this, CooperativeLevel.Priority);

		string wavFile = @"Startup.wav";
		SecondaryBuffer sndBuffer = new SecondaryBuffer(wavFile, headphoneDev);

		sndBuffer.Play(0, BufferPlayFlags.Default);
	}
	else
	{
		MessageBox.Show("voice not available");
	}
}
else
{
	MessageBox.Show("not voice capable");
}

my only problem with the XInput API is that it does not allow you to hook the middle 'XBox' button press event. i'm assuming that MS is reserving rights to that button for later use? e.g. if connected to a MCE PC then it should automatically open up the MCE shell. Thanks to the ZMan for giving me a jump start on where to find the XInput bits from the work he did on using XInput to control a pan/tilt camera for all the gamer cam grrls out there. you know any cam girl that uses an XBox controller to show the goods becomes that much hotter ... did i mention you can control gamepad vibration :)

Media Center

now i've got the hardware and can read the controller data. all thats left is to put it into MCE. this was accomplished with a MediaCenter AddIn that runs in the background. NOTE if you want more info about writing MCE AddIns, then check out the /mceSAPI article. that article is real similar to this but uses Speech Recognition and Speech Synthesis for control. as MCE starts up it kicks off a long running process that just watches for XBox 360 Controller input. as it is starting up, or when the controller is plugged in, the joystick will vibrate for half a second to let you know that the mceXInput AddIn is working. it then maps that input to the proper MediaCenter command (mostly keyboard commands). NOTE the Vista version of MCE is likely to support .NET 2.0, and then i would not have had to rewrap the XInput API.

haven't actually touched an XBox 360 yet, so the picture above was all that i had to go off of for mapping the controls correctly. kind of surprised volume control doesn't show up anywhere? mapped all of the keys except for the yellow 'Y' for the 'on-screen keyboard'. need to see how the real thing works first ... finally, i don't have a Tuner card for my MCE installation, so i could not test the controls related to TV viewing :(

Video

here's a short video showing it being used

Conclusion

that shows how to write a MediaCenter AddIn to let you control your MCE PC with a Wired XBox 360 Controller. my hope is that the Vista version of MCE will support this out of the box to provide a seamless experience between the XBox 360 (being used as an Extender) and your MCE PC. this took less than a day to develop. now i can return to kicking myself for not preordering ...

expect for newer PC games to start supporting the Wired XBox 360 Controller out of the box. personally, i'd like to see NASAs WorldWind support it as well.

ultimately, i hope that .NET makes its way to the XBox 360 console, so that 3rd party developers can use Managed DirectX to write casual games that run on the console. i've been blogging this for a while now to no avail. this is the opposition i've been getting

maybe XNA will be the answer i want to hear. anything would be better than the current blow off. so how do i get a look at an XBox 360 dev kit?

Source

here is the source code for the mceXInput AddIn. the code is for VS.NET 1.1. for XInput, you will need the October CTP of DirectX installed. you will also need the driver installed for the Wired XBox 360 Controller. i use 'deploy.bat' to build and install the assembly.

if you're not interested in the code, and just want to use it, then just unzip the following directory and run 'install.bat'.

Updates

might update this to support the 'on screen keyboard' functionality once i see how XBox supports it

Future

still need to try out WWF. later