TGWii Code
by Rob Terrell · 04/07/2007 (7:38 pm) · 12 comments
TGWii code! My apologies to anyone who was waiting for this. My original plan was to make a resource that was complete (i.e. support the nunchuck) and more abstracted (i.e. so Windows code could be easily added). However, other stuff in life forced their way up the priority queue, and it's taken me this long to get free and think about this again. I just sent my code to Vinh Tran, who's been kicking ass on the Windows Wiimote side. I've asked Vinh to work together on a cross-platform resource.
And, in case I disappear for three months again, I'm posting the code I've got so far.
This is based on code from the DarwinRemote project (on sourceforge). They did all the hard stuff; I just bolted it onto Torque. It's not imported into the project as a framework. I was mucking around inside some of the DarwinRemote code to fix a scaling bug they had, and it was simpler to just import it all and trace through their code.
I'd like to abstract the engine-level interfaces to the point where the code for each platform's wii controller implementation can be in a single file, for each platform's target. Perfectly obvious, right, but I didn't make it work that way from the get-go.
In macCarbInput.cc I added a call to my wiiMote_kickstart() in Input::Init(). wiimote_kickstart() sets up the cocoa stuff (basically, it allocates an autorelease pool for cocoa objects) and starts the bluetooth device discovery. It would probably make more sense to enable this via script. This is to support Cocoa objects from Carbon, because the DarwinRemote code is Cocoa, and TGE is Carbon. (Mac OS X has two APIs -- Cocoa is Objective-C and Carbon is C/C++).
There's a callback from the bluetooth stack when data is received; when that happens, I call into a function I added to macCarbEvents.cc:
void _OnWiiData(float mdx, float mdy, bool aBtnDown, bool aBtnUp, bool bBtn)
The X and Y values are posted to the Game's event queue. The A button is mapped to KEY_BUTTON2 and the b button is mapped to KEY_BUTTON0. Up and Down events for the A button are fired into the queue separately; for the B button, a down and then an up is queued automatically. (This is because, if the first method is used for a button, that button can't be used for walking; if the second method is used, that button can't be used for firing.)
It probably makes sense to map the coordinates to Joystick events, but the Joystick functions are noops in the Mac code, and I would need to understand the Windows input code better before I could try to make that work.
I'm not sure what should be exposed to scripts. I do have a function for rumble exposed to scripting:
extern wiimote_rumble ( double l );
In my TGWii demo, when the player takes damage, he gets a rumble.
The code is here: robterrell.com/Wiimote.zip
I guess that's it. Keep an eye out for any progress from Vinh or myself.
And, in case I disappear for three months again, I'm posting the code I've got so far.
This is based on code from the DarwinRemote project (on sourceforge). They did all the hard stuff; I just bolted it onto Torque. It's not imported into the project as a framework. I was mucking around inside some of the DarwinRemote code to fix a scaling bug they had, and it was simpler to just import it all and trace through their code.
I'd like to abstract the engine-level interfaces to the point where the code for each platform's wii controller implementation can be in a single file, for each platform's target. Perfectly obvious, right, but I didn't make it work that way from the get-go.
In macCarbInput.cc I added a call to my wiiMote_kickstart() in Input::Init(). wiimote_kickstart() sets up the cocoa stuff (basically, it allocates an autorelease pool for cocoa objects) and starts the bluetooth device discovery. It would probably make more sense to enable this via script. This is to support Cocoa objects from Carbon, because the DarwinRemote code is Cocoa, and TGE is Carbon. (Mac OS X has two APIs -- Cocoa is Objective-C and Carbon is C/C++).
There's a callback from the bluetooth stack when data is received; when that happens, I call into a function I added to macCarbEvents.cc:
void _OnWiiData(float mdx, float mdy, bool aBtnDown, bool aBtnUp, bool bBtn)
The X and Y values are posted to the Game's event queue. The A button is mapped to KEY_BUTTON2 and the b button is mapped to KEY_BUTTON0. Up and Down events for the A button are fired into the queue separately; for the B button, a down and then an up is queued automatically. (This is because, if the first method is used for a button, that button can't be used for walking; if the second method is used, that button can't be used for firing.)
It probably makes sense to map the coordinates to Joystick events, but the Joystick functions are noops in the Mac code, and I would need to understand the Windows input code better before I could try to make that work.
I'm not sure what should be exposed to scripts. I do have a function for rumble exposed to scripting:
extern wiimote_rumble ( double l );
In my TGWii demo, when the player takes damage, he gets a rumble.
The code is here: robterrell.com/Wiimote.zip
I guess that's it. Keep an eye out for any progress from Vinh or myself.
About the author
#2
I used starter.fps for the mod. I added in the Killer Kork resource to give you something to shoot at, and also threw in some rumble on damage. That would be on Line 855 of /server/scripts/player.cs:
wiiRumble(%flash);
Also, I made some GUI screens at startup that tell the player to press the Wii remote connect button, etc. That much you probably already know how to do. For fun, I also threw in the TGWii icon that I made, because I spent way too much time on it.
04/08/2007 (1:15 pm)
In case you need a little more help getting started -- you can add these files to your stock 1.5 project, replacing the old files with the same names (haven't tried with 1.5.1 yet, I assume a quick diff would work for that). You will need to turn on the Objective-C++ compiler for "macCocoaWii.m" -- you can do that by getting info on the file in the XCode project window and changing the associated compiler for the file.I used starter.fps for the mod. I added in the Killer Kork resource to give you something to shoot at, and also threw in some rumble on damage. That would be on Line 855 of /server/scripts/player.cs:
wiiRumble(%flash);
Also, I made some GUI screens at startup that tell the player to press the Wii remote connect button, etc. That much you probably already know how to do. For fun, I also threw in the TGWii icon that I made, because I spent way too much time on it.
#3
04/08/2007 (7:10 pm)
The damn cool icon didn't go unnoticed.
#4
You rock!
04/09/2007 (9:33 am)
Thanks so much, Rob. :) I think all the work you did on this is fantastic, and I for one am really appreciative.You rock!
#5
06/03/2007 (3:25 pm)
Just spent a few hours trying to figure out a linking error with IOBluetoothDeviceInquiry. I finally figured out the issue was because I was building for 10.3.9, which doesn't include this class. Building for 10.4 was fine though. Just figured I mention this and hopefully save some people some trouble.
#6
06/03/2007 (7:51 pm)
Could you post the scripts for the level?
#7
I have just put darwiin's code into TGE 1.5. Looks like the replies from the inquiries I make when getting the remote with kick_start() are getting pilled up and not sent back into my delegate's functions. I sniffed with the bluetooth logger and the replies are sent back but are getting stuck somewhere. When I do an [inquiry stop] call, then I get the callback into "deviceInquiryDeviceFound" and right after a call to "deviceInquiryComplete" with the abort boolean on.
Does that ring a bell to anyone? Do I have to stop the inquiry to get the devicefound call?
Thanks in advance...
PS. I am new to ObjectiveC but getting the hang of it...
08/06/2007 (5:01 pm)
Hello, I have just put darwiin's code into TGE 1.5. Looks like the replies from the inquiries I make when getting the remote with kick_start() are getting pilled up and not sent back into my delegate's functions. I sniffed with the bluetooth logger and the replies are sent back but are getting stuck somewhere. When I do an [inquiry stop] call, then I get the callback into "deviceInquiryDeviceFound" and right after a call to "deviceInquiryComplete" with the abort boolean on.
Does that ring a bell to anyone? Do I have to stop the inquiry to get the devicefound call?
Thanks in advance...
PS. I am new to ObjectiveC but getting the hang of it...
#8
08/21/2007 (11:34 am)
Vilain, you shouldn't have to [inquiry stop] to get the device. Here a thought -- are you using any other bluetooth devices? I'm not, and the code works perfectly fine as is. I'll see if I can dig up a bluetooth mouse and see if it makes a difference.
#9
having toyed myself with Rob work, I found that in my configuration, the bluetooth callbacks aren't called if I compile TGE in multithreaded mode. The bluetooth stuff need to be in the main thread (as told in an Apple dev-list), and I blocked on inter-thread communication.
So, I compiled TGE in monothreaded mode, and that worked, except that my application crash if I try to change the screen resolution.
Hope that can help you.
09/17/2007 (1:25 pm)
Hi Vilain,having toyed myself with Rob work, I found that in my configuration, the bluetooth callbacks aren't called if I compile TGE in multithreaded mode. The bluetooth stuff need to be in the main thread (as told in an Apple dev-list), and I blocked on inter-thread communication.
So, I compiled TGE in monothreaded mode, and that worked, except that my application crash if I try to change the screen resolution.
Hope that can help you.
#10
I'm running with the Wii Remote Framework that I downloaded from sourceforge and compiled myself. No big problems here. The only thing I've noticed so far is that the name of the buttons have changed from kWiiRemoteAButton, for example, to just WiiRemoteAButton. No big deal.
My first frustrating problem was that when I dropped macCocoaWii.m into my project I got all sorts of linkage errors. This was caused by xcode defaulting the file type to C instead of C++, based on the file extension. I changed the name to macCocoaWii.mm (probably not necessary, but conventional) and then changed the file type in the "Get Info" dialog to sourcecode.cpp.objcpp.
I'm sure I'll have more problems; hopefully I'll also find more solutions to post.
01/01/2009 (8:15 pm)
I recently picked up a Wii remote because I wanted to try Johnny Chung Lee's head tracking in Torque (see http://www.cs.cmu.edu/~johnny/projects/wii/). I think things have changed a little since Rob set this up and I thought I'd note what I'm finding as I'm trying to get this working - for my own reference if no one else.I'm running with the Wii Remote Framework that I downloaded from sourceforge and compiled myself. No big problems here. The only thing I've noticed so far is that the name of the buttons have changed from kWiiRemoteAButton, for example, to just WiiRemoteAButton. No big deal.
My first frustrating problem was that when I dropped macCocoaWii.m into my project I got all sorts of linkage errors. This was caused by xcode defaulting the file type to C instead of C++, based on the file extension. I changed the name to macCocoaWii.mm (probably not necessary, but conventional) and then changed the file type in the "Get Info" dialog to sourcecode.cpp.objcpp.
I'm sure I'll have more problems; hopefully I'll also find more solutions to post.
#11
But its not discovering the wii remote yet. In trying to track down this problem, I found the following in the log:
Starting wii controller
(0): Unable to find function onWiiDiscoveryStart
wii controller discovery begun
I thought this might have something to do with it, but I found the same log entry in Rob's demo app and it successfully discovers the wii. So this looks like a scripting hook that was put in and never used. The problem is that I have no idea where the code is expecting to find this function. I've done some trial and error of adding an onWiiDiscoveryStart function to various scripts, but I always get the warning. I'm going with YAGNI and deleting the hook.
-----
Did a bit more digging in Rob's demo app and found that he had a client/scripts/wii.cs.dso that had onWiiDiscoveryStart. The problem is that this script is loaded long after the wii is initialized, so even if you do define the function, it won't exist when it's needed.
01/02/2009 (9:46 am)
So I've got things compiled and running. The only hiccough here was to remember to copy the framework files as part of the build.But its not discovering the wii remote yet. In trying to track down this problem, I found the following in the log:
Starting wii controller
(0): Unable to find function onWiiDiscoveryStart
wii controller discovery begun
I thought this might have something to do with it, but I found the same log entry in Rob's demo app and it successfully discovers the wii. So this looks like a scripting hook that was put in and never used. The problem is that I have no idea where the code is expecting to find this function. I've done some trial and error of adding an onWiiDiscoveryStart function to various scripts, but I always get the warning. I'm going with YAGNI and deleting the hook.
-----
Did a bit more digging in Rob's demo app and found that he had a client/scripts/wii.cs.dso that had onWiiDiscoveryStart. The problem is that this script is loaded long after the wii is initialized, so even if you do define the function, it won't exist when it's needed.
#12
have a look at this resource I posted last year about all of this :
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=15313
Nicolas Buquet
www.buquet-net.com/cv/
01/05/2009 (12:23 am)
Hi John,have a look at this resource I posted last year about all of this :
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=15313
Nicolas Buquet
www.buquet-net.com/cv/
Torque Owner Matt Troup
Default Studio Name