示例#1
0
int wiiuse_set_report_type(struct wiimote_t *wm,cmd_blk_cb cb)
{
	ubyte buf[2];
	int motion,ir,exp;

	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;

	motion = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC) || WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR);
	exp = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP);
	ir = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR);

	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)				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]);

	wiiuse_sendcmd(wm,WM_CMD_REPORT_TYPE,buf,2,cb);
	return buf[1];
}
示例#2
0
int wiiuse_write_data(struct wiimote_t *wm,uint addr,ubyte *data,ubyte len,cmd_blk_cb cb)
{
	struct op_t *op;
	struct cmd_blk_t *cmd;

	if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return 0;
	if(!data || !len) return 0;
	
	cmd = (struct cmd_blk_t*)__lwp_queue_get(&wm->cmdq);
	if(!cmd) return 0;

	cmd->cb = cb;
	cmd->len = 22;

	op = (struct op_t*)cmd->data;
	op->cmd = WM_CMD_WRITE_DATA;
	op->buffer = NULL;
	op->wait = 0;
	op->writedata.addr = BIG_ENDIAN_LONG(addr);
	op->writedata.size = (len&0x0f);
	memcpy(op->writedata.data,data,len);
	memset(op->writedata.data+len,0,(16 - len));
	__wiiuse_push_command(wm,cmd);

	return 1;
}
示例#3
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);
}
int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len) {
	DWORD bytes;
	int i;

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

	switch (wm->stack) {
		case WIIUSE_STACK_UNKNOWN:
		{
			/* try to auto-detect the stack type */
			if (i = WriteFile(wm->dev_handle, buf, 22, &bytes, &wm->hid_overlap)) {
				/* bluesoleil will always return 1 here, even if it's not connected */
				wm->stack = WIIUSE_STACK_BLUESOLEIL;
				return i;
			}

			if (i = HidD_SetOutputReport(wm->dev_handle, buf, len)) {
				wm->stack = WIIUSE_STACK_MS;
				return i;
			}

			WIIUSE_ERROR("Unable to determine bluetooth stack type.");
			return 0;
		}

		case WIIUSE_STACK_MS:
			return HidD_SetOutputReport(wm->dev_handle, buf, len);

		case WIIUSE_STACK_BLUESOLEIL:
			return WriteFile(wm->dev_handle, buf, 22, &bytes, &wm->hid_overlap);
	}

	return 0;
}
示例#5
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);
}
示例#6
0
void wiiuse_status(struct wiimote_t *wm,cmd_blk_cb cb)
{
	ubyte buf;

	if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return;
	
	buf = 0x00;
	wiiuse_sendcmd(wm,WM_CMD_CTRL_STATUS,&buf,1,cb);
}
示例#7
0
void wiiuse_set_leds(struct wiimote_t *wm,int leds,cmd_blk_cb cb)
{
	ubyte buf;

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

	wm->leds = (leds&0xf0);

	buf = wm->leds;
	wiiuse_sendcmd(wm,WM_CMD_LED,&buf,1,cb);
}
示例#8
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);
}
示例#9
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];
}
示例#10
0
int wiiuse_os_read(struct wiimote_t* wm, byte* buf, int len) {
	DWORD b, r;

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

	if (!ReadFile(wm->dev_handle, buf, len, &b, &wm->hid_overlap)) {
		/* partial read */
		b = GetLastError();

		if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) {
			/* remote disconnect */
			wiiuse_disconnected(wm);
			return 0;
		}

		r = WaitForSingleObject(wm->hid_overlap.hEvent, wm->timeout);
		if (r == WAIT_TIMEOUT) {
			/* timeout - cancel and continue */

			if (*buf) {
				WIIUSE_WARNING("Packet ignored.  This may indicate a problem (timeout is %i ms).", wm->timeout);
			}

			CancelIo(wm->dev_handle);
			ResetEvent(wm->hid_overlap.hEvent);
			return 0;
		} else if (r == WAIT_FAILED) {
			WIIUSE_WARNING("A wait error occurred on reading from wiimote %i.", wm->unid);
			return 0;
		}

		if (!GetOverlappedResult(wm->dev_handle, &wm->hid_overlap, &b, 0)) {
			return 0;
		}

		/* log the received data */
#ifdef WITH_WIIUSE_DEBUG
		{
			DWORD i;
			printf("[DEBUG] (id %i) RECV: (%.2x) ", wm->unid, buf[0]);
			for (i = 1; i < b; i++) {
				printf("%.2x ", buf[i]);
			}
			printf("\n");
		}
#endif
	}

	ResetEvent(wm->hid_overlap.hEvent);
	return 1;
}
示例#11
0
文件: io_nix.c 项目: C-Compton/OpenGL
/**
 *	@brief Disconnect a wiimote.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *
 *	@see wiic_connect()
 *
 *	Note that this will not free the wiimote structure.
 */
