Exemplo n.º 1
0
void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) {
	if (!wm)	{
		return;
	}

	switch (wm->handshake_state) {
		case 0: {
				byte* buf;

				/* continuous reporting off, report to buttons only */
				WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
				wiiuse_set_leds(wm, WIIMOTE_LED_NONE);

				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC);
				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
				WIIMOTE_DISABLE_FLAG(wm, WIIUSE_CONTINUOUS);

				wiiuse_set_report_type(wm);

				/* send request to wiimote for accelerometer calibration */
				buf = (byte*)malloc(sizeof(byte) * 8);
				wiiuse_read_data_cb(wm, wiiuse_handshake, buf, WM_MEM_OFFSET_CALIBRATION, 7);
				wm->handshake_state++;

				wiiuse_set_leds(wm, WIIMOTE_LED_NONE);

				break;
			}

		case 1: {
				struct read_req_t* req = wm->read_req;
				struct accel_t* accel = &wm->accel_calib;
				byte val;

				/* received read data */
				accel->cal_zero.x = req->buf[0];
				accel->cal_zero.y = req->buf[1];
				accel->cal_zero.z = req->buf[2];

				accel->cal_g.x = req->buf[4] - accel->cal_zero.x;
				accel->cal_g.y = req->buf[5] - accel->cal_zero.y;
				accel->cal_g.z = req->buf[6] - accel->cal_zero.z;

				/* done with the buffer */
				free(req->buf);

				/* handshake is done */
				WIIUSE_DEBUG("Handshake finished. Calibration: Idle: X=%x Y=%x Z=%x\t+1g: X=%x Y=%x Z=%x",
				             accel->cal_zero.x, accel->cal_zero.y, accel->cal_zero.z,
				             accel->cal_g.x, accel->cal_g.y, accel->cal_g.z);

				/* M+ off */
				val = 0x55;
				wiiuse_write_data_cb(wm, WM_EXP_MEM_ENABLE1, &val, 1, wiiuse_disable_motion_plus1);

				break;
			}

		case 2: {
				/* request the status of the wiimote to check for any expansion */
				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
				WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);
				wm->handshake_state++;

				/* now enable IR if it was set before the handshake completed */
				if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
					WIIUSE_DEBUG("Handshake finished, enabling IR.");
					WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
					wiiuse_set_ir(wm, 1);
				}

				wm->event = WIIUSE_CONNECT;
				wiiuse_status(wm);

				break;
			}

		default: {
				break;
			}
	}
}
Exemplo n.º 2
0
/**
 *	@brief	Read data from the wiimote (event version).
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param buffer	An allocated buffer to store the data as it arrives from the wiimote.
 *					Must be persistent in memory and large enough to hold the data.
 *	@param addr		The address of wiimote memory to read from.
 *	@param len		The length of the block to be read.
 *
 *	The library can only handle one data read request at a time
 *	because it must keep track of the buffer and other
 *	events that are specific to that request.  So if a request
 *	has already been made, subsequent requests will be added
 *	to a pending list and be sent out when the previous
 *	finishes.
 */
int wiiuse_read_data(struct wiimote_t* wm, byte* buffer, unsigned int addr, uint16_t len) {
	return wiiuse_read_data_cb(wm, NULL, buffer, addr, len);
}
Exemplo n.º 3
0
/**
 *	@brief Handle the handshake data from the nunchuk.
 *
 *	@param nc		A pointer to a nunchuk_t structure.
 *	@param data		The data read in from the device.
 *	@param len		The length of the data block, in bytes.
 *
 *	@return	Returns 1 if handshake was successful, 0 if not.
 */
