# HG changeset patch
# User Rusty Russell <rusty@rustcorp.com.au>
# Date 1239512602 -34200
# Branch trunk
# Node ID 4d1c11e34ca295de9161f3766680effc3b97ef8f
# Parent  f55406e1c490f91548a522d1e8c60806efdbcaf0
From http://abstrakraft.org/cwiid/ticket/79:
New Identification + remove Decode + GHWT Guitar as a classic controller

Description
 I've created a patch for the current SVN trunk(184) with the new identification of the extension controller. There is no need of use the function DECODE so I commented it. With this new identification the new guitar is detected and works as a classic controller.
 I've tested with wmgui my classic controller, my nunchuck and my GHWT guitar.

diff -r f55406e1c490 -r 4d1c11e34ca2 libcwiid/cwiid_internal.h
--- a/libcwiid/cwiid_internal.h	Tue Jan 13 16:50:29 2009 +1030
+++ b/libcwiid/cwiid_internal.h	Sun Apr 12 14:33:22 2009 +0930
@@ -125,7 +125,8 @@
 #define CLIFF_IR_BLOCK_2	"\x63\x03"
 
 /* Extension Decode */
-#define DECODE(a)	(((a ^ 0x17)+0x17)&0xFF)
+//#define DECODE(a)	(((a ^ 0x17)+0x17)&0xFF)
+#define DECODE(a)	(a)
 
 /* Write Sequences */
 enum write_seq_type {
diff -r f55406e1c490 -r 4d1c11e34ca2 libcwiid/thread.c
--- a/libcwiid/thread.c	Tue Jan 13 16:50:29 2009 +1030
+++ b/libcwiid/thread.c	Sun Apr 12 14:33:22 2009 +0930
@@ -192,33 +192,40 @@
 
 		if (status_mesg->ext_type == CWIID_EXT_UNKNOWN) {
 			if (wiimote->state.ext_type == CWIID_EXT_NONE) {
-				buf = 0x00;
+				buf = 0x55;
 				/* Initialize extension register space */
-				if (cwiid_write(wiimote, CWIID_RW_REG, 0xA40040, 1, &buf)) {
+				if (cwiid_write(wiimote, CWIID_RW_REG, 0xA400F0, 1, &buf)) {
 					cwiid_err(wiimote, "Extension initialization error");
 					status_mesg->ext_type = CWIID_EXT_UNKNOWN;
 				}
-				/* Read extension ID */
-				else if (cwiid_read(wiimote, CWIID_RW_REG | CWIID_RW_DECODE,
-				                    0xA400FE, 1, &buf)) {
-					cwiid_err(wiimote, "Read error (extension error)");
-					status_mesg->ext_type = CWIID_EXT_UNKNOWN;
-				}
 				else {
-					switch (buf) {
-					case EXT_NONE:
-					case EXT_PARTIAL:
-						status_mesg->ext_type = CWIID_EXT_NONE;
-						break;
-					case EXT_NUNCHUK:
-						status_mesg->ext_type = CWIID_EXT_NUNCHUK;
-						break;
-					case EXT_CLASSIC:
-						status_mesg->ext_type = CWIID_EXT_CLASSIC;
-						break;
-					default:
+					buf=0x00; 
+					if (cwiid_write(wiimote, CWIID_RW_REG, 0xA400FB, 1, &buf)) {
+						cwiid_err(wiimote, "Extension initialization error");
 						status_mesg->ext_type = CWIID_EXT_UNKNOWN;
-						break;
+					}
+					/* Read extension ID */
+					else if (cwiid_read(wiimote, CWIID_RW_REG | CWIID_RW_DECODE,
+					                    0xA400FE, 1, &buf)) {
+						cwiid_err(wiimote, "Read error (extension error)");
+						status_mesg->ext_type = CWIID_EXT_UNKNOWN;
+					}
+					else {
+						switch (buf) {
+						case EXT_NONE:
+						case EXT_PARTIAL:
+							status_mesg->ext_type = CWIID_EXT_NONE;
+							break;
+						case EXT_NUNCHUK:
+							status_mesg->ext_type = CWIID_EXT_NUNCHUK;
+							break;
+						case EXT_CLASSIC:
+							status_mesg->ext_type = CWIID_EXT_CLASSIC;
+							break;
+						default:
+							status_mesg->ext_type = CWIID_EXT_UNKNOWN;
+							break;
+						}
 					}
 				}
 			}
# HG changeset patch
# User Rusty Russell <rusty@rustcorp.com.au>
# Date 1239512719 -34200
# Branch trunk
# Node ID 1b4594a4db68ace2481938b26ccd826731b72c0c
# Parent  4d1c11e34ca295de9161f3766680effc3b97ef8f
Proper implementation of extension identification (http://wiibrew.org/wiki/Wii_Remote)

diff -r 4d1c11e34ca2 -r 1b4594a4db68 libcwiid/cwiid_internal.h
--- a/libcwiid/cwiid_internal.h	Sun Apr 12 14:33:22 2009 +0930
+++ b/libcwiid/cwiid_internal.h	Sun Apr 12 14:35:19 2009 +0930
@@ -112,12 +112,6 @@
 #define BTN_MASK_1			0x9F
 #define NUNCHUK_BTN_MASK	0x03
 
-/* Extension Values */
-#define EXT_NONE	0x2E
-#define EXT_PARTIAL 0xFF
-#define EXT_NUNCHUK 0x00
-#define EXT_CLASSIC 0x01
-
 /* IR Enable blocks */
 #define MARCAN_IR_BLOCK_1	"\x00\x00\x00\x00\x00\x00\x90\x00\xC0"
 #define MARCAN_IR_BLOCK_2	"\x40\x00"
diff -r 4d1c11e34ca2 -r 1b4594a4db68 libcwiid/thread.c
--- a/libcwiid/thread.c	Sun Apr 12 14:33:22 2009 +0930
+++ b/libcwiid/thread.c	Sun Apr 12 14:35:19 2009 +0930
@@ -168,11 +168,52 @@
 	return NULL;
 }
 
+static enum cwiid_ext_type identify_extension(struct wiimote *wiimote)
+{
+	unsigned char buf[6];
+
+	buf[0] = 0x55;
+	/* Initialize extension register space */
+	if (cwiid_write(wiimote, CWIID_RW_REG, 0xA400F0, 1, buf)) {
+		cwiid_err(wiimote, "Extension initialization error");
+		return CWIID_EXT_UNKNOWN;
+	}
+
+	buf[0] = 0x00; 
+	if (cwiid_write(wiimote, CWIID_RW_REG, 0xA400FB, 1, buf)) {
+		cwiid_err(wiimote, "Extension initialization error");
+		return CWIID_EXT_UNKNOWN;
+	}
+
+	/* Read extension ID */
+	if (cwiid_read(wiimote, CWIID_RW_REG | CWIID_RW_DECODE,
+		       0xA400FA, sizeof(buf), buf)) {
+		cwiid_err(wiimote, "Read error (extension error)");
+		return CWIID_EXT_UNKNOWN;
+	}
+
+#if 0
+	printf("extension identification: %02x%02x%02x%02x%02x%02x\n",
+	       buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+#endif
+
+	/* These endings seem to mean disconnected/partial connection */
+	if (memcmp(buf+4, "\x2E\x2E", 2) == 0
+	    || memcmp(buf+4, "\xFF\xFF", 2) == 0)
+		return CWIID_EXT_NONE;
+
+	if (memcmp(buf, "\x00\x00\xA4\x20\x00\x00", 6) == 0)
+		return CWIID_EXT_NUNCHUK;
+	else if (memcmp(buf, "\x00\x00\xA4\x20\x01\x01", 6) == 0)
+		return CWIID_EXT_CLASSIC;
+
+	return CWIID_EXT_UNKNOWN;
+}
+
 void *status_thread(struct wiimote *wiimote)
 {
 	struct mesg_array ma;
 	struct cwiid_status_mesg *status_mesg;
-	unsigned char buf;
 
 	ma.count = 1;
 	status_mesg = &ma.array[0].status_mesg;
@@ -192,42 +233,8 @@
 
 		if (status_mesg->ext_type == CWIID_EXT_UNKNOWN) {
 			if (wiimote->state.ext_type == CWIID_EXT_NONE) {
-				buf = 0x55;
-				/* Initialize extension register space */
-				if (cwiid_write(wiimote, CWIID_RW_REG, 0xA400F0, 1, &buf)) {
-					cwiid_err(wiimote, "Extension initialization error");
-					status_mesg->ext_type = CWIID_EXT_UNKNOWN;
-				}
-				else {
-					buf=0x00; 
-					if (cwiid_write(wiimote, CWIID_RW_REG, 0xA400FB, 1, &buf)) {
-						cwiid_err(wiimote, "Extension initialization error");
-						status_mesg->ext_type = CWIID_EXT_UNKNOWN;
-					}
-					/* Read extension ID */
-					else if (cwiid_read(wiimote, CWIID_RW_REG | CWIID_RW_DECODE,
-					                    0xA400FE, 1, &buf)) {
-						cwiid_err(wiimote, "Read error (extension error)");
-						status_mesg->ext_type = CWIID_EXT_UNKNOWN;
-					}
-					else {
-						switch (buf) {
-						case EXT_NONE:
-						case EXT_PARTIAL:
-							status_mesg->ext_type = CWIID_EXT_NONE;
-							break;
-						case EXT_NUNCHUK:
-							status_mesg->ext_type = CWIID_EXT_NUNCHUK;
-							break;
-						case EXT_CLASSIC:
-							status_mesg->ext_type = CWIID_EXT_CLASSIC;
-							break;
-						default:
-							status_mesg->ext_type = CWIID_EXT_UNKNOWN;
-							break;
-						}
-					}
-				}
+				status_mesg->ext_type = 
+					identify_extension(wiimote);
 			}
 			else {
 				status_mesg->ext_type = wiimote->state.ext_type;
# HG changeset patch
# User Rusty Russell <rusty@rustcorp.com.au>
# Date 1239514553 -34200
# Branch trunk
# Node ID 5a5b08006cd80e50e425e1964008587b34d9fa6a
# Parent  1b4594a4db68ace2481938b26ccd826731b72c0c
Identification for Guitar Hero World Tour Drumkit/Drums.
Note: breaks ABI :(

diff -r 1b4594a4db68 -r 5a5b08006cd8 libcwiid/cwiid.h
--- a/libcwiid/cwiid.h	Sun Apr 12 14:35:19 2009 +0930
+++ b/libcwiid/cwiid.h	Sun Apr 12 15:05:53 2009 +0930
@@ -173,6 +173,7 @@
 	CWIID_EXT_NONE,
 	CWIID_EXT_NUNCHUK,
 	CWIID_EXT_CLASSIC,
+	CWIID_EXT_GHWT_DRUMS,
 	CWIID_EXT_UNKNOWN
 };
 
diff -r 1b4594a4db68 -r 5a5b08006cd8 libcwiid/process.c
--- a/libcwiid/process.c	Sun Apr 12 14:35:19 2009 +0930
+++ b/libcwiid/process.c	Sun Apr 12 15:05:53 2009 +0930
@@ -189,6 +189,7 @@
 		cwiid_err(wiimote, "Received unexpected extension report");
 		break;
 	case CWIID_EXT_UNKNOWN:
+	case CWIID_EXT_GHWT_DRUMS:
 		break;
 	case CWIID_EXT_NUNCHUK:
 		if (wiimote->state.rpt_mode & CWIID_RPT_NUNCHUK) {
diff -r 1b4594a4db68 -r 5a5b08006cd8 libcwiid/thread.c
--- a/libcwiid/thread.c	Sun Apr 12 14:35:19 2009 +0930
+++ b/libcwiid/thread.c	Sun Apr 12 15:05:53 2009 +0930
@@ -206,6 +206,8 @@
 		return CWIID_EXT_NUNCHUK;
 	else if (memcmp(buf, "\x00\x00\xA4\x20\x01\x01", 6) == 0)
 		return CWIID_EXT_CLASSIC;
+	else if (memcmp(buf, "\x01\x00\xA4\x20\x01\x03", 6) == 0)
+		return CWIID_EXT_GHWT_DRUMS;
 
 	return CWIID_EXT_UNKNOWN;
 }
diff -r 1b4594a4db68 -r 5a5b08006cd8 wmdemo/wmdemo.c
--- a/wmdemo/wmdemo.c	Sun Apr 12 14:35:19 2009 +0930
+++ b/wmdemo/wmdemo.c	Sun Apr 12 15:05:53 2009 +0930
@@ -254,6 +254,9 @@
 	case CWIID_EXT_UNKNOWN:
 		printf("Unknown extension attached\n");
 		break;
+	case CWIID_EXT_GHWT_DRUMS:
+		printf("GHWT drumkit attached\n");
+		break;
 	case CWIID_EXT_NUNCHUK:
 		printf("Nunchuk: btns=%.2X stick=(%d,%d) acc.x=%d acc.y=%d "
 		       "acc.z=%d\n", state->ext.nunchuk.buttons,
diff -r 1b4594a4db68 -r 5a5b08006cd8 wmgui/main.c
--- a/wmgui/main.c	Sun Apr 12 14:35:19 2009 +0930
+++ b/wmgui/main.c	Sun Apr 12 15:05:53 2009 +0930
@@ -1050,6 +1050,9 @@
 			case CWIID_EXT_CLASSIC:
 				ext_str = "Classic controller";
 				break;
+			case CWIID_EXT_GHWT_DRUMS:
+				ext_str = "GHWT drumkit";
+				break;
 			case CWIID_EXT_UNKNOWN:
 				ext_str = "Unknown extension";
 				break;
# HG changeset patch
# User Rusty Russell <rusty@rustcorp.com.au>
# Date 1239518224 -34200
# Branch trunk
# Node ID e21b1a2fc840e1d7e0cb44d06f1ab84b75524e2a
# Parent  5a5b08006cd80e50e425e1964008587b34d9fa6a
Hook up reporting and status for GHWT drums.

diff -r 5a5b08006cd8 -r e21b1a2fc840 libcwiid/cwiid.h
--- a/libcwiid/cwiid.h	Sun Apr 12 15:05:53 2009 +0930
+++ b/libcwiid/cwiid.h	Sun Apr 12 16:07:04 2009 +0930
@@ -75,7 +75,8 @@
 #define CWIID_RPT_IR		0x08
 #define CWIID_RPT_NUNCHUK	0x10
 #define CWIID_RPT_CLASSIC	0x20
-#define CWIID_RPT_EXT		(CWIID_RPT_NUNCHUK | CWIID_RPT_CLASSIC)
+#define CWIID_RPT_GHWT_DRUMS	0x40
+#define CWIID_RPT_EXT		(CWIID_RPT_NUNCHUK | CWIID_RPT_CLASSIC | CWIID_RPT_GHWT_DRUMS)
 
 /* LED flags */
 #define CWIID_LED1_ON	0x01
@@ -115,6 +116,30 @@
 #define CWIID_CLASSIC_BTN_DOWN	0x4000
 #define CWIID_CLASSIC_BTN_RIGHT	0x8000
 
+#define CWIID_GHWT_DRUMS_PEDAL	0x0004
+#define CWIID_GHWT_DRUMS_BLUE	0x0008
+#define CWIID_GHWT_DRUMS_GREEN	0x0010
+#define CWIID_GHWT_DRUMS_YELLOW	0x0020
+#define CWIID_GHWT_DRUMS_RED	0x0040
+#define CWIID_GHWT_DRUMS_ORANGE	0x0080
+#define CWIID_GHWT_DRUMS_PLUS	0x0400
+#define CWIID_GHWT_DRUMS_MINUS	0x1000
+
+#define CWIID_CLASSIC_BTN_LEFT	0x0002
+#define CWIID_CLASSIC_BTN_ZR	0x0004
+#define CWIID_CLASSIC_BTN_X		0x0008
+#define CWIID_CLASSIC_BTN_A		0x0010
+#define CWIID_CLASSIC_BTN_Y		0x0020
+#define CWIID_CLASSIC_BTN_B		0x0040
+#define CWIID_CLASSIC_BTN_ZL	0x0080
+#define CWIID_CLASSIC_BTN_R		0x0200
+#define CWIID_CLASSIC_BTN_PLUS	0x0400
+#define CWIID_CLASSIC_BTN_HOME	0x0800
+#define CWIID_CLASSIC_BTN_MINUS	0x1000
+#define CWIID_CLASSIC_BTN_L		0x2000
+#define CWIID_CLASSIC_BTN_DOWN	0x4000
+#define CWIID_CLASSIC_BTN_RIGHT	0x8000
+
 /* Data Read/Write flags */
 #define CWIID_RW_EEPROM	0x00
 #define CWIID_RW_REG	0x04
@@ -165,6 +190,7 @@
 	CWIID_MESG_IR,
 	CWIID_MESG_NUNCHUK,
 	CWIID_MESG_CLASSIC,
+	CWIID_MESG_GHWT_DRUMS,
 	CWIID_MESG_ERROR,
 	CWIID_MESG_UNKNOWN
 };
@@ -232,6 +258,18 @@
 	uint16_t buttons;
 };
 
+struct cwiid_ghwt_drums_mesg {
+	enum cwiid_mesg_type type;
+	/* 6 bit X and Y values of stick above wiimote */
+	uint8_t stick[2];
+	/* 0 = very hard, 7 = not hit at all. */
+	uint8_t softness;
+	/* Which drum/pedal (if any) does softness apply. */
+	uint8_t which_softness;
+	/* What is pressed */
+	uint16_t sensors;
+};
+
 struct cwiid_error_mesg {
 	enum cwiid_mesg_type type;
 	enum cwiid_error error;
@@ -245,6 +283,7 @@
 	struct cwiid_ir_mesg ir_mesg;
 	struct cwiid_nunchuk_mesg nunchuk_mesg;
 	struct cwiid_classic_mesg classic_mesg;
+	struct cwiid_ghwt_drums_mesg ghwt_drums_mesg;
 	struct cwiid_error_mesg error_mesg;
 };
 
@@ -263,9 +302,21 @@
 	uint16_t buttons;
 };
 
+struct ghwt_drums_state {
+	/* 6 bit X and Y values of stick above wiimote */
+	uint8_t stick[2];
+	/* 0 = very hard, 7 = not hit at all. */
+	uint8_t softness;
+	/* Which drum/pedal (if any) does softness apply. */
+	uint8_t which_softness;
+	/* What is pressed */
+	uint16_t sensors;
+};
+
 union ext_state {
 	struct nunchuk_state nunchuk;
 	struct classic_state classic;
+	struct ghwt_drums_state ghwt_drums;
 };
 
 struct cwiid_state {
diff -r 5a5b08006cd8 -r e21b1a2fc840 libcwiid/process.c
--- a/libcwiid/process.c	Sun Apr 12 15:05:53 2009 +0930
+++ b/libcwiid/process.c	Sun Apr 12 16:07:04 2009 +0930
@@ -177,6 +177,40 @@
 	return 0;
 }
 
+static void decode_drums(struct cwiid_ghwt_drums_mesg *drums_mesg,
+			 const unsigned char data[])
+{
+	drums_mesg->type = CWIID_MESG_GHWT_DRUMS;
+
+	drums_mesg->stick[CWIID_X] = data[0] & 0x3F;
+	drums_mesg->stick[CWIID_Y] = data[1] & 0x3F;
+	/* Button bits are inverted. */
+	drums_mesg->sensors = ((~data[5] & 0xFC) | ((~data[4] & 0x14) << 8));
+	drums_mesg->softness = (data[3] >> 5);
+	switch ((data[2] & 0x7E) >> 1) {
+	case 0x1B:
+		drums_mesg->which_softness = CWIID_GHWT_DRUMS_PEDAL;
+		break;
+	case 0x19:
+		drums_mesg->which_softness = CWIID_GHWT_DRUMS_RED;
+		break;
+	case 0x11:
+		drums_mesg->which_softness = CWIID_GHWT_DRUMS_YELLOW;
+		break;
+	case 0x0F:
+		drums_mesg->which_softness = CWIID_GHWT_DRUMS_BLUE;
+		break;
+	case 0x0E:
+		drums_mesg->which_softness = CWIID_GHWT_DRUMS_ORANGE;
+		break;
+	case 0x12:
+		drums_mesg->which_softness = CWIID_GHWT_DRUMS_GREEN;
+		break;
+	default:
+		drums_mesg->which_softness = 0;
+	}
+}
+
 int process_ext(struct wiimote *wiimote, unsigned char *data,
                 unsigned char len, struct mesg_array *ma)
 {
@@ -189,7 +223,6 @@
 		cwiid_err(wiimote, "Received unexpected extension report");
 		break;
 	case CWIID_EXT_UNKNOWN:
-	case CWIID_EXT_GHWT_DRUMS:
 		break;
 	case CWIID_EXT_NUNCHUK:
 		if (wiimote->state.rpt_mode & CWIID_RPT_NUNCHUK) {
@@ -225,6 +258,11 @@
 			                          (uint16_t)data[5]);
 		}
 		break;
+	case CWIID_EXT_GHWT_DRUMS:
+		if (wiimote->state.rpt_mode & CWIID_RPT_GHWT_DRUMS) {
+			decode_drums(&ma->array[ma->count++].ghwt_drums_mesg,
+				     data);
+		}
 	}
 
 	return 0;
diff -r 5a5b08006cd8 -r e21b1a2fc840 libcwiid/state.c
--- a/libcwiid/state.c	Sun Apr 12 15:05:53 2009 +0930
+++ b/libcwiid/state.c	Sun Apr 12 16:07:04 2009 +0930
@@ -75,6 +75,14 @@
 			wiimote->state.ext.classic.r = mesg->classic_mesg.r;
 			wiimote->state.ext.classic.buttons = mesg->classic_mesg.buttons;
 			break;
+		case CWIID_MESG_GHWT_DRUMS:
+			memcpy(wiimote->state.ext.ghwt_drums.stick,
+			       mesg->ghwt_drums_mesg.stick,
+			       sizeof wiimote->state.ext.ghwt_drums.stick);
+			wiimote->state.ext.ghwt_drums.softness = mesg->ghwt_drums_mesg.softness;
+			wiimote->state.ext.ghwt_drums.which_softness = mesg->ghwt_drums_mesg.which_softness;
+			wiimote->state.ext.ghwt_drums.sensors = mesg->ghwt_drums_mesg.sensors;
+			break;
 		case CWIID_MESG_ERROR:
 			wiimote->state.error = mesg->error_mesg.error;
 			break;
@@ -144,8 +152,8 @@
 
 	/* Pick a report mode based on report flags */
 	if ((rpt_mode & CWIID_RPT_EXT) &&
-	  ((wiimote->state.ext_type == CWIID_EXT_NUNCHUK) ||
-	   (wiimote->state.ext_type == CWIID_EXT_CLASSIC))) {
+	    wiimote->state.ext_type != CWIID_EXT_NONE && 
+	    wiimote->state.ext_type != CWIID_EXT_UNKNOWN) {
 		if ((rpt_mode & CWIID_RPT_IR) && (rpt_mode & CWIID_RPT_ACC)) {
 			rpt_type = RPT_BTN_ACC_IR10_EXT6;
 			ir_enable_seq = ir_enable10_seq;
diff -r 5a5b08006cd8 -r e21b1a2fc840 wmdemo/wmdemo.c
--- a/wmdemo/wmdemo.c	Sun Apr 12 15:05:53 2009 +0930
+++ b/wmdemo/wmdemo.c	Sun Apr 12 16:07:04 2009 +0930
@@ -124,7 +124,7 @@
 			break;
 		case 'e':
 			/* CWIID_RPT_EXT is actually
-			 * CWIID_RPT_NUNCHUK | CWIID_RPT_CLASSIC */
+			 * CWIID_RPT_NUNCHUK | CWIID_RPT_CLASSIC | ... */
 			toggle_bit(rpt_mode, CWIID_RPT_EXT);
 			set_rpt_mode(wiimote, rpt_mode);
 			break;
@@ -215,6 +215,7 @@
 	if (state->rpt_mode & CWIID_RPT_IR) printf(" IR");
 	if (state->rpt_mode & CWIID_RPT_NUNCHUK) printf(" NUNCHUK");
 	if (state->rpt_mode & CWIID_RPT_CLASSIC) printf(" CLASSIC");
+	if (state->rpt_mode & CWIID_RPT_GHWT_DRUMS) printf(" GHWT_DRUMS");
 	printf("\n");
 	
 	printf("Active LEDs:");
@@ -251,11 +252,18 @@
 	case CWIID_EXT_NONE:
 		printf("No extension\n");
 		break;
-	case CWIID_EXT_UNKNOWN:
-		printf("Unknown extension attached\n");
-		break;
 	case CWIID_EXT_GHWT_DRUMS:
-		printf("GHWT drumkit attached\n");
+		printf("GHWT drumkit: stick=(%d,%d) pads = %s%s%s%s%s%s softness=%u:%u\n",
+		       state->ext.ghwt_drums.stick[CWIID_X],
+		       state->ext.ghwt_drums.stick[CWIID_Y],
+		       state->ext.ghwt_drums.sensors & CWIID_GHWT_DRUMS_RED ? "R" : "",
+		       state->ext.ghwt_drums.sensors & CWIID_GHWT_DRUMS_BLUE ? "B" : "",
+		       state->ext.ghwt_drums.sensors & CWIID_GHWT_DRUMS_GREEN ? "G" : "",
+		       state->ext.ghwt_drums.sensors & CWIID_GHWT_DRUMS_YELLOW ? "Y" : "",
+		       state->ext.ghwt_drums.sensors & CWIID_GHWT_DRUMS_ORANGE ? "O" : "",
+		       state->ext.ghwt_drums.sensors & CWIID_GHWT_DRUMS_PEDAL ? "P" : "",
+		       state->ext.ghwt_drums.which_softness,
+		       state->ext.ghwt_drums.softness);
 		break;
 	case CWIID_EXT_NUNCHUK:
 		printf("Nunchuk: btns=%.2X stick=(%d,%d) acc.x=%d acc.y=%d "
@@ -275,6 +283,9 @@
 		       state->ext.classic.r_stick[CWIID_Y],
 		       state->ext.classic.l, state->ext.classic.r);
 		break;
+	default:
+		printf("Unknown extension attached\n");
+		break;
 	}
 }
 
@@ -310,6 +321,9 @@
 			case CWIID_EXT_CLASSIC:
 				printf("Classic Controller");
 				break;
+			case CWIID_EXT_GHWT_DRUMS:
+				printf("GHWT Drums");
+				break;
 			default:
 				printf("Unknown Extension");
 				break;
@@ -358,6 +372,22 @@
 			       mesg[i].classic_mesg.r_stick[CWIID_Y],
 			       mesg[i].classic_mesg.l, mesg[i].classic_mesg.r);
 			break;
+		case CWIID_MESG_GHWT_DRUMS:
+			printf("GHWT Drums Report: stick=(%d,%d) pads = %X(%s%s%s%s%s%s%s%s) softness=%u:%u\n",
+			       mesg[i].ghwt_drums_mesg.stick[CWIID_X],
+			       mesg[i].ghwt_drums_mesg.stick[CWIID_Y],
+			       mesg[i].ghwt_drums_mesg.sensors,
+			       mesg[i].ghwt_drums_mesg.sensors & CWIID_GHWT_DRUMS_RED ? "R" : "",
+			       mesg[i].ghwt_drums_mesg.sensors & CWIID_GHWT_DRUMS_BLUE ? "B" : "",
+			       mesg[i].ghwt_drums_mesg.sensors & CWIID_GHWT_DRUMS_GREEN ? "G" : "",
+			       mesg[i].ghwt_drums_mesg.sensors & CWIID_GHWT_DRUMS_YELLOW ? "Y" : "",
+			       mesg[i].ghwt_drums_mesg.sensors & CWIID_GHWT_DRUMS_ORANGE ? "O" : "",
+			       mesg[i].ghwt_drums_mesg.sensors & CWIID_GHWT_DRUMS_PEDAL ? "P" : "",
+			       mesg[i].ghwt_drums_mesg.sensors & CWIID_GHWT_DRUMS_PLUS ? "+" : "",
+			       mesg[i].ghwt_drums_mesg.sensors & CWIID_GHWT_DRUMS_MINUS ? "-" : "",
+			       mesg[i].ghwt_drums_mesg.which_softness,
+			       mesg[i].ghwt_drums_mesg.softness);
+			break;
 		case CWIID_MESG_ERROR:
 			if (cwiid_close(wiimote)) {
 				fprintf(stderr, "Error on wiimote disconnect\n");
# HG changeset patch
# User Rusty Russell <rusty@rustcorp.com.au>
# Date 1239546063 -34200
# Branch trunk
# Node ID 8de5409c315aa480b2569b16671a416bb46a4a33
# Parent  e21b1a2fc840e1d7e0cb44d06f1ab84b75524e2a
Python bindings for drums

diff -r e21b1a2fc840 -r 8de5409c315a python/Wiimote.c
--- a/python/Wiimote.c	Sun Apr 12 16:07:04 2009 +0930
+++ b/python/Wiimote.c	Sun Apr 12 23:51:03 2009 +0930
@@ -521,6 +521,30 @@
 			Py_DECREF(PyExt);
 		}
 		break;
+	case CWIID_EXT_GHWT_DRUMS:
+		if (state.rpt_mode & CWIID_RPT_GHWT_DRUMS) {
+			PyExt = Py_BuildValue("{s:(B,B),s:B,s:B,s:I}",
+			                      "stick",
+			                        state.ext.ghwt_drums.stick[CWIID_X],
+			                        state.ext.ghwt_drums.stick[CWIID_Y],
+			                      "softness", state.ext.ghwt_drums.softness,
+			                      "which_softness", state.ext.ghwt_drums.which_softness,
+			                      "sensors", state.ext.ghwt_drums.sensors);
+
+			if (!PyExt) {
+				Py_DECREF(PyState);
+				return NULL;
+			}
+
+			if (PyDict_SetItemString(PyState, "ghwt_drums", PyExt)) {
+				Py_DECREF(PyState);
+				Py_DECREF(PyExt);
+				return NULL;
+			}
+
+			Py_DECREF(PyExt);
+		}
+		break;
 	default:
 		break;
 	}
@@ -835,6 +859,16 @@
 			             "r", mesg[i].classic_mesg.r,
 			             "buttons", mesg[i].classic_mesg.buttons);
 			break;
+		case CWIID_MESG_GHWT_DRUMS:
+			mesgVal = Py_BuildValue("{s:(B,B),s:B,s:B,s:I}",
+			                      "stick",
+			                        mesg[i].ghwt_drums_mesg.stick[CWIID_X],
+			                        mesg[i].ghwt_drums_mesg.stick[CWIID_Y],
+			                      "softness", mesg[i].ghwt_drums_mesg.softness,
+			                      "which_softness", mesg[i].ghwt_drums_mesg.which_softness,
+			                      "sensors", mesg[i].ghwt_drums_mesg.sensors);
+			break;
+
 		case CWIID_MESG_ERROR:
 			mesgVal = Py_BuildValue("i", mesg[i].error_mesg.error);
 			break;
diff -r e21b1a2fc840 -r 8de5409c315a python/cwiidmodule.c
--- a/python/cwiidmodule.c	Sun Apr 12 16:07:04 2009 +0930
+++ b/python/cwiidmodule.c	Sun Apr 12 23:51:03 2009 +0930
@@ -96,6 +96,7 @@
 	CWIID_CONST_MACRO(RPT_IR),
 	CWIID_CONST_MACRO(RPT_NUNCHUK),
 	CWIID_CONST_MACRO(RPT_CLASSIC),
+	CWIID_CONST_MACRO(RPT_GHWT_DRUMS),
 	CWIID_CONST_MACRO(RPT_EXT),
 	CWIID_CONST_MACRO(LED1_ON),
 	CWIID_CONST_MACRO(LED2_ON),
@@ -129,6 +130,14 @@
 	CWIID_CONST_MACRO(CLASSIC_BTN_L),
 	CWIID_CONST_MACRO(CLASSIC_BTN_DOWN),
 	CWIID_CONST_MACRO(CLASSIC_BTN_RIGHT),
+	CWIID_CONST_MACRO(GHWT_DRUMS_PEDAL),
+	CWIID_CONST_MACRO(GHWT_DRUMS_BLUE),
+	CWIID_CONST_MACRO(GHWT_DRUMS_GREEN),
+	CWIID_CONST_MACRO(GHWT_DRUMS_YELLOW),
+	CWIID_CONST_MACRO(GHWT_DRUMS_RED),
+	CWIID_CONST_MACRO(GHWT_DRUMS_ORANGE),
+	CWIID_CONST_MACRO(GHWT_DRUMS_PLUS),
+	CWIID_CONST_MACRO(GHWT_DRUMS_MINUS),
 	CWIID_CONST_MACRO(RW_EEPROM),
 	CWIID_CONST_MACRO(RW_REG),
 	CWIID_CONST_MACRO(RW_DECODE),
@@ -153,11 +162,13 @@
 	CWIID_CONST_MACRO(MESG_IR),
 	CWIID_CONST_MACRO(MESG_NUNCHUK),
 	CWIID_CONST_MACRO(MESG_CLASSIC),
+	CWIID_CONST_MACRO(MESG_GHWT_DRUMS),
 	CWIID_CONST_MACRO(MESG_ERROR),
 	CWIID_CONST_MACRO(MESG_UNKNOWN),
 	CWIID_CONST_MACRO(EXT_NONE),
 	CWIID_CONST_MACRO(EXT_NUNCHUK),
 	CWIID_CONST_MACRO(EXT_CLASSIC),
+	CWIID_CONST_MACRO(EXT_GHWT_DRUMS),
 	CWIID_CONST_MACRO(EXT_UNKNOWN),
 	CWIID_CONST_MACRO(ERROR_DISCONNECT),
 	CWIID_CONST_MACRO(ERROR_COMM),
