root/trunk/orca/gl/joystick.c

Revision 144, 3.9 kB (checked in by krobillard, 3 years ago)

Native arguments are now kept on the stack until after the call and the
result is now always put into a1.

Line 
1//============================================================================
2//
3// joystick.c
4//
5// Copyright (C) 2005 Karl Robillard
6//
7//============================================================================
8
9
10#ifdef __linux__
11
12#include <stdlib.h>
13#include <fcntl.h>
14#include <errno.h>
15#include <stdio.h>
16#include <unistd.h>
17#include <linux/joystick.h>
18#include "gx.h"
19
20
21enum JoystickValue    // joystick object
22{
23    JV_NAME = 2,
24    JV_FD,
25    JV_AXIS_COUNT,
26    JV_BTN_COUNT,
27    JV_INPUT
28};
29
30
31static int jsOpen( OValue* a1, OContext* ctx )
32{
33    char* dev;
34    int fd;
35
36    if( ! orIs( a1, OT_WORD ) )
37        return 0;
38    if( a1->word.atom != gEnv.atom_joystick )
39        return 0;
40
41    dev = getenv( "JOYSTICK_DEV" );
42    if( ! dev )
43        //dev = "/dev/js0";
44        dev = "/dev/input/js0";
45
46    fd = open( dev, O_RDONLY | O_NONBLOCK );
47    if( fd >= 0 )
48    {
49        char buttons, axes;
50        char name[80];
51        OIndex i;
52        OBlock* blk;
53        OBlock* cblk;
54        OValue* val;
55        OValue* end;
56
57
58        val = orLookupPath( OT_WORD, orInternAtom( "joystick-port", 13 ),
59                            OR_LPATH_END );
60        if( ! val )
61            return 1;
62
63        orCloneObject( &val->ctx, ctx );
64        cblk = orBlockPtr( ctx->vblkN );
65
66        ioctl( fd, JSIOCGAXES, &axes );
67        ioctl( fd, JSIOCGBUTTONS, &buttons );
68        ioctl( fd, JSIOCGNAME(sizeof(name)), &name );
69
70        val = cblk->values + JV_FD;
71        orSetTF( val, OT_INTEGER );
72        orInt(val) = fd;
73
74        i = orMakeCString( name, -1 );
75        val = cblk->values + JV_NAME;
76        orSetTF( val, OT_STRING );
77        orSetSeries( val, i, 0 );
78
79        val = cblk->values + JV_AXIS_COUNT;
80        orSetTF( val, OT_INTEGER );
81        orInt(val) = axes;
82
83        val = cblk->values + JV_BTN_COUNT;
84        orSetTF( val, OT_INTEGER );
85        orInt(val) = buttons;
86
87        blk = orMakeBlock( axes + buttons );
88        blk->used = axes + buttons;
89        val = blk->values;
90        end = val + blk->used;
91        while( val != end )
92        {
93            orSetTF( val, OT_INTEGER );
94            orInt(val) = 0;
95            ++val;
96        }
97
98        val = cblk->values + JV_INPUT;
99        orSetTF( val, OT_BLOCK );
100        orSetSeries( val, orBlockN(blk), 0 );
101    }
102    else
103    {
104        orErrorT( OR_ERROR_ACCESS, "cannot open device %s", dev );
105    }
106
107    return 1;
108}
109
110
111static void jsClose( OContext* ctx )
112{
113    OBlock* vblk;
114    OValue* val;
115    int fd;
116
117    vblk = orBlockPtr( ctx->vblkN );
118    val = vblk->values + JV_FD;
119    if( orIs( val, OT_INTEGER ) )
120    {
121        fd = orInt(val);
122        if( fd > -1 )
123        {
124            close( fd );
125            orSetTF( val, OT_NONE );
126        }
127    }
128}
129
130
131/*
132  Set 'input block values.
133*/
134static void jsRead( OContext* ctx, OValue* a1 )
135{
136    int events = 0;
137    OBlock* vblk;
138    OValue* val;
139
140    vblk = orBlockPtr( ctx->vblkN );
141    val = vblk->values + JV_FD;
142
143    if( orIs( val, OT_INTEGER ) && (orInt(val) > -1) )
144    {
145        int axes;
146        int fd;
147        struct js_event je;
148        OBlock* blk;
149
150        fd = orInt(val);
151
152        val = vblk->values + JV_AXIS_COUNT;
153        axes = orInt(val);
154
155        val = vblk->values + JV_INPUT;
156        blk = orBLOCK(val);
157        val = blk->values;
158
159        while( read(fd, &je, sizeof(struct js_event)) > 0 )
160        {
161            if( je.type & JS_EVENT_BUTTON )
162            {
163                // je.value will be 0 or 1.
164
165                val[ je.number + axes ].integer = je.value;
166            }
167            else if( je.type & JS_EVENT_AXIS )
168            {
169                // je.value will be -32767 to +32767.
170
171                val[ je.number ].integer = je.value;
172            }
173            events = 1;
174        }
175
176        if( errno != EAGAIN )
177            perror( "Joystick read" );
178    }
179
180    orResult( OT_LOGIC, events );
181}
182
183
184static void jsWrite( OContext* ctx, OValue* a1 )
185{
186    (void) ctx;
187    (void) a1;
188}
189
190
191OPortDevice joystickPortDev =
192{
193    jsOpen,
194    jsClose,
195    jsRead,
196    jsWrite
197};
198
199
200#endif
201
202
203//EOF
Note: See TracBrowser for help on using the browser.