int nunchuk_handshake(struct wiimote_t* wm, struct nunchuk_t* nc, byte* data, unsigned short len) {
	int i;
	int offset = 0;

	nc->btns = 0;
	nc->btns_held = 0;
	nc->btns_released = 0;

	/* set the smoothing to the same as the wiimote */
	nc->flags = &wm->flags;
	nc->accel_calib.st_alpha = wm->accel_calib.st_alpha;

	/* decrypt data */
	for (i = 0; i < len; ++i)
		data[i] = (data[i] ^ 0x17) + 0x17;

	if (data[offset] == 0xFF) {
		/*
		 *	Sometimes the data returned here is not correct.
		 *	This might happen because the wiimote is lagging
		 *	behind our initialization sequence.
		 *	To fix this just request the handshake again.
		 *
		 *	Other times it's just the first 16 bytes are 0xFF,
		 *	but since the next 16 bytes are the same, just use
		 *	those.
		 */
		if (data[offset + 16] == 0xFF) {
			/* get the calibration data */
			byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));

			WIIUSE_DEBUG("Nunchuk handshake appears invalid, trying again.");
			wiiuse_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);

			return 0;
		} else
			offset += 16;
	}

	nc->accel_calib.cal_zero.x = data[offset + 0];
	nc->accel_calib.cal_zero.y = data[offset + 1];
	nc->accel_calib.cal_zero.z = data[offset + 2];
	nc->accel_calib.cal_g.x = data[offset + 4];
	nc->accel_calib.cal_g.y = data[offset + 5];
	nc->accel_calib.cal_g.z = data[offset + 6];
	nc->js.max.x = data[offset + 8];
	nc->js.min.x = data[offset + 9];
	nc->js.center.x = data[offset + 10];
	nc->js.max.y = data[offset + 11];
	nc->js.min.y = data[offset + 12];
	nc->js.center.y = data[offset + 13];

	/* default the thresholds to the same as the wiimote */
	nc->orient_threshold = wm->orient_threshold;
	nc->accel_threshold = wm->accel_threshold;

	/* handshake done */
	wm->exp.type = EXP_NUNCHUK;

	#ifdef WIN32
	wm->timeout = WIIMOTE_DEFAULT_TIMEOUT;
	#endif

	return 1;
}
Exemplo n.º 4
0
Arquivo: io.c Projeto: admiral0/wiiuse
 /**
 *	@brief Get initialization data from the wiimote.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param data		unused
 *	@param len		unused
 *
 *	When first called for a wiimote_t structure, a request
 *	is sent to the wiimote for initialization information.
 *	This includes factory set accelerometer data.
 *	The handshake will be concluded when the wiimote responds
 *	with this data.
 */
void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) {
	if (!wm)	return;

	switch (wm->handshake_state) {
		case 0:
		{
			/* send request to wiimote for accelerometer calibration */
			byte* buf;

			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
			wiiuse_set_leds(wm, WIIMOTE_LED_NONE);

			buf = (byte*)malloc(sizeof(byte) * 8);
			wiiuse_read_data_cb(wm, wiiuse_handshake, buf, WM_MEM_OFFSET_CALIBRATION, 7);
			wm->handshake_state++;

			wiiuse_set_leds(wm, WIIMOTE_LED_NONE);

			break;
		}
		case 1:
		{
			struct read_req_t* req = wm->read_req;
			struct accel_t* accel = &wm->accel_calib;

			/* received read data */
			accel->cal_zero.x = req->buf[0];
			accel->cal_zero.y = req->buf[1];
			accel->cal_zero.z = req->buf[2];

			accel->cal_g.x = req->buf[4] - accel->cal_zero.x;
			accel->cal_g.y = req->buf[5] - accel->cal_zero.y;
			accel->cal_g.z = req->buf[6] - accel->cal_zero.z;

			/* done with the buffer */
			free(req->buf);

			/* handshake is done */
			WIIUSE_DEBUG("Handshake finished. Calibration: Idle: X=%x Y=%x Z=%x\t+1g: X=%x Y=%x Z=%x",
					accel->cal_zero.x, accel->cal_zero.y, accel->cal_zero.z,
					accel->cal_g.x, accel->cal_g.y, accel->cal_g.z);


			/* request the status of the wiimote to see if there is an expansion */
			wiiuse_status(wm);

			WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);
			wm->handshake_state++;

			/* now enable IR if it was set before the handshake completed */
			if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
				WIIUSE_DEBUG("Handshake finished, enabling IR.");
				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
				wiiuse_set_ir(wm, 1);
			}

			break;
		}
		default:
		{
			break;
		}
	}
}