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
15typedef 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
32typedef 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.
44typedef 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
101enum {	/* 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
107typedef 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
125typedef 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. */
141enum { /* 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
162typedef 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