700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > linux 玩安卓游戏手柄 Linux joystick 游戏手柄编程 (获取输入数据)

linux 玩安卓游戏手柄 Linux joystick 游戏手柄编程 (获取输入数据)

时间:2023-01-25 17:41:54

相关推荐

linux 玩安卓游戏手柄 Linux joystick 游戏手柄编程 (获取输入数据)

啥也不说了,先上代码:

由于linux中的list.h不能直接用,所以单独提取了出来使用:

//listop.h

/*itisfromlinuxlist*/

#ifndefLISTOP_H

#defineLISTOP_H

structlist_head{

structlist_head*next,*prev;

};

typedefstructlist_headlist_t;

#defineLIST_HEAD_INIT(name){&(name),&(name)}

#defineLIST_HEAD(name)\

structlist_headname=LIST_HEAD_INIT(name)

#defineINIT_LIST_HEAD(ptr)do{\

(ptr)->next=(ptr);(ptr)->prev=(ptr);\

}while(0)

/**

*list_add-addanewentry

*@new:newentrytobeadded

*@head:listheadtoadditafter

*

*Insertanewentryafterthespecifiedhead.

*Thisisgoodforimplementingstacks.

*/

voidlist_add(structlist_head*new,structlist_head*head);

/**

*list_add_tail-addanewentry

*@new:newentrytobeadded

*@head:listheadtoadditbefore

*

*Insertanewentrybeforethespecifiedhead.

*Thisisusefulforimplementingqueues.

*/

voidlist_add_tail(structlist_head*new,structlist_head*head);

/**

*list_del-deletesentryfromlist.

*@entry:theelementtodeletefromthelist.

*Note:list_emptyonentrydoesnotreturntrueafterthis,theentryisinanundefinedstate.

*/

voidlist_del(structlist_head*entry);

/**

*list_del_init-deletesentryfromlistandreinitializeit.

*@entry:theelementtodeletefromthelist.

*/

voidlist_del_init(structlist_head*entry);

/**

*list_move-deletefromonelistandaddasanother'shead

*@list:theentrytomove

*@head:theheadthatwillprecedeourentry

*/

voidlist_move(structlist_head*list,structlist_head*head);

/**

*list_move_tail-deletefromonelistandaddasanother'stail

*@list:theentrytomove

*@head:theheadthatwillfollowourentry

*/

voidlist_move_tail(structlist_head*list,

structlist_head*head);

/**

*list_splice-jointwolists

*@list:thenewlisttoadd.

*@head:theplacetoadditinthefirstlist.

*/

voidlist_splice(structlist_head*list,structlist_head*head);

/**

*list_empty-testswhetheralistisempty

*@head:thelisttotest.

*/

staticintlist_empty(structlist_head*head)

{

returnhead->next==head;

}

/**

*list_dequeue-dequeuetheheadofthelistiftherearemorethanoneentry

*@list:thelisttodequeue

*/

structlist_head*list_dequeue(structlist_head*list);

/**

*list_entry-getthestructforthisentry

*@ptr:the&structlist_headpointer.

*@type:thetypeofthestructthisisembeddedin.

*@member:thenameofthelist_structwithinthestruct.

*/

#definelist_entry(ptr,type,member)\

((type*)((char*)(ptr)-(unsignedlong)(&((type*)0)->member)))

/**

*list_for_each-iterateoveralist

*@pos:the&structlist_headtouseasaloopcounter.

*@head:theheadforyourlist.

*/

#definelist_for_each(pos,head)\

for(pos=(head)->next;pos!=(head);\

pos=pos->next)

/**

*list_for_each_safe-iterateoveralistsafeagainstremovaloflistentry

*@pos:the&structlist_headtouseasaloopcounter.

*@n:another&structlist_headtouseastemporarystorage

*@head:theheadforyourlist.

*/

#definelist_for_each_safe(pos,n,head)\

for(pos=(head)->next,n=pos->next;pos!=(head);\

pos=n,n=pos->next)

/**

*list_for_each_prev-iterateoveralistinreverseorder

*@pos:the&structlist_headtouseasaloopcounter.

*@head:theheadforyourlist.

*/

#definelist_for_each_prev(pos,head)\

for(pos=(head)->prev;pos!=(head);\

pos=pos->prev)

/**

*list_for_each_entry-iterateoverlistofgiventype

*@pos:thetype*touseasaloopcounter.

*@head:theheadforyourlist.

*@member:thenameofthelist_structwithinthestruct.

*/