void wiic_disconnect( struct wiimote_t* wm ) {
  if ( !wm || !WIIMOTE_IS_CONNECTED(wm) ) return;
  
  close( wm->out_sock );
  close( wm->in_sock );
  
  wm->out_sock = -1;
  wm->in_sock = -1;
  wm->event = WIIC_NONE;
  
  WIIMOTE_DISABLE_STATE( wm, WIIMOTE_STATE_CONNECTED );
  WIIMOTE_DISABLE_STATE( wm, WIIMOTE_STATE_HANDSHAKE );
}
示例#12
0
short any_wiimote_connected(wiimote** wm, int wiimotes) {
	int i;
	if (!wm) {
		return 0;
	}

	for (i = 0; i < wiimotes; i++) {
		if (wm[i] && WIIMOTE_IS_CONNECTED(wm[i])) {
			return 1;
		}
	}

	return 0;
}
示例#13
0
void wiiuse_send_next_command(struct wiimote_t *wm)
{
	struct cmd_blk_t *cmd = wm->cmd_head;

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

	if(!cmd) return;
	if(cmd->state!=CMD_READY) return;

	cmd->state = CMD_SENT;
	if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_RUMBLE)) cmd->data[1] |= 0x01;

	wiiuse_io_write(wm,cmd->data,cmd->len);
}
void wiiuse_disconnect(struct wiimote_t* wm) {
	if (!wm || WIIMOTE_IS_CONNECTED(wm))
		return;

	CloseHandle(wm->dev_handle);
	wm->dev_handle = 0;

	ResetEvent(&wm->hid_overlap);

	wm->event = WIIUSE_NONE;

	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
}
bool FWiimoteInputDevice::AnyWiimoteConnected() const
{
    if (!GWiimotes)
    {
        return false;
    }

    for (int i = 0; i < MAX_WIIMOTES; i++)
    {
        if (GWiimotes[i] && WIIMOTE_IS_CONNECTED(GWiimotes[i]))
        {
            return true;
        }
    }

    return false;
}
示例#16
0
/**
 *	@brief	Read data from the wiimote (callback version).
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param read_cb	Function pointer to call when the data arrives from the wiimote.
 *	@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_cb(struct wiimote_t* wm, wiiuse_read_cb read_cb, byte* buffer, unsigned int addr, uint16_t len) {
	struct read_req_t* req;

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

	/* make this request structure */
	req = (struct read_req_t*)malloc(sizeof(struct read_req_t));
	if (req == NULL) {
		return 0;
	}
	req->cb = read_cb;
	req->buf = buffer;
	req->addr = addr;
	req->size = len;
	req->wait = len;
	req->dirty = 0;
	req->next = NULL;

	/* add this to the request list */
	if (!wm->read_req) {
		/* root node */
		wm->read_req = req;

		WIIUSE_DEBUG("Data read request can be sent out immediately.");

		/* send the request out immediately */
		wiiuse_send_next_pending_read_request(wm);
	} else {
		struct read_req_t* nptr = wm->read_req;
		for (; nptr->next; nptr = nptr->next) {
			;
		}
		nptr->next = req;

		WIIUSE_DEBUG("Added pending data read request.");
	}

	return 1;
}
示例#17
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);
}
示例#18
0
int wiiuse_write_streamdata(struct wiimote_t *wm,ubyte *data,ubyte len,cmd_blk_cb cb)
{
	struct cmd_blk_t *cmd;

	if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return 0;
	if(!data || !len || len>20) return 0;

	cmd = (struct cmd_blk_t*)__lwp_queue_get(&wm->cmdq);
	if(!cmd) return 0;

	cmd->cb = cb;
	cmd->len = 22;
	cmd->data[0] = WM_CMD_STREAM_DATA;
	cmd->data[1] = (len<<3);
	memcpy(cmd->data+2,data,len);
	__wiiuse_push_command(wm,cmd);

	return 1;
}
示例#19
0
/**
 *	@brief	Write data to the wiimote (callback version).
 *
 *	@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.
 *	@param cb			Function pointer to call when the data arrives from the wiimote.
 *
 *	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_write_data_cb(struct wiimote_t *wm, unsigned int addr, byte *data, byte len, wiiuse_write_cb write_cb) {
	struct data_req_t* req;

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

	req = (struct data_req_t*)malloc(sizeof(struct data_req_t));
	req->cb = write_cb;
	req->len = len;
	memcpy(req->data, data, req->len);
	req->state = REQ_READY;
	req->addr = addr;/* BIG_ENDIAN_LONG(addr); */
	req->next = NULL;
	/* add this to the request list */
	if (!wm->data_req) {
		/* root node */
		wm->data_req = req;

		WIIUSE_DEBUG("Data write request can be sent out immediately.");

		/* send the request out immediately */
		wiiuse_send_next_pending_write_request(wm);
	} else {
		struct data_req_t* nptr = wm->data_req;
		WIIUSE_DEBUG("chaud2fois");
		for (; nptr->next; nptr = nptr->next) {
			;
		}
		nptr->next = req;

		WIIUSE_DEBUG("Added pending data write request.");
	}

	return 1;
}
示例#20
0
/**
 *	@brief Send the next pending data write request to the wiimote.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *
 *	@see wiiuse_write_data()
 *
 *	This function is not part of the wiiuse API.
 */
