static void wiimod_classic_in_ext()

in hid-wiimote-modules.c [1044:1196]


static void wiimod_classic_in_ext(struct wiimote_data *wdata, const __u8 *ext)
{
	__s8 rx, ry, lx, ly, lt, rt;

	/*   Byte |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    1   | RX <5:4>  |              LX <5:0>             |
	 *    2   | RX <3:2>  |              LY <5:0>             |
	 *   -----+-----+-----+-----+-----------------------------+
	 *    3   |RX<1>| LT <5:4>  |         RY <5:1>            |
	 *   -----+-----+-----------+-----------------------------+
	 *    4   |     LT <3:1>    |         RT <5:1>            |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    5   | BDR | BDD | BLT | B-  | BH  | B+  | BRT |  1  |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    6   | BZL | BB  | BY  | BA  | BX  | BZR | BDL | BDU |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 * All buttons are 0 if pressed
	 * RX and RY are right analog stick
	 * LX and LY are left analog stick
	 * LT is left trigger, RT is right trigger
	 * BLT is 0 if left trigger is fully pressed
	 * BRT is 0 if right trigger is fully pressed
	 * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons
	 * BZL is left Z button and BZR is right Z button
	 * B-, BH, B+ are +, HOME and - buttons
	 * BB, BY, BA, BX are A, B, X, Y buttons
	 * LSB of RX, RY, LT, and RT are not transmitted and always 0.
	 *
	 * With motionp enabled it changes slightly to this:
	 *   Byte |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    1   | RX <5:4>  |          LX <5:1>           | BDU |
	 *    2   | RX <3:2>  |          LY <5:1>           | BDL |
	 *   -----+-----+-----+-----+-----------------------+-----+
	 *    3   |RX<1>| LT <5:4>  |         RY <5:1>            |
	 *   -----+-----+-----------+-----------------------------+
	 *    4   |     LT <3:1>    |         RT <5:1>            |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    5   | BDR | BDD | BLT | B-  | BH  | B+  | BRT | EXT |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    6   | BZL | BB  | BY  | BA  | BX  | BZR |  0  |  0  |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 * Only the LSBs of LX and LY are lost. BDU and BDL are moved, the rest
	 * is the same as before.
	 */

	static const s8 digital_to_analog[3] = {0x20, 0, -0x20};

	if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
		if (wiimote_dpad_as_analog) {
			lx = digital_to_analog[1 - !(ext[4] & 0x80)
				+ !(ext[1] & 0x01)];
			ly = digital_to_analog[1 - !(ext[4] & 0x40)
				+ !(ext[0] & 0x01)];
		} else {
			lx = (ext[0] & 0x3e) - 0x20;
			ly = (ext[1] & 0x3e) - 0x20;
		}
	} else {
		if (wiimote_dpad_as_analog) {
			lx = digital_to_analog[1 - !(ext[4] & 0x80)
				+ !(ext[5] & 0x02)];
			ly = digital_to_analog[1 - !(ext[4] & 0x40)
				+ !(ext[5] & 0x01)];
		} else {
			lx = (ext[0] & 0x3f) - 0x20;
			ly = (ext[1] & 0x3f) - 0x20;
		}
	}

	rx = (ext[0] >> 3) & 0x18;
	rx |= (ext[1] >> 5) & 0x06;
	rx |= (ext[2] >> 7) & 0x01;
	ry = ext[2] & 0x1f;

	rt = ext[3] & 0x1f;
	lt = (ext[2] >> 2) & 0x18;
	lt |= (ext[3] >> 5) & 0x07;

	rx <<= 1;
	ry <<= 1;
	rt <<= 1;
	lt <<= 1;

	input_report_abs(wdata->extension.input, ABS_HAT1X, lx);
	input_report_abs(wdata->extension.input, ABS_HAT1Y, ly);
	input_report_abs(wdata->extension.input, ABS_HAT2X, rx - 0x20);
	input_report_abs(wdata->extension.input, ABS_HAT2Y, ry - 0x20);
	input_report_abs(wdata->extension.input, ABS_HAT3X, rt);
	input_report_abs(wdata->extension.input, ABS_HAT3Y, lt);

	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LT],
			 !(ext[4] & 0x20));
	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_MINUS],
			 !(ext[4] & 0x10));
	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_HOME],
			 !(ext[4] & 0x08));
	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_PLUS],
			 !(ext[4] & 0x04));
	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_RT],
			 !(ext[4] & 0x02));
	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZL],
			 !(ext[5] & 0x80));
	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_B],
			 !(ext[5] & 0x40));
	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_Y],
			 !(ext[5] & 0x20));
	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_A],
			 !(ext[5] & 0x10));
	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_X],
			 !(ext[5] & 0x08));
	input_report_key(wdata->extension.input,
			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZR],
			 !(ext[5] & 0x04));

	if (!wiimote_dpad_as_analog) {
		input_report_key(wdata->extension.input,
				 wiimod_classic_map[WIIMOD_CLASSIC_KEY_RIGHT],
				 !(ext[4] & 0x80));
		input_report_key(wdata->extension.input,
				 wiimod_classic_map[WIIMOD_CLASSIC_KEY_DOWN],
				 !(ext[4] & 0x40));

		if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
			input_report_key(wdata->extension.input,
				 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT],
				 !(ext[1] & 0x01));
			input_report_key(wdata->extension.input,
				 wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP],
				 !(ext[0] & 0x01));
		} else {
			input_report_key(wdata->extension.input,
				 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT],
				 !(ext[5] & 0x02));
			input_report_key(wdata->extension.input,
				 wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP],
				 !(ext[5] & 0x01));
		}
	}

	input_sync(wdata->extension.input);
}