From 9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 13 Apr 2025 18:48:02 +0100 Subject: initial --- site/udo/wiimote.udo | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100755 site/udo/wiimote.udo (limited to 'site/udo/wiimote.udo') diff --git a/site/udo/wiimote.udo b/site/udo/wiimote.udo new file mode 100755 index 0000000..474d2ba --- /dev/null +++ b/site/udo/wiimote.udo @@ -0,0 +1,227 @@ +#ifndef UDO_WIIMOTE +#define UDO_WIIMOTE ## +/* + Wiimote interface + + This file is part of the SONICS UDO collection by Richard Knight 2022 + License: GPL-2.0-or-later + http://1bpm.net +*/ + +#include "interop.udo" + +; button bit masks +#define WII_1 #2# +#define WII_2 #1# +#define WII_A #8# +#define WII_B #4# +#define WII_HOME #128# +#define WII_MINUS #16# +#define WII_PLUS #4096# +#define WII_LEFT #256# +#define WII_RIGHT #512# +#define WII_UP #2048# +#define WII_DOWN #1024# + + +; everything goes to globals when connected +gkwii_pitch init 0 +gkwii_roll init 0 +gkwii_accelX init 0 +gkwii_accelY init 0 +gkwii_accelZ init 0 +gkwii_buttons init 0 + + +#ifdef USE_WIIMOTE_NUNCHUCK +#define WII_Z #-33# +#define WII_C #-34# + +gkwii_ncang init 0 +gkwii_ncmag init 0 +gkwii_ncpitch init 0 +gkwii_ncroll init 0 +#end + + +/* + Get the state of a wiimote button + + kstate wii_button ibutton + + kstate 1 if pressed/held or 0 if not + ibutton the bit mask of the button; use the macros defined +*/ +opcode wii_button, k, i + ibutton xin + if (ibutton < 0) then ; nunchuck buttons not captured by wiidata(0) + ibutton abs ibutton + kvalue = wiidata(ibutton) + else + kvalue = (gkwii_buttons & ibutton == ibutton) ? 1 : 0 + endif + xout kvalue +endop + + + +/* + Keep an instrument on for as long as a wiimote button is held + + wii_buttonhold ibutton, Sinstrument + + ibutton the bit mask of the button; use the macros defined + Sinstrument instrument name to start/stop accordingly +*/ +opcode wii_buttonhold, 0, iS + ibutton, Sinstrument xin + kbut = wii_button(ibutton) + if (changed:k(kbut) == 1) then + if (kbut == 1) then + schedulek(Sinstrument, 0, 999999) ; longnum here as -1 not good for p3 + else + turnoff2(Sinstrument, 0, 1) + endif + endif +endop + + +opcode wii_buttonhold, 0, iSi + ibutton, Sinstrument, ip4 xin + kbut = wii_button(ibutton) + if (changed:k(kbut) == 1) then + if (kbut == 1) then + schedulek(Sinstrument, 0, -1, ip4) + else + turnoff2(Sinstrument, 0, 1) + endif + endif +endop + +/* + Use the wiimote minus and plus buttons to scroll through item indexes + + kitem wii_pager imaxitems [, iteminitial=0, ksetindex=-1] + + kitem the selected item/page + imaxindex maximum number of items + initialindex initial value + ksetindex set the item index directly with this +*/ +opcode wii_pager, k, ioJ + imaxindex, initialindex, ksetindex xin + kcurrentitem init initialindex + + kplus = wii_button($WII_PLUS) + kminus = wii_button($WII_MINUS) + if (kminus == 1 && changed:k(kminus) == 1) then + if (kcurrentitem == 0) then + kcurrentitem = imaxindex + else + kcurrentitem -= 1 + endif + elseif (kplus == 1 && changed:k(kplus) == 1) then + if (kcurrentitem == imaxindex) then + kcurrentitem = 0 + else + kcurrentitem += 1 + endif + elseif (changed:k(ksetindex) == 1) then + if (ksetindex >= 0 && ksetindex <= imaxindex) then + kcurrentitem = ksetindex + endif + endif + xout kcurrentitem +endop + + +instr wii_reset + gkwii_pitch = 0 + gkwii_roll = 0 + gkwii_accelX = 0 + gkwii_accelY = 0 + gkwii_accelZ = 0 + gkwii_buttons = 0 +#ifdef USE_WIIMOTE_NUNCHUCK + gkwii_ncang init 0 + gkwii_ncmag init 0 + gkwii_ncpitch init 0 + gkwii_ncroll init 0 +#end + turnoff +endin + +instr _wii_handler_watchdog + icbid = p4 + SonFail = p5 + kmetro metro 0.5 + if (kmetro == 1) then + if (active:k("wii_handler") == 0) then + schedulek(SonFail, 0, -1, icbid) + turnoff + endif + endif +endin + + +instr _wii_handler_default_fail + icbid = p4 + schedule("wii_reset", 0, 1) + io_sendstring("callback", sprintf("{\"cbid\": %d, \"success\": false}", icbid)) + turnoff +endin + +/* + Connect wiimote and set global variables from it +*/ +instr wii_handler + icbid = p4 + SonComplete = strget(p5) + SonFailWatchdog = strget(p6) + iconnecttimeout = (p7 == 0) ? 1 : p7 + + if (strcmp(SonFailWatchdog, "") == 0) then + SonFailWatchdog = "_wii_handler_default_fail" + endif + schedule("_wii_handler_watchdog", 0, p3, icbid, SonFailWatchdog) + + iwiisuccess wiiconnect iconnecttimeout, 1 + + if (icbid > 0) then + io_sendstring("callback", sprintf("{\"cbid\": %d, \"success\": %s}", icbid, (iwiisuccess == 1) ? "true" : "false")) + endif + + if (iwiisuccess == 0) then + turnoff + endif + + if (strcmp(SonComplete, "") != 0) then + schedule(SonComplete, 0, -1) + endif + + ;gkwii_battery = wiidata(27) + ;printk2 gkwii_battery + + ; set range of pitch and roll as 0 to 1 + wiirange 20, 0, 1 + wiirange 21, 0, 1 + + gkwii_accelX = wiidata(23) ;/ 5 ;abs:k(wiidata(23)) / 5 + gkwii_accelY = wiidata(24) / 5 ;abs:k(wiidata(24)) / 5 + gkwii_accelZ = wiidata(25) / 5 ;abs:k(wiidata(25)) / 5 + gkwii_pitch = wiidata(20) + gkwii_roll = wiidata(21) + gkwii_buttons = wiidata(0) ; bit pattern + +#ifdef USE_WIIMOTE_NUNCHUCK + wiirange 30, 0, 1 + wiirange 31, 0, 1 + gkwii_ncang = wiidata(28) / 360 + gkwii_ncmag = wiidata(29) / 1.2 + gkwii_ncpitch = wiidata(30) + gkwii_ncroll = wiidata(31) +#end + +endin + +#end -- cgit v1.2.3