#definelist_for_each_entry(pos,head,member)\

for(pos=list_entry((head)->next,typeof(*pos),member);\

&pos->member!=(head);\

pos=list_entry(pos->member.next,typeof(*pos),member))

#endif//listop.c

#include"listop.h"

staticvoid__check_head(structlist_head*head)

{

if((head->next==0)&&(head->prev==0)){

INIT_LIST_HEAD(head);

}

}

/*

*Insertanewentrybetweentwoknownconsecutiveentries.

*

*Thisisonlyforinternallistmanipulationwhereweknow

*theprev/nextentriesalready!

*/

staticvoid__list_add(structlist_head*new,

structlist_head*prev,

structlist_head*next)

{

next->prev=new;

new->next=next;

new->prev=prev;

prev->next=new;

}

/*

*Deletealistentrybymakingtheprev/nextentries

*pointtoeachother.

*

*Thisisonlyforinternallistmanipulationwhereweknow

*theprev/nextentriesalready!

*/

staticvoid__list_del(structlist_head*prev,

structlist_head*next)

{

next->prev=prev;

prev->next=next;

}

/**

*list_add-addanewentry

*@new:newentrytobeadded

*@head:listheadtoadditafter

*

*Insertanewentryafterthespecifiedhead.

*Thisisgoodforimplementingstacks.

*/

voidlist_add(structlist_head*new,structlist_head*head)

{

__check_head(head);

__list_add(new,head,head->next);

}

/**

*list_add_tail-addanewentry

*@new:newentrytobeadded

*@head:listheadtoadditbefore

*

*Insertanewentrybeforethespecifiedhead.

*Thisisusefulforimplementingqueues.

*/

voidlist_add_tail(structlist_head*new,structlist_head*head)

{

__check_head(head);

__list_add(new,head->prev,head);

}

/**

*list_del-deletesentryfromlist.

*@entry:theelementtodeletefromthelist.

*Note:list_emptyonentrydoesnotreturntrueafterthis,theentryisinanundefinedstate.

*/

voidlist_del(structlist_head*entry)

{

__list_del(entry->prev,entry->next);

}

/**

*list_del_init-deletesentryfromlistandreinitializeit.

*@entry:theelementtodeletefromthelist.

*/

voidlist_del_init(structlist_head*entry)

{

__list_del(entry->prev,entry->next);

INIT_LIST_HEAD(entry);

}

/**

*list_move-deletefromonelistandaddasanother'shead

*@list:theentrytomove

*@head:theheadthatwillprecedeourentry

*/

voidlist_move(structlist_head*list,structlist_head*head)

{

__check_head(head);

__list_del(list->prev,list->next);

list_add(list,head);

}

/**

*list_move_tail-deletefromonelistandaddasanother'stail

*@list:theentrytomove

*@head:theheadthatwillfollowourentry

*/

voidlist_move_tail(structlist_head*list,

structlist_head*head)

{

__check_head(head);

__list_del(list->prev,list->next);

list_add_tail(list,head);

}

/**

*list_splice-jointwolists

*@list:thenewlisttoadd.

*@head:theplacetoadditinthefirstlist.

*/

voidlist_splice(structlist_head*list,structlist_head*head)

{

structlist_head*first=list;

structlist_head*last=list->prev;

structlist_head*at=head->next;

first->prev=head;

head->next=first;

last->next=at;

at->prev=last;

}

structlist_head*list_dequeue(structlist_head*list){

structlist_head*next,*prev,*result=((void*)0);

prev=list;

next=prev->next;

if(next!=prev){

result=next;

next=next->next;

next->prev=prev;

prev->next=next;

result->prev=result->next=result;

}

returnresult;

}

主要的文件在这里:

//my_joystick.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//#include/*郁闷,不能直接使用linux自带的list链表,需要单独提取出来,见前面的code*/

#include"listop.h"

#if1

#defineLOG_DBG(fmt,...)fprintf(stdout,fmt,##__VA_ARGS__)

#else

#defineLOG_DBG(fmt,...)

#endif

#defineLOG_ERR(fmt,...)fprintf(stderr,fmt,##__VA_ARGS__)

typedefstruct_joy_stick_ctx{

structlist_headlist;

inti4_js_fd;

unsignedinti4_op_block;

}JOYSTICK_CTX_T;

LIST_HEAD(_t_js_ctx_head);

/*==>structlist_head_t_js_ctx_head={&_t_js_ctx_head,&_t_js_ctx_head};*/

