HelpBrowser: path box becomes a more conventional search box
[supercollider.git] / SCClassLibrary / Common / Control / WII.sc
blob969cc223905df60ed0203a26845e2b8cb39c4003
1 /// NOTE: this code is still in an experimental state and only works on Linux, if compiled with Wii support.
2 /// Therefor, it also has no helpfile yet
3 /// This code may change without notice; do not use this code, unless you really want to and don't mind
4 /// having to change your code in the future.
5 /// Expect this code to be fully functional by version 3.2
6 /// - october 2007 - nescivi
8 WiiCalibrationInfo {
9         var <accX_zero, <accY_zero, <accZ_zero, <accX_lg, <accY_lg, <accZ_lg;
10         var <nAccX_zero, <nAccY_zero, <nAccZ_zero, <nAccX_lg, <nAccY_lg, <nAccZ_lg;
11         var <nX_max, <nX_min, <nX_center, <nY_max, <nY_min, <nY_center;
13         printOn { | stream |
14                 stream
15                 << this.class.name << $(
16                 << "accX_zero: " << accX_zero << ", "
17                 << "accY_zero: " << accY_zero << ", "
18                 << "accZ_zero: " << accZ_zero << ", "
19                 << "accX_lg: " << accX_lg << ", "
20                 << "accY_lg: " << accY_lg << ", "
21                 << "accZ_lg: " << accZ_lg << ", "
22                 << "nunchuk accX_zero: " << nAccX_zero << ", "
23                 << "nunchuk accY_zero: " << nAccY_zero << ", "
24                 << "nunchuk accZ_zero: " << nAccZ_zero << ", "
25                 << "nunchuk accX_lg: " << nAccX_lg << ", "
26                 << "nunchuk accY_lg: " << nAccY_lg << ", "
27                 << "nunchuk accZ_lg: " << nAccZ_lg << ", "
28                 << "nunchuk x_min: " << nX_min << ", "
29                 << "nunchuk x_max: " << nX_max << ", "
30                 << "nunchuk x_center: " << nX_center << ", "
31                 << "nunchuk y_min: " << nY_min << ", "
32                 << "nunchuk y_max: " << nY_max << ", "
33                 << "nunchuk y_center: " << nY_center
34                 << $)
35         }
38 WiiMoteIRObject{
39         var <>id, <>valid, <>posx, <>posy, <>size;
40         var <>action;
43 WiiMote {
44         var dataPtr, <spec, <actionSpec; // <slots
45         var <>id;
46         var <battery;
47         var <ext_type;
48         var <>closeAction, <>connectAction, <>disconnectAction;
49         var <calibration;
50         var <remote_led, <>remote_buttons, <>remote_motion, <>remote_ir;
51         var <>nunchuk_buttons, <>nunchuk_motion, <>nunchuk_stick;
52         var <>classic_buttons, <>classic_stick1, <>classic_stick2, <>classic_analog;
53         var <>dumpEvents = false;
54         classvar all;
55         classvar < eventLoopIsRunning = false;
56 //      classvar < updateDataTask, <updateTask;
58         *initClass {
59                 all = [];
60         }
62         *devicesMap{
63                 ^(
64                         wii_mote: [
65                                 \ax, \ay, \az, \ao,
66                                 \bA, \bB, \bOne, \bTwo,
67                                 \bMinus, \bHome, \bPlus, \bUp, \bDown, \bLeft, \bRight,
68                                 \led1, \led2, \led3, \led4,
69                                 \battery
70                         ],
71                         wii_nunchuk: [
72                                 \nax, \nay, \naz, \nao, \nsx, \nsy, \nbZ, \nbC
73                         ],
74                         wii_classic: [
75                                 \cbX, \cbY, \cbA, \cbB, \cbL, \cbR,
76                                 \cbZL, \cbZR,
77                                 \cbUp, \cbDown, \cbLeft, \cbRight,
78                                 \cbMinus, \cbHome, \cbPlus,
79                                 \csx1, \csy1, \csx2, \csy2,
80                                 \caleft, \caright
81                         ]
82                 )
83         }
85         deviceSpec {
86                 ^(
87                         battery: { battery },
88                         led1: { remote_led[0] },
89                         led2: { remote_led[1] },
90                         led3: { remote_led[2] },
91                         led4: { remote_led[3] },
92                         ax: { remote_motion[0] },
93                         ay: { remote_motion[1] },
94                         az: { remote_motion[2] },
95                         ao: { remote_motion[3] },
97                         bA: { remote_buttons[0] },
98                         bB: { remote_buttons[1] },
99                         bOne: { remote_buttons[2] },
100                         bTwo: { remote_buttons[3] },
101                         bMinus: { remote_buttons[4] },
102                         bHome: { remote_buttons[5] },
103                         bPlus: { remote_buttons[6] },
104                         bUp: { remote_buttons[7] },
105                         bDown: { remote_buttons[8] },
106                         bLeft: { remote_buttons[9] },
107                         bRight: { remote_buttons[10] },
109 /*                      px: { remote_ir[0] },
110                         py: { remote_ir[1] },
111                         angle: { remote_ir[2] },
112                         tracking: { remote_ir[3] },
115                         nax: { nunchuk_motion[0] },
116                         nay: { nunchuk_motion[1] },
117                         naz: { nunchuk_motion[2] },
118                         nao: { nunchuk_motion[3] },
120                         nsx: { nunchuk_stick[0] },
121                         nsy: { nunchuk_stick[1] },
123                         nbZ: { nunchuk_buttons[0] },
124                         nbC: { nunchuk_buttons[1] },
126                         cbX: { classic_buttons[0] },
127                         cbY: { classic_buttons[1] },
128                         cbA: { classic_buttons[2] },
129                         cbB: { classic_buttons[3] },
130                         cbL: { classic_buttons[4] },
131                         cbR: { classic_buttons[5] },
132                         cbZL: { classic_buttons[6] },
133                         cbZR: { classic_buttons[7] },
134                         cbUp: { classic_buttons[8] },
135                         cbDown: { classic_buttons[9] },
136                         cbLeft: { classic_buttons[10] },
137                         cbRight: { classic_buttons[11] },
138                         cbMinus: { classic_buttons[12] },
139                         cbHome: { classic_buttons[13] },
140                         cbPlus: { classic_buttons[14] },
142                         csx1: { classic_stick1[0] },
143                         csy1: { classic_stick1[1] },
145                         csx2: { classic_stick2[0] },
146                         csy2: { classic_stick2[1] },
148                         caleft: { classic_analog[0] },
149                         caright: { classic_analog[1] }
150                 )
151         }
153         *all {
154                 ^all.copy
155         }
156         *closeAll {
157                 all.copy.do({ | dev | dev.close });
158         }
159         *new { |id|
160                 ^super.new.id_(id).prInit();
161         }
162         isOpen {
163                 ^dataPtr.notNil
164         }
165         reconnect{
166                 this.disconnect;
167                 this.connect;
168         }
169         connect{
170                 ^this.prConnect;
171         }
172         disconnect{
173                 ^this.prDisconnect;
174         }
175         address{
176                 ^this.prAddress;
177         }
178         /*
179         setAddress{ |address|
180                 ^this.prSetAddress( address );
181                 }*/
182         close {
183                 if (this.isOpen) {
184                         this.prClose;
185                         //      all.remove(this);
186                 };
187                 try { all.remove( this ) };
188         }
189         setAction{ |key,keyAction|
190                 actionSpec.put( key, keyAction );
191         }
192         removeAction{ |key|
193                 actionSpec.removeAt( key );
194         }
195         at { | controlName |
196                 ^this.spec.atFail(controlName, {
197                         Error("invalid control name").throw
198                 });
199         }
200         /*
201         getLEDState { |id|
202                 this.prWiiGetLED( remote_led );
203                 ^remote_led[id]
204                 }*/
205         setLEDState { |id,state|
206                 var r;
207                 remote_led[id] = state;
208                 actionSpec.at( (\led ++ (id+1) ).asSymbol ).value( state );
209                 r = this.prWiiSetLED( remote_led );
210                 //              this.update;
211                 ^r;
212         }
213         /*
214         getExpansion{
215                 ^this.prGetExpansion;
216                 }*/
218         enable{ |onoff|
219                 this.prEnable( onoff );
220                 //              this.update;
221         }
222         enableExpansion{ |onoff|
223                 this.prEnableExpansion( onoff );
224                 //              this.update;
225         }
226         enableButtons{ |onoff|
227                 this.prEnableButtons( onoff );
228                 //              this.update;
229         }
230         enableMotionSensor{ |onoff|
231                 this.prEnableMotionSensor( onoff );
232                 //              this.update;
233         }
234         enableIRSensor{ |onoff|
235                 this.prEnableIRSensor( onoff );
236                 //              this.update;
237         }
238         rumble{ |onoff|
239                 this.prSetVibration( onoff );
240                 //              this.update;
241         }
242         /*
243         playSample{ |play,freq,vol,sample=0|
244                 this.prPlaySpeaker( play, freq, vol, sample );
245                 //              this.update;
246         }
247         mute{ |onoff|
248                 this.prMuteSpeaker( onoff );
249                 //              this.update;
250         }
251         enableSpeaker{ |onoff|
252                 this.prEnableSpeaker( onoff );
253                 //              this.update;
254         }
255         initSpeaker{ |format=0|
256                 this.prInitSpeaker( format );
257                 //              this.update;
258                 }*/
260         *start{ |updtime=50|
261                 UI.registerForShutdown({
262                         this.closeAll;
263                         this.prStop;
264                 });
265                 this.prStart( updtime );
266                 eventLoopIsRunning = true;
267         }
269         *discover{
270                 var newid, newwii, newall;
271                 if ( eventLoopIsRunning.not, { this.start; } );
272                 newid = all.size;
273                 newwii = WiiMote.new;
274                 "To discover the WiiMote, please press buttons 1 and 2 on the device and wait till the LEDs stop blinking".postln;
275                 newall = all.copy.add(newwii);
276                 if(this.prDiscover( newid, newall )) {
277                         // prDiscover returns true if the device was added, so then update the 'all' array.
278                         all = newall;
279                 };
280                 ^this.all;
281         }
283         *stop{
284                 this.prStop;
285                 eventLoopIsRunning = false;
286         }
288         // PRIVATE
289         prInit {
290                 remote_led = Array.fill( 4, 0 );
291                 remote_buttons = Array.fill( 11, 0 );
292                 remote_motion = Array.fill( 4, 0 );
293                 remote_ir = Array.fill( 4, { WiiMoteIRObject.new } );
294                 nunchuk_buttons = Array.fill( 2, 0 );
295                 nunchuk_motion = Array.fill( 4, 0 );
296                 nunchuk_stick = Array.fill( 2, 0 );
297                 classic_buttons = Array.fill( 15, 0 );
298                 classic_stick1 = Array.fill( 2, 0 );
299                 classic_stick2 = Array.fill( 2, 0 );
300                 classic_analog = Array.fill( 2, 0 );
301                 battery = 0;
303                 this.prOpen;
305                 closeAction = {};
306                 connectAction = {};
307                 disconnectAction = {};
309                 //              //              this.prWiiGetLED( remote_led );
310                 //              calibration = this.prCalibration(WiiCalibrationInfo.new);
312                 spec = this.deviceSpec;
313                 actionSpec = IdentityDictionary.new;
314         }
315         *prStart { |updtime=0.05|
316                 _Wii_Start;
317                 ^this.primitiveFailed
318         }
319         *prStop {
320                 _Wii_Stop;
321                 ^this.primitiveFailed
322         }
323         *prDiscover { |newid,alldevices|
324                 _Wii_Discover
325                 ^this.primitiveFailed
326         }
327         prOpen {
328                 _Wii_Open;
329                 ^this.primitiveFailed
330         }
331         prClose {
332                 _Wii_Close;
333                 ^this.primitiveFailed
334         }
335         prAddress { |address|
336                 _Wii_Address;
337                 ^this.primitiveFailed
338         }
339         /*
340         prSetAddress { |address|
341                 _Wii_SetAddress;
342                 ^this.primitiveFailed
343                 }*/
344         prConnect {
345                 _Wii_Connect;
346                 ^this.primitiveFailed
347         }
348         prDisconnect {
349                 _Wii_Disconnect;
350                 ^this.primitiveFailed
351         }
352         prCalibration { |calib|
353                 _Wii_Calibration;
354                 ^this.primitiveFailed
355         }
356         /*      prGetExpansion {
357                 _Wii_GetExpansion;
358                 ^this.primitiveFailed
359         }
360         prGetBattery {
361                 _Wii_GetBattery;
362                 ^this.primitiveFailed
363                 }*/
364         prEnable { |onoff|
365                 _Wii_Enable;
366                 ^this.primitiveFailed
367         }
368         prEnableExpansion { |onoff|
369                 _Wii_EnableExpansion;
370                 ^this.primitiveFailed
371         }
372         prEnableIRSensor { |onoff|
373                 _Wii_EnableIRSensor;
374                 ^this.primitiveFailed
375         }
376         prEnableMotionSensor { |onoff|
377                 _Wii_EnableMotionSensor;
378                 ^this.primitiveFailed
379         }
380         prEnableButtons { |onoff|
381                 _Wii_EnableButtons;
382                 ^this.primitiveFailed
383         }
384         prSetVibration { |onoff|
385                 _Wii_SetVibration;
386                 ^this.primitiveFailed
387         }
388         /*
389         prPlaySpeaker { |play, freq, vol, sample |
390                 _Wii_PlaySpeaker;
391                 ^this.primitiveFailed
392         }
393         prMuteSpeaker { |onoff |
394                 _Wii_MuteSpeaker;
395                 ^this.primitiveFailed
396         }
397         prInitSpeaker { |format|
398                 _Wii_InitSpeaker;
399                 ^this.primitiveFailed
400         }
401         prEnableSpeaker { |onoff |
402                 _Wii_EnableSpeaker;
403                 ^this.primitiveFailed
404         }
405         */
406         /*      prWiiGetLED { | states |
407                 _Wii_GetLED;
408                 ^this.primitiveFailed
409                 }*/
410         prWiiSetLED { |states|
411                 _Wii_SetLED;
412                 ^this.primitiveFailed
413         }
415         prHandleBatteryEvent{ |batlevel|
416                 battery = batlevel;
417                 actionSpec.at( \battery ).value( spec.at( \battery ).value );
418                 // battery action
419         }
421         prHandleExtensionEvent{ |exttype|
422                 ext_type = exttype;
423         }
425         prHandleButtonEvent{ |buttonData|
426                 //              buttonData are bits that decode to separate buttons (do in Primitive internally, and pass on Array?
427                 //("handle button Event"+buttonData).postln;
428                 remote_buttons = buttonData;
430                 [ \bA, \bB, \bOne, \bTwo, \bMinus, \bHome, \bPlus, \bUp, \bDown, \bLeft, \bRight ].do{ |key|
431                         actionSpec.at( key ).value( spec.at(key).value );
432                         if ( dumpEvents, { (key + spec.at(key).value.round(0.00001)).postln; });
433                 }
434         }
436         prHandleNunchukEvent{ |nunchukButtons, nunJoyX, nunJoyY, nunAccX, nunAccY, nunAccZ|
438                 // buttonData are bits that decode to separate buttons (do in Primitive)
439                 nunchuk_buttons = nunchukButtons;
440                 nunchuk_motion = [ nunAccX, nunAccY, nunAccZ, 0 ];
441                 nunchuk_stick = [ nunJoyX, nunJoyY ];
443                 [ \nax, \nay, \naz, \nsx, \nsy, \nbZ, \nbC ].do{ |key|
444                         actionSpec.at( key ).value( spec.at(key).value );
445                         if ( dumpEvents, { (key + spec.at(key).value.round(0.00001)).postln; });
446                 }
447         }
449         prHandleClassicEvent{ |clasButtons, clasJoy1X, clasJoy1Y, clasJoy2X, clasJoy2Y, clasL, clasR|
451                 // buttonData are bits that decode to separate buttons (do in Primitive)
452                 classic_buttons = clasButtons;
453                 classic_stick1 = [clasJoy1X, clasJoy1Y];
454                 classic_stick2 = [clasJoy2X, clasJoy2Y];
455                 classic_analog = [clasL, clasR];
457                 [ \cbX, \cbY, \cbA, \cbB, \cbL, \cbR, \cbZL, \cbZR, \cbUp, \cbDown, \cbLeft, \cbRight, \cbMinus, \cbHome, \cbPlus, \csx1, \csy1, \csx2, \csy2, \caleft, \caright  ].do{ |key|
458                         actionSpec.at( key ).value( spec.at(key).value );
459                         if ( dumpEvents, { (key + spec.at(key).value.round(0.00001)).postln; });
460                 }
461         }
463         prHandleIREvent{ |id,valid,posx,posy,size|
464                 // make ir an array of WiiMoteIRObject's and assign data to right IR object, and do actions
465                 remote_ir[id].valid_( valid ).posx_( posx ).posy_( posy ).size_( size ).action.value;
466         }
468         prHandleAccEvent{ |accX,accY,accZ|
469                 remote_motion = [ accX, accY, accZ, 0 ];
470                 // actions:
471                 [ \ax, \ay, \az ].do{ |key|
472                         actionSpec.at( key ).value( spec.at(key).value );
473                         if ( dumpEvents, { (key + spec.at(key).value.round(0.00001)).postln; });
474                 }
475         }
477         prHandleEvent {
478                 | buttonData, posX, posY, angle, tracking, accX, accY, accZ, orientation, extType, eButtonData, eData1, eData2, eData3, eData4, eData5, eData6, batteryLevel |
479                 battery = batteryLevel;
480                 remote_buttons = buttonData;
481                 remote_motion = [ accX, accY, accZ, orientation/3 ];
482                 remote_ir = [ posX, posY, angle, tracking ];
483                 ext_type = extType;
484                 if ( extType == 1, {
485                         nunchuk_buttons = eButtonData;
486                         nunchuk_motion = [ eData3, eData4, eData5, eData6/3 ];
487                         nunchuk_stick = [ eData1, eData2 ];
488                 });
489                 if ( extType == 2, {
490                         //                      classic_buttons.do{ |it,i| classic_buttons[i] = eButtonData.bitTest( i ).asInteger };
491                         classic_buttons = eButtonData;
492                         classic_stick1 = [eData1, eData2];
493                         classic_stick2 = [eData3, eData4];
494                         classic_analog = [eData5, eData6];
495                 });
497                 // event callback
498                 spec.keysValuesDo{ |key,val,i|
499                         actionSpec.at( key ).value( val.value );
500                         if ( dumpEvents, { (key + val.value.round(0.00001)).postln; });
501                 }
502         }
504         prReadError{
505                 this.close;
506                 "WiiMote read error".warn;
507                 closeAction.value;
508         }
510         prConnectAction{
511                 "WiiMote connected".postln;
512                 connectAction.value;
513         }
515         prDisconnectAction{
516                 "WiiMote disconnected!".warn;
517                 disconnectAction.value;
518         }
521 // EOF