Ejemplo n.º 1
0
/**
 *	@brief Send the next pending data read request to the wiimote.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *
 *	@see wiiuse_read_data()
 *
 *	This function is not part of the wiiuse API.
 */
void wiiuse_send_next_pending_read_request(struct wiimote_t* wm) {
	byte buf[6];
	struct read_req_t* req;

	if (!wm || !WIIMOTE_IS_CONNECTED(wm)) {
		return;
	}
	if (!wm->read_req)	{
		return;
	}

	/* skip over dirty ones since they have already been read */
	req = wm->read_req;
	while (req && req->dirty) {
		req = req->next;
	}
	if (!req) {
		return;
	}

	/* the offset is in big endian */
	to_big_endian_uint32_t(buf, req->addr);

	/* the length is in big endian */
	to_big_endian_uint16_t(buf + 4, req->size);

	WIIUSE_DEBUG("Request read at address: 0x%x  length: %i", req->addr, req->size);
	wiiuse_send(wm, WM_CMD_READ_DATA, buf, 6);
}
Ejemplo n.º 2
0
/**
 *	@brief	Enable or disable the rumble.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param status	1 to enable, 0 to disable.
 */
void wiiuse_rumble(struct wiimote_t* wm, int status) {
	byte buf;

	if (!wm || !WIIMOTE_IS_CONNECTED(wm)) {
		return;
	}

	/* make sure to keep the current lit leds */
	buf = wm->leds;

	if (status) {
		WIIUSE_DEBUG("Starting rumble...");
		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
		buf |= 0x01;
	} else {
		WIIUSE_DEBUG("Stopping rumble...");
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
		buf &= ~(0x01);
	}

	/* preserve IR state */
	if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
		buf |= 0x04;
	}

	wiiuse_send(wm, WM_CMD_RUMBLE, &buf, 1);
}
Ejemplo n.º 3
0
/**
 *	@brief Request the wiimote controller status.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *
 *	Controller status includes: battery level, LED status, expansions
 */
void wiiuse_status(struct wiimote_t* wm) {
	byte buf = 0;

	if (!wm || !WIIMOTE_IS_CONNECTED(wm)) {
		return;
	}

	WIIUSE_DEBUG("Requested wiimote status.");

	wiiuse_send(wm, WM_CMD_CTRL_STATUS, &buf, 1);
}
Ejemplo n.º 4
0
/**
 *	@brief	Set the report type based on the current wiimote state.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *
 *	@return The report type sent.
 *
 *	The wiimote reports formatted packets depending on the
 *	report type that was last requested.  This function will
 *	update the type of report that should be sent based on
 *	the current state of the device.
 */
int wiiuse_set_report_type(struct wiimote_t* wm) {

    byte buf[2];
	int motion, exp, ir, balance_board;

	if (!wm || !WIIMOTE_IS_CONNECTED(wm)) {
		return 0;
	}

	buf[0] = (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_CONTINUOUS) ? 0x04 : 0x00);	/* set to 0x04 for continuous reporting */
	buf[1] = 0x00;

	/* if rumble is enabled, make sure we keep it */
	if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE)) {
		buf[0] |= 0x01;
	}

	motion = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC);
	exp = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP);
	ir = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR);
	balance_board = exp && (wm->exp.type == EXP_WII_BOARD);

	if (motion && ir && exp)	{
		buf[1] = WM_RPT_BTN_ACC_IR_EXP;
	} else if (motion && exp) {
		buf[1] = WM_RPT_BTN_ACC_EXP;
	} else if (motion && ir) {
		buf[1] = WM_RPT_BTN_ACC_IR;
	} else if (ir && exp) {
		buf[1] = WM_RPT_BTN_IR_EXP;
	} else if (ir) {
		buf[1] = WM_RPT_BTN_ACC_IR;
	} else if(exp && balance_board) {
        if(wm->exp.wb.use_alternate_report)
	        buf[1] = WM_RPT_BTN_EXP_8;
        else
            buf[1] = WM_RPT_BTN_EXP;
	} else if (exp) {
		buf[1] = WM_RPT_BTN_EXP;
	} else if (motion) {
		buf[1] = WM_RPT_BTN_ACC;
	} else {
		buf[1] = WM_RPT_BTN;
	}

	WIIUSE_DEBUG("Setting report type: 0x%x", buf[1]);

	exp = wiiuse_send(wm, WM_CMD_REPORT_TYPE, buf, 2);
	if (exp <= 0) {
		return exp;
	}

	return buf[1];
}
Ejemplo n.º 5
0
/**
 *	@brief	Set the enabled LEDs.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param leds		What LEDs to enable.
 *
 *	\a leds is a bitwise or of WIIMOTE_LED_1, WIIMOTE_LED_2, WIIMOTE_LED_3, or WIIMOTE_LED_4.
 */