intjoystick_open(char*cp_js_dev_name,inti4_block)

{

inti4_open_flags=O_RDONLY;

JOYSTICK_CTX_T*pt_joystick_ctx=NULL;

if(!cp_js_dev_name){

LOG_ERR("[%s]jsdevicenameisNULL\n",__func__);

return-1;

}

pt_joystick_ctx=(JOYSTICK_CTX_T*)calloc(sizeof(JOYSTICK_CTX_T),1);

if(!pt_joystick_ctx){

LOG_ERR("[%s]nomemory!!\n",__func__);

return-1;

}

pt_joystick_ctx->i4_op_block=i4_block?1:0;

if(pt_joystick_ctx->i4_op_block==0){

i4_open_flags|=O_NONBLOCK;

}

pt_joystick_ctx->i4_js_fd=open(cp_js_dev_name,i4_open_flags);

if(pt_joystick_ctx->i4_js_fd

LOG_ERR("[%s]opendevice%serror\n",__func__,cp_js_dev_name);

free(pt_joystick_ctx);

return-1;

}

list_add_tail(&pt_joystick_ctx->list,&_t_js_ctx_head);

returnpt_joystick_ctx->i4_js_fd;

}

intjoystick_close(inti4_fd)

{

structlist_head*pt_entry;

structlist_head*pt_next;

JOYSTICK_CTX_T*pt_node;

if(list_empty(&_t_js_ctx_head)){

LOG_ERR("[%s]devicenotopened\n",__func__);

return-1;

}

list_for_each_safe(pt_entry,pt_next,&_t_js_ctx_head){

pt_node=list_entry(pt_entry,JOYSTICK_CTX_T,list);

if(pt_node->i4_js_fd==i4_fd){

list_del_init(&pt_node->list);

free(pt_node);

returnclose(i4_fd);

}

}

LOG_ERR("[%s]i4_fd=%dinvalid\n",__func__,i4_fd);

return-1;

}

intjoystick_read_one_event(inti4_fd,structjs_event*tp_jse)

{

inti4_rd_bytes;

/*donotchecki4_fdagain*/

i4_rd_bytes=read(i4_fd,tp_jse,sizeof(structjs_event));

if(i4_rd_bytes==-1){

if(errno==EAGAIN){/*whennoblock,itisnoterror*/

return0;

}

else{

return-1;

}

}

returni4_rd_bytes;

}

intjoystick_read_ready(inti4_fd)

{

inti4_block=2;

structlist_head*pt_entry;

JOYSTICK_CTX_T*pt_node;

if(list_empty(&_t_js_ctx_head)){

LOG_ERR("[%s]devicenotopened\n",__func__);

return-1;

}

list_for_each(pt_entry,&_t_js_ctx_head){

pt_node=list_entry(pt_entry,JOYSTICK_CTX_T,list);

if(pt_node->i4_js_fd==i4_fd){

i4_block=pt_node->i4_op_block;

break;

}

}

if(i4_block==2){

LOG_ERR("[%s]i4_fd=%dinvalid\n",__func__,i4_fd);

return0;

}

elseif(i4_block==1){

fd_setreadfd;

inti4_ret=0;

structtimevaltimeout={0,0};

FD_ZERO(&readfd);

FD_SET(i4_fd,&readfd);

i4_ret=select(i4_fd+1,&readfd,NULL,NULL,&timeout);

if(i4_ret>0&&FD_ISSET(i4_fd,&readfd)){

return1;

}

else{

return0;

}

}

return1;/*noblockread,awaysready*/

}

voiddebug_list(void)

{

if(!list_empty(&_t_js_ctx_head)){

structlist_head*pt_entry;

JOYSTICK_CTX_T*pt_node;

list_for_each(pt_entry,&_t_js_ctx_head){

pt_node=list_entry(pt_entry,JOYSTICK_CTX_T,list);

LOG_DBG("fd:%d--block:%d\n",pt_node->i4_js_fd,pt_node->i4_op_block);

}

}

else{

LOG_DBG("----------->EMPTYNOW\n");

}

}

#if1

typedefstruct_axes_t{

intx;

inty;

}AXES_T;

intmain(intargc,char*argv[])

