xref: /haiku/headers/private/device/joystick_driver.h (revision 1a76488fc88584bf66b9751d7fb9b6527ac20d87)
1 /*
2 	Copyright 1999, Be Incorporated.   All Rights Reserved.
3 	This file may be used under the terms of the Be Sample Code License.
4 */
5 
6 #ifndef _JOYSTICK_DRIVER_H
7 #define _JOYSTICK_DRIVER_H
8 
9 #include <stdlib.h>
10 
11 #include <SupportDefs.h>
12 #include <Drivers.h>
13 #include <module.h>
14 
15 typedef struct _joystick {
16 	bigtime_t	timestamp;
17 	uint32		horizontal;
18 	uint32		vertical;
19 	bool		button1;
20 	bool		button2;
21 } joystick;
22 
23 /* maximum number of axes on one controller (pads count as 2 axes each) */
24 #define MAX_AXES 12
25 /* maximum number of hats on one controller -- PADS SHOULD BE RETURNED AS AXES! */
26 #define MAX_HATS 8
27 /* maximum number of buttons on one controller */
28 #define MAX_BUTTONS 32
29 /* maximum number of controllers on one port */
30 #define MAX_STICKS 4
31 
32 typedef struct _extended_joystick {
33 	bigtime_t	timestamp;		/* system_time when it was read */
34 	uint32		buttons;		/* lsb to msb, 1 == on */
35 	int16		axes[MAX_AXES];	/* -32768 to 32767, X, Y, Z, U, V, W */
36 	uint8		hats[MAX_HATS];	/* 0 through 8 (1 == N, 3 == E, 5 == S, 7 == W) */
37 } _PACKED extended_joystick;
38 
39 
40 // This is a helper structure to manage variably sized data. It is here to
41 // make storing and accessing the flat data in the "data" member easier. When
42 // transferring data via read/write/ioctl only the flat data in "data" is ever
43 // transmitted, not the whole structure.
44 typedef struct _variable_joystick {
45 #ifdef __cplusplus
46 	status_t initialize(uint32 axisCount, uint32 hatCount, uint32 buttonCount)
47 	{
48 		axis_count = axisCount;
49 		hat_count = hatCount;
50 		button_blocks = (buttonCount + 31) / 32;
51 
52 		data_size = sizeof(bigtime_t)			// timestamp
53 			+ button_blocks * sizeof(uint32)	// bitmaps
54 			+ axis_count * sizeof(int16)		// axis values
55 			+ hat_count * sizeof(uint8);		// hat values
56 
57 		data = (uint8 *)malloc(data_size);
58 		if (data == NULL)
59 			return B_NO_MEMORY;
60 
61 		// fill in the convenience pointers
62 		timestamp = (bigtime_t *)data;
63 		buttons = (uint32 *)&timestamp[1];
64 		axes = (int16 *)&buttons[button_blocks];
65 		hats = (uint8 *)&axes[axis_count];
66 		return B_OK;
67 	}
68 
69 	status_t initialize_to_extended_joystick()
70 	{
71 		return initialize(MAX_AXES, MAX_HATS, MAX_BUTTONS);
72 	}
73 #endif
74 
75 	uint32		axis_count;
76 	uint32		hat_count;
77 	uint32		button_blocks;
78 		// count of 32 bit button bitmap blocks == (button_count + 31) / 32
79 
80 	// These pointers all point into the data section and are here for
81 	// convenience. They need to be set up manually by the one who creates this
82 	// structure or by using the initialize() method.
83 	bigtime_t *	timestamp;
84 	uint32 *	buttons;
85 	int16 *		axes;
86 	uint8 *		hats;
87 
88 	// The data is always structured in the following way (see extended_joystick
89 	// for data interpretation):
90 	//		bigtime_t	timestamp;
91 	//		uint32		button_bitmap_blocks[button_blocks];
92 	//		int16		axes[axis_count];
93 	//		uint8		hats[hat_count];
94 	size_t		data_size;
95 	uint8 *		data;
96 } variable_joystick;
97 
98 
99 #define MAX_CONFIG_SIZE 100
100 
101 enum {	/* flags for joystick module info */
102 	js_flag_force_feedback = 0x1,
103 	js_flag_force_feedback_directional = 0x2,
104 	js_flag_variable_size_reads = 0x4
105 };
106 
107 typedef struct _joystick_module_info {
108 	char			module_name[64];
109 	char			device_name[64];
110 	int16			num_axes;
111 	int16			num_buttons;
112 	int16			num_hats;
113 	uint16			_reserved[7];
114 	uint32			flags;
115 	uint16			num_sticks;
116 	int16			config_size;
117 	char			device_config[MAX_CONFIG_SIZE];	/* device specific */
118 } joystick_module_info;
119 
120 /* Note that joystick_module is something used by the game port driver */
121 /* to talk to digital joysticks; if you're writing a sound card driver */
122 /* and want to add support for a /dev/joystick device, use the generic_gameport */
123 /* module. */
124 
125 typedef struct _joystick_module {
126 	module_info minfo;
127 	/** "configure" might change the "info" if it auto-detects a device */
128 	int (*configure)(int port, joystick_module_info * info, size_t size, void ** out_cookie);
129 	/** "read" actual data from device into "data" */
130 	int (*read)(void * cookie, int port, extended_joystick * data, size_t size);
131 	/** "crumble" the cookie (deallocate) when done */
132 	int (*crumble)(void * cookie, int port);
133 	/** "force" tells the joystick to exert force on the same axes as input for the specified duration */
134 	int (*force)(void * cookie, int port, bigtime_t duration, extended_joystick * force, size_t size);
135 	int _reserved_;
136 } joystick_module;
137 
138 /** Doing force feedback means writing an extended_joystick to the device with force values.
139     The "timestamp" should be the duration of the feedback. Successive writes will be queued
140     by the device module. */
141 enum { /* Joystick driver ioctl() opcodes */
142     B_JOYSTICK_GET_SPEED_COMPENSATION = B_JOYSTICK_DRIVER_BASE,
143                                             /* arg -> ptr to int32 */
144     B_JOYSTICK_SET_SPEED_COMPENSATION,      /* arg -> ptr to int32 */
145     B_JOYSTICK_GET_MAX_LATENCY,             /* arg -> ptr to long long */
146     B_JOYSTICK_SET_MAX_LATENCY,             /* arg -> ptr to long long */
147     B_JOYSTICK_SET_DEVICE_MODULE,			/* arg -> ptr to joystick_module; also enters enhanced mode */
148     B_JOYSTICK_GET_DEVICE_MODULE,           /* arg -> ptr to joystick_module */
149 	B_JOYSTICK_SET_RAW_MODE					/* arg -> ptr to bool (true or false) */
150 };
151 
152 /* Speed compensation is not generally necessary, because the joystick */
153 /* driver is measuring using real time, not just # cycles. "0" means the */
154 /* default, center value. + typically returns higher values; - returns lower */
155 /* A typical range might be from -10 to +10, but it varies by driver */
156 
157 /* Lower latency will make for more overhead in reading the joystick */
158 /* ideally, you set this value to just short of how long it takes you */
159 /* to calculate and render a frame. 30 fps -> latency 33000 */
160 
161 
162 typedef struct _generic_gameport_module {
163 	module_info minfo;
164 	status_t (*create_device)(int port, void ** out_storage);
165 	status_t (*delete_device)(void * storage);
166 	status_t (*open_hook)(void * storage, uint32 flags, void ** out_cookie);
167 	status_t (*close_hook)(void * cookie);
168 	status_t (*free_hook)(void * cookie);
169 	status_t (*control_hook)(void * cookie, uint32 op, void * data, size_t len);
170 	status_t (*read_hook)(void * cookie, off_t pos, void * data, size_t * len);
171 	status_t (*write_hook)(void * cookie, off_t pos, const void * data, size_t * len);
172 	int	_reserved_;
173 } generic_gameport_module;
174 
175 
176 #endif
177