void wiiuse_set_leds(struct wiimote_t* wm, int leds) {
	byte buf;

	if (!wm || !WIIMOTE_IS_CONNECTED(wm)) {
		return;
	}

	/* remove the lower 4 bits because they control rumble */
	wm->leds = (leds & 0xF0);

	/* make sure if the rumble is on that we keep it on */
	if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE)) {
		wm->leds |= 0x01;
	}

	buf = wm->leds;

	wiiuse_send(wm, WM_CMD_LED, &buf, 1);
}
Ejemplo n.º 6
0
/**
*    @brief Read memory/register data synchronously
*
*    @param wm        Pointer to a wiimote_t structure.
*    @param memory    If set to non-zero, reads EEPROM, otherwise registers
*    @param addr      Address offset to read from
*    @param size      How many bytes to read
*    @param data      Pre-allocated memory to store the received data
*
*    Synchronous/blocking read, this function will not return until it receives the specified
*    amount of data from the Wiimote.
*
*/
void wiiuse_read_data_sync(struct wiimote_t *wm, byte memory, unsigned addr, unsigned short size, byte *data) {
	byte pkt[6];
	byte buf[MAX_PAYLOAD];
	unsigned n_full_reports;
	unsigned last_report;
	byte *output;
	unsigned int i;

	/*
	 * address in big endian first, the leading byte will
	 * be overwritten (only 3 bytes are sent)
	 */
	to_big_endian_uint32_t(pkt, addr);

	/* read from registers or memory */
	pkt[0] = (memory != 0) ? 0x00 : 0x04;

	/* length in big endian */
	to_big_endian_uint16_t(pkt + 4, size);

	/* send */
	wiiuse_send(wm, WM_CMD_READ_DATA, pkt, sizeof(pkt));

	/* calculate how many 16B packets we have to get back */
	n_full_reports = size / 16;
	last_report = size % 16;
	output = data;

	for (i = 0; i < n_full_reports; ++i) {
		wiiuse_wait_report(wm, WM_RPT_READ, buf, MAX_PAYLOAD);
		memmove(output, buf + 6, 16);
		output += 16;
	}

	/* read the last incomplete packet */
	if (last_report) {
		wiiuse_wait_report(wm, WM_RPT_READ, buf, MAX_PAYLOAD);
		memmove(output, buf + 6, last_report);
	}
}
Ejemplo n.º 7
0
/**
 *	@brief	Write data to the wiimote.
 *
 *	@param wm			Pointer to a wiimote_t structure.
 *	@param addr			The address to write to.
 *	@param data			The data to be written to the memory location.
 *	@param len			The length of the block to be written.
 */
int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, const byte* data, byte len) {
	byte buf[21] = {0};		/* the payload is always 23 */

	byte * bufPtr = buf;
	if (!wm || !WIIMOTE_IS_CONNECTED(wm)) {
            WIIUSE_ERROR("Attempt to write, but no wiimote available or not connected!");
            return 0;
	}
	if (!data || !len) {
            WIIUSE_ERROR("Attempt to write, but no data or length == 0");
            return 0;
	}

	WIIUSE_DEBUG("Writing %i bytes to memory location 0x%x...", len, addr);

#ifdef WITH_WIIUSE_DEBUG
	{
		int i = 0;
		printf("Write data is: ");
		for (; i < len; ++i) {
			printf("%x ", data[i]);
		}
		printf("\n");
	}
#endif

	/* the offset is in big endian */
	buffer_big_endian_uint32_t(&bufPtr, (uint32_t)addr);

	/* length */
	buffer_big_endian_uint8_t(&bufPtr, len);

	/* data */
	memcpy(bufPtr, data, len);

	wiiuse_send(wm, WM_CMD_WRITE_DATA, buf, 21);
	return 1;
}
Ejemplo n.º 8
0
/**
 *	@brief	Set if the wiimote should track IR targets.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param status	1 to enable, 0 to disable.
 */
void wiiuse_set_ir(struct wiimote_t* wm, int status) {
	byte buf;
	char* block1 = NULL;
	char* block2 = NULL;
	int ir_level;

	if (!wm)
		return;

	/*
	 *	Wait for the handshake to finish first.
	 *	When it handshake finishes and sees that
	 *	IR is enabled, it will call this function
	 *	again to actually enable IR.
	 */
	if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE)) {
		if(status) {
			WIIUSE_DEBUG("Tried to enable IR, will wait until handshake finishes.");
			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR);
		} // else ignoring request to turn off, since it's turned off by default
		return;
	}

	/*
	 *	Check to make sure a sensitivity setting is selected.
	 */
	ir_level = get_ir_sens(wm, &block1, &block2);
	if (!ir_level) {
		WIIUSE_ERROR("No IR sensitivity setting selected.");
		return;
	}

	if (status) {
		/* if already enabled then stop */
		if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
			return;
		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR);
	} else {
		/* if already disabled then stop */
		if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
			return;
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
	}

	/* set camera 1 and 2 */
	buf = (status ? 0x04 : 0x00);
	wiiuse_send(wm, WM_CMD_IR, &buf, 1);
	wiiuse_send(wm, WM_CMD_IR_2, &buf, 1);

	if (!status) {
		WIIUSE_DEBUG("Disabled IR cameras for wiimote id %i.", wm->unid);
		wiiuse_set_report_type(wm);
		return;
	}

	/* enable IR, set sensitivity */
	buf = 0x08;
	wiiuse_write_data(wm, WM_REG_IR, &buf, 1);

	/* wait for the wiimote to catch up */
	#ifndef WIN32
		usleep(50000);
	#else
		Sleep(50);
	#endif

	/* write sensitivity blocks */
	wiiuse_write_data(wm, WM_REG_IR_BLOCK1, (byte*)block1, 9);
	wiiuse_write_data(wm, WM_REG_IR_BLOCK2, (byte*)block2, 2);

	/* set the IR mode */
	if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP))
		buf = WM_IR_TYPE_BASIC;
	else
		buf = WM_IR_TYPE_EXTENDED;
	wiiuse_write_data(wm, WM_REG_IR_MODENUM, &buf, 1);

	#ifndef WIN32
		usleep(50000);
	#else
		Sleep(50);
	#endif

	/* set the wiimote report type */
	wiiuse_set_report_type(wm);

	WIIUSE_DEBUG("Enabled IR camera for wiimote id %i (sensitivity level %i).", wm->unid, ir_level);
}