void wiiuse_send_next_pending_write_request(struct wiimote_t* wm) {
	struct data_req_t* req;

	if (!wm || !WIIMOTE_IS_CONNECTED(wm)) {
		return;
	}
	req = wm->data_req;
	if (!req) {
		return;
	}
	if (!req->data || !req->len) {
		return;
	}
	if (req->state != REQ_READY) {
		return;
	}

	wiiuse_write_data(wm, req->addr, req->data, req->len);

	req->state = REQ_SENT;
	return;
}
int wiiuse_io_read(struct wiimote_t* wm) {
	DWORD b, r;

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

	if (!ReadFile(wm->dev_handle, wm->event_buf, sizeof(wm->event_buf), &b, &wm->hid_overlap)) {
		/* partial read */
		b = GetLastError();

		if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) {
			/* remote disconnect */
			wiiuse_disconnected(wm);
			return 0;
		}

		r = WaitForSingleObject(wm->hid_overlap.hEvent, wm->timeout);
		if (r == WAIT_TIMEOUT) {
			/* timeout - cancel and continue */

			if (*wm->event_buf)
				WIIUSE_WARNING("Packet ignored.  This may indicate a problem (timeout is %i ms).", wm->timeout);

			CancelIo(wm->dev_handle);
			ResetEvent(wm->hid_overlap.hEvent);
			return 0;
		} else if (r == WAIT_FAILED) {
			WIIUSE_WARNING("A wait error occured on reading from wiimote %i.", wm->unid);
			return 0;
		}

		if (!GetOverlappedResult(wm->dev_handle, &wm->hid_overlap, &b, 0))
			return 0;
	}

	ResetEvent(wm->hid_overlap.hEvent);
	return 1;
}
示例#22
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;
}
示例#23
0
int wiiuse_read_data(struct wiimote_t *wm,ubyte *buffer,uint addr,uword len,cmd_blk_cb cb)
{
	struct op_t *op;
	struct cmd_blk_t *cmd;

	if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return 0;
	if(!buffer || !len) return 0;
	
	cmd = (struct cmd_blk_t*)__lwp_queue_get(&wm->cmdq);
	if(!cmd) return 0;

	cmd->cb = cb;
	cmd->len = 7;

	op = (struct op_t*)cmd->data;
	op->cmd = WM_CMD_READ_DATA;
	op->buffer = buffer;
	op->wait = len;
	op->readdata.addr = BIG_ENDIAN_LONG(addr);
	op->readdata.size = BIG_ENDIAN_SHORT(len);
	__wiiuse_push_command(wm,cmd);

	return 1;
}
示例#24
0
文件: os_nix.c 项目: Freso/wiiuse
int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) {
	int evnt;
	struct timeval tv;
	fd_set fds;
	int r;
	int i;
	byte read_buffer[MAX_PAYLOAD];
	int highest_fd = -1;

	evnt = 0;
	if (!wm) {
		return 0;
	}

	/* block select() for 1/2000th of a second */
	tv.tv_sec = 0;
	tv.tv_usec = 500;

	FD_ZERO(&fds);

	for (i = 0; i < wiimotes; ++i) {
		/* only poll it if it is connected */
		if (WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_CONNECTED)) {
			FD_SET(wm[i]->in_sock, &fds);

			/* find the highest fd of the connected wiimotes */
			if (wm[i]->in_sock > highest_fd) {
				highest_fd = wm[i]->in_sock;
			}
		}

		wm[i]->event = WIIUSE_NONE;
	}

	if (highest_fd == -1)
		/* nothing to poll */
	{
		return 0;
	}

	if (select(highest_fd + 1, &fds, NULL, NULL, &tv) == -1) {
		WIIUSE_ERROR("Unable to select() the wiimote interrupt socket(s).");
		perror("Error Details");
		return 0;
	}

	/* check each socket for an event */
	for (i = 0; i < wiimotes; ++i) {
		/* if this wiimote is not connected, skip it */
		if (!WIIMOTE_IS_CONNECTED(wm[i])) {
			continue;
		}

		if (FD_ISSET(wm[i]->in_sock, &fds)) {
			/* clear out the event buffer */
			memset(read_buffer, 0, sizeof(read_buffer));

			/* clear out any old read data */
			clear_dirty_reads(wm[i]);

			/* read the pending message into the buffer */
			r = wiiuse_os_read(wm[i], read_buffer, sizeof(read_buffer));
			if (r > 0) {
				/* propagate the event */
				propagate_event(wm[i], read_buffer[0], read_buffer + 1);
				evnt += (wm[i]->event != WIIUSE_NONE);
			}
		} else {
			/* send out any waiting writes */
			wiiuse_send_next_pending_write_request(wm[i]);
			idle_cycle(wm[i]);
		}
	}

	return evnt;
}
示例#25
0
/**
 *	@brief Connect to a wiimote with a known address.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param address	The address of the device to connect to.
 *					If NULL, use the address in the struct set by wiiuse_find().
 *
 *	@return 1 on success, 0 on failure
 */