{

intfd,rc;

intop_times=0;

charnumber_of_axes=0;

charnumber_of_btns=0;

charjs_name_str[128];

unsignedintbuttons_state=0;

AXES_T*tp_axes=NULL;

inti,print_init_stat=0;

structjs_eventjse;

fd=joystick_open("/dev/input/js0",1);

if(fd

LOG_ERR("openfailed.\n");

exit(1);

}

rc=ioctl(fd,JSIOCGAXES,&number_of_axes);

if(rc!=-1){

LOG_DBG("number_of_axes:%d\n",number_of_axes);

if(number_of_axes>0){

tp_axes=(AXES_T*)calloc(sizeof(AXES_T),1);

}

}

rc=ioctl(fd,JSIOCGBUTTONS,&number_of_btns);

if(rc!=-1){

LOG_DBG("number_of_btns:%d\n",number_of_btns);

}

if(ioctl(fd,JSIOCGNAME(sizeof(js_name_str)),js_name_str)

LOG_DBG(js_name_str,"Unknown",sizeof(js_name_str));

}

LOG_DBG("joystickName:%s\n",js_name_str);

for(;;){

if(joystick_read_ready(fd)){

rc=joystick_read_one_event(fd,&jse);

if(rc>0){

if((jse.type&JS_EVENT_INIT)==JS_EVENT_INIT){

if((jse.type&~JS_EVENT_INIT)==JS_EVENT_BUTTON){

if(jse.value){

buttons_state|=(1<

}

else{

buttons_state&=~(1<

}

}

elseif((jse.type&~JS_EVENT_INIT)==JS_EVENT_AXIS){

if(tp_axes){

if((jse.number&1)==0){

tp_axes[jse.number/2].x=jse.value;

}

else{

tp_axes[jse.number/2].y=jse.value;

}

}

}

}

else{

op_times++;

if(print_init_stat==0){

for(i=0;i

LOG_DBG("joystickinitstate:button%dis%s.\n",i,((buttons_state&(1<

}

if(tp_axes)

for(i=0;i

LOG_DBG("joystickinitstate:axes%disx=%dy=%d.\n",i,tp_axes[i].x,tp_axes[i].y);

}

print_init_stat=1;

}

if(jse.type==JS_EVENT_BUTTON){

if(jse.value){

buttons_state|=(1<

}

else{

buttons_state&=~(1<

}

LOG_DBG("joystickstate:button%dis%s.\n",jse.number,((buttons_state&(1<

}

elseif(jse.type==JS_EVENT_AXIS){

if(tp_axes){

if((jse.number&1)==0){

tp_axes[jse.number/2].x=jse.value;

}

else{

tp_axes[jse.number/2].y=jse.value;

}

LOG_DBG("joystickstate:axes%disx=%dy=%d.\n",jse.number/2,tp_axes[jse.number/2].x,tp_axes[jse.number/2].y);

}

else{

LOG_DBG("joystickstate:axes%dis%s=%d.\n",jse.number/2,((jse.number&1)==0)?"x":"y",jse.value);

}

}

}

if(op_times>=18){

break;

}

}

}

usleep(1000);

}

joystick_close(fd);

if(tp_axes){

free(tp_axes);

}

return0;

}

#endif

编译: gcc -o my_joystick my_joystick.c listop.c

运行:

mayer@mayer-Ubuntu:hid$ ./my_joystick

number_of_axes:2

number_of_btns:10

joystick Name: BETOP GAMEPAD

joystick init state: button 0 is UP.

joystick init state: button 1 is UP.

joystick init state: button 2 is UP.

joystick init state: button 3 is UP.

joystick init state: button 4 is UP.

joystick init state: button 5 is UP.

joystick init state: button 6 is UP.

joystick init state: button 7 is UP.

joystick init state: button 8 is UP.

joystick init state: button 9 is UP.

joystick init state: axes 0 is x=0 y=0.

joystick init state: axes 1 is x=0 y=135129.

joystick state: button 0 is DOWN.

joystick state: button 0 is UP.

joystick state: button 1 is DOWN.

joystick state: button 1 is UP.

joystick state: button 3 is DOWN.

joystick state: button 3 is UP.

joystick state: button 2 is DOWN.

joystick state: button 2 is UP.

joystick state: button 7 is DOWN.

joystick state: button 7 is UP.

joystick state: button 5 is DOWN.

joystick state: button 5 is UP.

joystick state: button 6 is DOWN.

joystick state: button 6 is UP.

joystick state: button 4 is DOWN.

joystick state: button 4 is UP.

joystick state: button 5 is DOWN.

joystick state: button 5 is UP.

不明白的地方可以参考linux kernel中的说明文件:Documentation/input/joystick-api.txt

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。