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