filename | src/maple/controller.c |
changeset | 1010:a506a2f66180 |
prev | 850:28782ebbd01d |
next | 1034:7044e01148f0 |
author | nkeynes |
date | Mon Jun 08 04:12:21 2009 +0000 (14 years ago) |
permissions | -rw-r--r-- |
last change | General cleanup of the GD-rom subsystem - merge gdrom_image_t and gdrom_disc_t - Abstract MMC devices using a lower-level scsi transport - OSX: only look at the whole disc device, and ignore partitions |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * Implements the standard dreamcast controller
5 * Part No. HKT-7700
6 *
7 * Copyright (c) 2005 Nathan Keynes.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
20 #include <stdlib.h>
21 #include <assert.h>
22 #include "dream.h"
23 #include "dreamcast.h"
24 #include "display.h"
25 #include "maple.h"
27 /* First word of controller condition */
28 #define BUTTON_C 0x00000001 /* not on standard controller */
29 #define BUTTON_B 0x00000002
30 #define BUTTON_A 0x00000004
31 #define BUTTON_START 0x00000008
32 #define BUTTON_DPAD_UP 0x00000010
33 #define BUTTON_DPAD_DOWN 0x00000020
34 #define BUTTON_DPAD_LEFT 0x00000040
35 #define BUTTON_DPAD_RIGHT 0x00000080
36 #define BUTTON_Z 0x00000100 /* not on standard controller */
37 #define BUTTON_Y 0x00000200
38 #define BUTTON_X 0x00000400
39 #define BUTTON_D 0x00000800 /* not on standard controller */
40 #define BUTTON_LEFT_TRIGGER 0xFF000000 /* Bitmask */
41 #define BUTTON_RIGHT_TRIGGER 0x00FF0000 /* Bitmask */
43 /* Second word of controller condition (bitmasks) */
44 #define JOY_X_AXIS_MASK 0x000000FF
45 #define JOY_Y_AXIS_MASK 0x0000FF00
46 #define JOY_X_AXIS_CENTER 0x00000080
47 #define JOY_Y_AXIS_CENTER 0x00008000
48 #define JOY2_X_AXIS_MASK 0x00FF0000 /* not on standard controller */
49 #define JOY2_Y_AXIS_MASK 0xFF000000 /* not on standard controller */
51 #define JOY_X_AXIS(x) ((x)&0xFF)
52 #define JOY_Y_AXIS(y) (((y)&0xFF)<<8)
54 /* The following bits are used by the emulator for flags but don't actually
55 * appear in the hardware
56 */
57 #define JOY_LEFT 0x80000001
58 #define JOY_RIGHT 0x80000002
59 #define JOY_UP 0x80000004
60 #define JOY_DOWN 0x80000008
62 /* Standard controller ID */
63 #define CONTROLLER_IDENT {0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, \
64 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x63, 0x61, 0x73, 0x74, 0x20, \
65 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
66 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x42, 0x79, 0x20, \
67 0x6f, 0x72, 0x20, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, \
68 0x20, 0x46, 0x72, 0x6f, 0x6d, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x45, 0x4e, 0x54, 0x45, 0x52, \
69 0x50, 0x52, 0x49, 0x53, 0x45, 0x53, 0x2c, 0x4c, 0x54, 0x44, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, \
70 0xae, 0x01, 0xf4, 0x01}
71 #define CONTROLLER_VERSION {0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x31, \
72 0x30, 0x2c, 0x31, 0x39, 0x39, 0x38, 0x2f, 0x30, 0x39, 0x2f, 0x32, 0x38, 0x2c, 0x33, 0x31, 0x35, \
73 0x2d, 0x36, 0x32, 0x31, 0x31, 0x2d, 0x41, 0x42, 0x20, 0x20, 0x20, 0x2c, 0x41, 0x6e, 0x61, 0x6c, \
74 0x6f, 0x67, 0x20, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20, \
75 0x34, 0x74, 0x68, 0x20, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x35, 0x2f, 0x38, 0x20, \
76 0x20, 0x2b, 0x44, 0x46 }
78 #define CONTROLLER_CONFIG_ENTRIES 15
80 static void controller_attach( maple_device_t dev );
81 static void controller_detach( maple_device_t dev );
82 static void controller_destroy( maple_device_t dev );
83 static maple_device_t controller_clone( maple_device_t dev );
84 static maple_device_t controller_new();
85 static lxdream_config_entry_t controller_get_config( maple_device_t dev );
86 static void controller_set_config_value( maple_device_t dev, unsigned int key, const gchar *value );
87 static int controller_get_cond( maple_device_t dev, int function, unsigned char *outbuf,
88 unsigned int *outlen );
90 typedef struct controller_device {
91 struct maple_device dev;
92 uint32_t condition[2];
93 struct lxdream_config_entry config[CONTROLLER_CONFIG_ENTRIES+1];
94 } *controller_device_t;
96 struct maple_device_class controller_class = { "Sega Controller", controller_new };
98 static struct controller_device base_controller = {
99 { MAPLE_DEVICE_TAG, &controller_class, MAPLE_GRAB_DONTCARE,
100 CONTROLLER_IDENT, CONTROLLER_VERSION,
101 controller_get_config, controller_set_config_value,
102 controller_attach, controller_detach, controller_destroy,
103 controller_clone, NULL, NULL, controller_get_cond, NULL, NULL, NULL, NULL, NULL },
104 {0x0000FFFF, 0x80808080},
105 {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY },
106 { "dpad right", N_("Dpad right"), CONFIG_TYPE_KEY },
107 { "dpad up", N_("Dpad up"), CONFIG_TYPE_KEY },
108 { "dpad down", N_("Dpad down"), CONFIG_TYPE_KEY },
109 { "analog left", N_("Analog left"), CONFIG_TYPE_KEY },
110 { "analog right", N_("Analog right"), CONFIG_TYPE_KEY },
111 { "analog up", N_("Analog up"), CONFIG_TYPE_KEY },
112 { "analog down", N_("Analog down"), CONFIG_TYPE_KEY },
113 { "button X", N_("Button X"), CONFIG_TYPE_KEY },
114 { "button Y", N_("Button Y"), CONFIG_TYPE_KEY },
115 { "button A", N_("Button A"), CONFIG_TYPE_KEY },
116 { "button B", N_("Button B"), CONFIG_TYPE_KEY },
117 { "trigger left", N_("Trigger left"), CONFIG_TYPE_KEY },
118 { "trigger right", N_("Trigger right"), CONFIG_TYPE_KEY },
119 { "start", N_("Start button"), CONFIG_TYPE_KEY },
120 { NULL, CONFIG_TYPE_NONE }} };
122 static int config_button_map[] = {
123 BUTTON_DPAD_LEFT, BUTTON_DPAD_RIGHT, BUTTON_DPAD_UP, BUTTON_DPAD_DOWN,
124 JOY_LEFT, JOY_RIGHT, JOY_UP, JOY_DOWN, BUTTON_X, BUTTON_Y, BUTTON_A,
125 BUTTON_B, BUTTON_LEFT_TRIGGER, BUTTON_RIGHT_TRIGGER, BUTTON_START };
127 #define CONTROLLER(x) ((controller_device_t)(x))
129 static maple_device_t controller_new( )
130 {
131 controller_device_t dev = malloc( sizeof(struct controller_device) );
132 memcpy( dev, &base_controller, sizeof(base_controller) );
133 return MAPLE_DEVICE(dev);
134 }
136 static maple_device_t controller_clone( maple_device_t srcdevice )
137 {
138 controller_device_t src = (controller_device_t)srcdevice;
139 controller_device_t dev = (controller_device_t)controller_new();
140 lxdream_copy_config_list( dev->config, src->config );
141 memcpy( dev->condition, src->condition, sizeof(src->condition) );
142 return MAPLE_DEVICE(dev);
143 }
145 /**
146 * Input callback
147 */
148 static void controller_key_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
149 {
150 controller_device_t dev = (controller_device_t)mdev;
151 if( isKeyDown ) {
152 switch( value ) {
153 case JOY_LEFT:
154 dev->condition[1] &= ~JOY_X_AXIS_MASK;
155 dev->condition[1] |= JOY_X_AXIS(0x7F - pressure);
156 break;
157 case JOY_RIGHT:
158 dev->condition[1] &= ~JOY_X_AXIS_MASK;
159 dev->condition[1] |= JOY_X_AXIS(0x80 + pressure);
160 break;
161 case JOY_UP:
162 dev->condition[1] &= ~JOY_Y_AXIS_MASK;
163 dev->condition[1] |= JOY_Y_AXIS(0x7F - pressure);
164 break;
165 case JOY_DOWN:
166 dev->condition[1] &= ~JOY_Y_AXIS_MASK;
167 dev->condition[1] |= JOY_Y_AXIS(0x80 + pressure);
168 break;
169 case BUTTON_LEFT_TRIGGER:
170 case BUTTON_RIGHT_TRIGGER:
171 dev->condition[0] |= value;
172 break;
173 default:
174 dev->condition[0] &= ~value;
175 }
176 } else {
177 switch(value ) {
178 case JOY_LEFT:
179 case JOY_RIGHT:
180 dev->condition[1] = (dev->condition[1] & ~JOY_X_AXIS_MASK)| JOY_X_AXIS_CENTER;
181 break;
182 case JOY_UP:
183 case JOY_DOWN:
184 dev->condition[1] = (dev->condition[1] & ~JOY_Y_AXIS_MASK)| JOY_Y_AXIS_CENTER;
185 break;
186 case BUTTON_LEFT_TRIGGER:
187 case BUTTON_RIGHT_TRIGGER:
188 dev->condition[0] &= ~value;
189 break;
190 default:
191 dev->condition[0] |= value;
192 }
193 }
194 }
196 static lxdream_config_entry_t controller_get_config( maple_device_t mdev )
197 {
198 controller_device_t dev = (controller_device_t)mdev;
199 return dev->config;
200 }
202 static void controller_set_config_value( maple_device_t mdev, unsigned int key, const gchar *value )
203 {
204 controller_device_t dev = (controller_device_t)mdev;
205 assert( key < CONTROLLER_CONFIG_ENTRIES );
207 input_unregister_key( dev->config[key].value, controller_key_callback, dev, config_button_map[key] );
208 lxdream_set_config_value( &dev->config[key], value );
209 input_register_key( dev->config[key].value, controller_key_callback, dev, config_button_map[key] );
210 }
212 static void controller_destroy( maple_device_t mdev )
213 {
214 free( mdev );
215 }
217 /**
218 * Device is being attached to the bus. Go through the config and reserve the
219 * keys we need.
220 */
221 static void controller_attach( maple_device_t mdev )
222 {
223 controller_device_t dev = (controller_device_t)mdev;
224 int i;
225 for( i=0; i<CONTROLLER_CONFIG_ENTRIES; i++ ) {
226 input_register_key( dev->config[i].value, controller_key_callback, dev, config_button_map[i] );
227 }
228 }
230 static void controller_detach( maple_device_t mdev )
231 {
232 controller_device_t dev = (controller_device_t)mdev;
233 int i;
234 for( i=0; i<CONTROLLER_CONFIG_ENTRIES; i++ ) {
235 input_unregister_key( dev->config[i].value, controller_key_callback, dev, config_button_map[i] );
236 }
238 }
241 static int controller_get_cond( maple_device_t mdev, int function, unsigned char *outbuf,
242 unsigned int *outlen )
243 {
244 controller_device_t dev = (controller_device_t)mdev;
245 if( function == MAPLE_FUNC_CONTROLLER ) {
246 *outlen = 2;
247 memcpy( outbuf, dev->condition, 8 );
248 return 0;
249 } else {
250 return MAPLE_ERR_FUNC_UNSUP;
251 }
252 }
.