aboutsummaryrefslogtreecommitdiff
path: root/site/udo/wiimote.udo
diff options
context:
space:
mode:
authorRichard <q@1bpm.net>2025-04-13 18:48:02 +0100
committerRichard <q@1bpm.net>2025-04-13 18:48:02 +0100
commit9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 (patch)
tree291bd79ce340e67affa755a8a6b4f6a83cce93ea /site/udo/wiimote.udo
downloadapps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.tar.gz
apps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.tar.bz2
apps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.zip
initial
Diffstat (limited to 'site/udo/wiimote.udo')
-rwxr-xr-xsite/udo/wiimote.udo227
1 files changed, 227 insertions, 0 deletions
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