static int wiiuse_connect_single(struct wiimote_t* wm, char* address)
{
	struct sockaddr_l2 addr={0} ;
  //char dest[18]="00:25:A0:B0:96:8A" ;

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

	wm->out_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
	if (wm->out_sock == -1)
		return 0;

	addr.l2_family = AF_BLUETOOTH;
	addr.l2_psm = htobs(WM_OUTPUT_CHANNEL); // =0x11, le port -> Wiimote.
	//str2ba(dest, &addr.l2_bdaddr) ;

	if( address )
		// Use provided address.
		str2ba(address, &addr.l2_bdaddr) ;
	else
		// Use address of device discovered.
		str2ba(wm->bdaddr_str, &addr.l2_bdaddr) ;

	/*
	 *	OUTPUT CHANNEL
	 */
	
	/* connect to wiimote */
  if( connect(wm->out_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0 )
	{
		perror("connect() output sock");
		return 0;
	}

	/*
	 *	INPUT CHANNEL
	 */
	wm->in_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
	if (wm->in_sock == -1)
  {
		close(wm->out_sock);
		wm->out_sock = -1;
		return 0;
	}

	addr.l2_psm = htobs(WM_INPUT_CHANNEL);

	/* connect to wiimote */
	if ( connect(wm->in_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
	{
		perror("connect() interrupt sock");
		close(wm->out_sock);
		wm->out_sock = -1;
		return 0;
	}

	WIIUSE_INFO("Connected to wiimote [id %i].", wm->unid);

	/* do the handshake */
	WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
	wiiuse_handshake(wm, NULL, 0);

	wiiuse_set_report_type(wm);

	return 1;
}
void FWiimoteInputDevice::SendControllerEvents()
{
    /*
    *   Maybe I'm interested in the battery power of the 0th
    *   wiimote.  This should be WIIMOTE_ID_1 but to be sure
    *   you can get the wiimote associated with WIIMOTE_ID_1
    *   using the wiiuse_get_by_id() function.
    *
    *   A status request will return other things too, like
    *   if any expansions are plugged into the wiimote or
    *   what LEDs are lit.
    */
    /* wiiuse_status(wiimotes[0]); */

    /*
    *   This is the main loop
    *
    *   wiiuse_poll() needs to be called with the wiimote array
    *   and the number of wiimote structures in that array
    *   (it doesn't matter if some of those wiimotes are not used
    *   or are not connected).
    *
    *   This function will set the event flag for each wiimote
    *   when the wiimote has things to report.
    */
    if (AnyWiimoteConnected())
    {
        if (wiiuse_poll(GWiimotes, MAX_WIIMOTES))
        {
            /*
            *   This happens if something happened on any wiimote.
            *   So go through each one and check if anything happened.
            */
            const double CurrentTime = FPlatformTime::Seconds();
            for (int i = 0; i < MAX_WIIMOTES; ++i)
            {
                FControllerState& ControllerState = ControllerStates[i];
                ControllerState.Wiimote = GWiimotes[i];
                if (ControllerState.Wiimote && WIIMOTE_IS_CONNECTED(ControllerState.Wiimote))
                {
                    // Check Analog state
                    if (ControllerState.Wiimote->exp.type == EXP_NUNCHUK ||
                        ControllerState.Wiimote->exp.type == EXP_MOTION_PLUS_NUNCHUK)
                    {
                        /* nunchuk */
                        struct nunchuk_t* nc = (nunchuk_t*)&ControllerState.Wiimote->exp.nunchuk;

                        if (ControllerState.LeftXAnalog != nc->js.x)
                        {
                            MessageHandler->OnControllerAnalog(FGamepadKeyNames::LeftAnalogX, ControllerState.ControllerId, nc->js.x);
                            ControllerState.LeftXAnalog = nc->js.x;
                        }

                        if (ControllerState.LeftYAnalog != nc->js.y)
                        {
                            MessageHandler->OnControllerAnalog(FGamepadKeyNames::LeftAnalogY, ControllerState.ControllerId, nc->js.y);
                            ControllerState.LeftYAnalog = nc->js.y;
                        }
                    }
                }

                FMemory::Memzero(CurrentStates);

                switch (ControllerState.Wiimote->event)
                {
                case WIIUSE_EVENT:
                    /* a generic event occurred */
                    handle_event(ControllerState.Wiimote, i);
                    break;

                case WIIUSE_STATUS:
                    /* a status event occurred */
                    handle_ctrl_status(ControllerState.Wiimote, i);
                    break;

                case WIIUSE_DISCONNECT:
                case WIIUSE_UNEXPECTED_DISCONNECT:
                    /* the wiimote disconnected */
                    handle_disconnect(ControllerState.Wiimote, i);
                    break;

                case WIIUSE_READ_DATA:
                    /*
                    *   Data we requested to read was returned.
                    *   Take a look at ControllerState.Wiimote>read_req
                    *   for the data.
                    */
                    break;

                case WIIUSE_NUNCHUK_INSERTED:
                    /*
                    *   a nunchuk was inserted
                    *   This is a good place to set any nunchuk specific
                    *   threshold values.  By default they are the same
                    *   as the wiimote.
                    */
                    /* wiiuse_set_nunchuk_orient_threshold((struct nunchuk_t*)&wiimotes[i]->exp.nunchuk, 90.0f); */
                    /* wiiuse_set_nunchuk_accel_threshold((struct nunchuk_t*)&wiimotes[i]->exp.nunchuk, 100); */
                    UE_LOG(LogWiimote, Log, TEXT("Nunchuk inserted."));
                    break;

                case WIIUSE_MOTION_PLUS_ACTIVATED:
                    UE_LOG(LogWiimote, Log, TEXT("Motion+ was activated"));
                    break;

                case WIIUSE_NUNCHUK_REMOVED:
                case WIIUSE_MOTION_PLUS_REMOVED:
                    /* some expansion was removed */
                    handle_ctrl_status(ControllerState.Wiimote, i);
                    UE_LOG(LogWiimote, Log, TEXT("An expansion was removed."));
                    break;

                default:
                    break;
                }

                // For each button check against the previous state and send the correct message if any
                for (int32 ButtonIndex = 0; ButtonIndex < MAX_NUM_WIIMOTE_BUTTONS; ++ButtonIndex)
                {
                    if (CurrentStates[ButtonIndex] != ControllerState.ButtonStates[ButtonIndex])
                    {
                        if (CurrentStates[ButtonIndex])
                        {
                            MessageHandler->OnControllerButtonPressed(Buttons[ButtonIndex], ControllerState.ControllerId, false);
                        }
                        else
                        {
                            MessageHandler->OnControllerButtonReleased(Buttons[ButtonIndex], ControllerState.ControllerId, false);
                        }

                        if (CurrentStates[ButtonIndex] != 0)
                        {
                            // this button was pressed - set the button's NextRepeatTime to the InitialButtonRepeatDelay
                            ControllerState.NextRepeatTime[ButtonIndex] = CurrentTime + InitialButtonRepeatDelay;
                        }
                    }
                    else if (CurrentStates[ButtonIndex] != 0 && ControllerState.NextRepeatTime[ButtonIndex] <= CurrentTime)
                    {
                        MessageHandler->OnControllerButtonPressed(Buttons[ButtonIndex], ControllerState.ControllerId, true);

                        // set the button's NextRepeatTime to the ButtonRepeatDelay
                        ControllerState.NextRepeatTime[ButtonIndex] = CurrentTime + ButtonRepeatDelay;
                    }

                    // Update the state for next time
                    ControllerState.ButtonStates[ButtonIndex] = CurrentStates[ButtonIndex];
                }

            }
        }
    }
}
示例#27
0
/**
 *	@brief Connect to a wiimote with a known address.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param address	The address of the device to connect to.
 *					If NULL, use the address in the struct set by wiic_find().
 *
 *	@return 1 on success, 0 on failure
 */
static int wiic_connect_single(struct wiimote_t* wm, char* address) {
    struct sockaddr_l2 addr;
    memset(&addr, 0, sizeof(addr));

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

    addr.l2_family = AF_BLUETOOTH;

    if (address)
        /* use provided address */
        str2ba(address, &addr.l2_bdaddr);
    else
        /* use address of device discovered */
        addr.l2_bdaddr = wm->bdaddr;

    /*
     *	OUTPUT CHANNEL
     */
    wm->out_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
    if (wm->out_sock == -1)
        return 0;

    addr.l2_psm = htobs(WM_OUTPUT_CHANNEL);

    /* connect to wiimote */
    if (connect(wm->out_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("connect() output sock");
        return 0;
    }

    /*
     *	INPUT CHANNEL
     */
    wm->in_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
    if (wm->in_sock == -1) {
        close(wm->out_sock);
        wm->out_sock = -1;
        return 0;
    }

    addr.l2_psm = htobs(WM_INPUT_CHANNEL);

    /* connect to wiimote */
    if (connect(wm->in_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("connect() interrupt sock");
        close(wm->out_sock);
        wm->out_sock = -1;
        return 0;
    }

    WIIC_INFO("Connected to wiimote [id %i].", wm->unid);

    /* do the handshake */
    WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
    wiic_handshake(wm, NULL, 0);

    wiic_set_report_type(wm);

    return 1;
}
示例#28
0
/**
 * Launch wiimote detection and add the corresponding gamepad devices to the
 * device manager.
 * TODO: this should be done in a separate thread, to not block the UI...
 */
void WiimoteManager::launchDetection(int timeout)
{
  // It's only needed on systems with bluez, because wiiuse_find does not find alredy connected wiimotes
#ifdef WIIUSE_BLUEZ
    //Cleans up the config and the disconnected wiimotes
    int number_previous_wiimotes = 0;
    wiimote_t** previous_wiimotes = (wiimote_t**) malloc(sizeof(struct wiimote_t*) * MAX_WIIMOTES);
    memset(previous_wiimotes,0,sizeof(struct wiimote_t*) * MAX_WIIMOTES);
    for (unsigned int i = 0; i < m_wiimotes.size(); i++)
    {
      if (WIIMOTE_IS_CONNECTED(m_all_wiimote_handles[i]))
      {
        previous_wiimotes[i]=m_all_wiimote_handles[i];
        m_all_wiimote_handles[i] = NULL;
        number_previous_wiimotes++;
      }
    }

    //To prevent segmentation fault, have to delete NULLs
    wiimote_t** deletable_wiimotes = (wiimote_t**) malloc(sizeof(struct wiimote_t*) * (m_wiimotes.size()-number_previous_wiimotes));
    memset(deletable_wiimotes,0,sizeof(struct wiimote_t*) * (m_wiimotes.size()-number_previous_wiimotes));
    int number_deletables = 0;
    for (unsigned int i = 0; i < m_wiimotes.size(); i++)
    {
      if (m_all_wiimote_handles[i] != NULL)
      {
        deletable_wiimotes[number_deletables++] = m_all_wiimote_handles[i];
      }
    }
    m_all_wiimote_handles = wiiuse_init(MAX_WIIMOTES);
    wiiuse_cleanup(deletable_wiimotes, number_deletables);

#endif

    // Stop WiiUse, remove wiimotes, gamepads, gamepad configs.
    cleanup();

    m_all_wiimote_handles = wiiuse_init(MAX_WIIMOTES);

    // Detect wiimotes
    int nb_found_wiimotes = wiiuse_find(m_all_wiimote_handles, MAX_WIIMOTES, timeout);

#ifndef WIIUSE_BLUEZ
    // Couldn't find any wiimote?
    if(nb_found_wiimotes == 0)
        return;
#endif

#ifdef WIIUSE_BLUEZ
    // Couldn't find any wiimote?
    if(nb_found_wiimotes + number_previous_wiimotes == 0)
        return;
#endif

    // Try to connect to all found wiimotes
    int nb_wiimotes = wiiuse_connect(m_all_wiimote_handles, nb_found_wiimotes);

#ifndef WIIUSE_BLUEZ
    // Couldn't connect to any wiimote?
    if(nb_wiimotes == 0)
        return;
#endif

#ifdef WIIUSE_BLUEZ
    // Couldn't connect to any wiimote?
    if(nb_wiimotes + number_previous_wiimotes == 0)
        return;

    //Merges previous and new wiimote's list
    int number_merged_wiimotes = 0;
    for (int i = 0; i < number_previous_wiimotes && i + nb_wiimotes < MAX_WIIMOTES; i++)
    {
      m_all_wiimote_handles[i+nb_wiimotes] = previous_wiimotes[i];
      previous_wiimotes[i] = NULL;
      m_all_wiimote_handles[i]->unid = nb_wiimotes+i+1;
      number_merged_wiimotes++;
    }
    nb_wiimotes += number_merged_wiimotes;

    //To prevent segmentation fault, have to delete NULLs
    number_deletables = 0;
    deletable_wiimotes = (wiimote_t**) malloc(sizeof(struct wiimote_t*) * (number_previous_wiimotes-number_merged_wiimotes));
    memset(deletable_wiimotes,0,sizeof(struct wiimote_t*) * (number_previous_wiimotes-number_merged_wiimotes));
    for (int i = 0; i < number_previous_wiimotes; i++)
    {
      if (previous_wiimotes[i] != NULL)
      {
        deletable_wiimotes[number_deletables++] = previous_wiimotes[i];
      }
    }
    // Cleans up wiimotes which ones didn't fit in limit
    wiiuse_cleanup(deletable_wiimotes, number_deletables);

#endif

    // ---------------------------------------------------
    // Create or find a GamepadConfig for all wiimotes
    DeviceManager* device_manager = input_manager->getDeviceManager();
    GamepadConfig* gamepad_config = NULL;

    device_manager->getConfigForGamepad(WIIMOTE_START_IRR_ID, "Wiimote",
                                        &gamepad_config);
    int num_buttons = (int)( log((float)WIIMOTE_BUTTON_ALL) / log((float)2.0f))+1;
    gamepad_config->setNumberOfButtons(num_buttons);
    gamepad_config->setNumberOfAxis(1);

    setWiimoteBindings(gamepad_config);

    // Initialize all Wiimotes, which in turn create their
    // associated GamePadDevices
    for(int i=0 ; i < nb_wiimotes ; i++)
    {
        m_wiimotes.push_back(new Wiimote(m_all_wiimote_handles[i], i,
                                         gamepad_config              ));
    } // end for

    // ---------------------------------------------------
    // Set the LEDs and rumble for 0.2s
    int leds[] = {WIIMOTE_LED_1, WIIMOTE_LED_2, WIIMOTE_LED_3, WIIMOTE_LED_4};
    for(unsigned int i=0 ; i < m_wiimotes.size(); i++)
    {
        wiimote_t*  wiimote_handle = m_wiimotes[i]->getWiimoteHandle();
        wiiuse_set_leds(wiimote_handle, leds[i]);
        wiiuse_rumble(wiimote_handle, 1);
    }

    StkTime::sleep(200);

    for(unsigned int i=0 ; i < m_wiimotes.size(); i++)
    {
        wiimote_t*  wiimote_handle = m_wiimotes[i]->getWiimoteHandle();
        wiiuse_rumble(wiimote_handle, 0);
    }

    // TODO: only enable accelerometer during race
    enableAccelerometer(true);

    // ---------------------------------------------------
    // Launch the update thread
#ifdef WIIMOTE_THREADING
    m_shut = false;
    pthread_create(&m_thread, NULL, &threadFuncWrapper, this);
#endif
}   // launchDetection