4 * Implements the standard dreamcast controller
6 * Copyright (c) 2005 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
22 #include "dreamcast.h"
25 #include "maple/controller.h"
27 #define CONTROLLER_CONFIG_ENTRIES 15
29 static void controller_attach( maple_device_t dev );
30 static void controller_detach( maple_device_t dev );
31 static void controller_destroy( maple_device_t dev );
32 static maple_device_t controller_clone( maple_device_t dev );
33 static maple_device_t controller_new();
34 static lxdream_config_entry_t controller_get_config( maple_device_t dev );
35 static void controller_set_config_value( maple_device_t dev, unsigned int key, const gchar *value );
36 static int controller_get_cond( maple_device_t dev, int function, unsigned char *outbuf,
37 unsigned int *outlen );
39 typedef struct controller_device {
40 struct maple_device dev;
41 uint32_t condition[2];
42 struct lxdream_config_entry config[CONTROLLER_CONFIG_ENTRIES+1];
43 } *controller_device_t;
45 struct maple_device_class controller_class = { "Sega Controller", controller_new };
47 static struct controller_device base_controller = {
48 { MAPLE_DEVICE_TAG, &controller_class, CONTROLLER_IDENT, CONTROLLER_VERSION,
49 controller_get_config, controller_set_config_value,
50 controller_attach, controller_detach, controller_destroy,
51 controller_clone, NULL, NULL, controller_get_cond, NULL, NULL, NULL },
52 {0x0000FFFF, 0x80808080},
53 {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY },
54 { "dpad right", N_("Dpad right"), CONFIG_TYPE_KEY },
55 { "dpad up", N_("Dpad up"), CONFIG_TYPE_KEY },
56 { "dpad down", N_("Dpad down"), CONFIG_TYPE_KEY },
57 { "analog left", N_("Analog left"), CONFIG_TYPE_KEY },
58 { "analog right", N_("Analog right"), CONFIG_TYPE_KEY },
59 { "analog up", N_("Analog up"), CONFIG_TYPE_KEY },
60 { "analog down", N_("Analog down"), CONFIG_TYPE_KEY },
61 { "button X", N_("Button X"), CONFIG_TYPE_KEY },
62 { "button Y", N_("Button Y"), CONFIG_TYPE_KEY },
63 { "button A", N_("Button A"), CONFIG_TYPE_KEY },
64 { "button B", N_("Button B"), CONFIG_TYPE_KEY },
65 { "trigger left", N_("Trigger left"), CONFIG_TYPE_KEY },
66 { "trigger right", N_("Trigger right"), CONFIG_TYPE_KEY },
67 { "start", N_("Start button"), CONFIG_TYPE_KEY },
68 { NULL, CONFIG_TYPE_NONE }} };
70 static int config_button_map[] = {
71 BUTTON_DPAD_LEFT, BUTTON_DPAD_RIGHT, BUTTON_DPAD_UP, BUTTON_DPAD_DOWN,
72 JOY_LEFT, JOY_RIGHT, JOY_UP, JOY_DOWN, BUTTON_X, BUTTON_Y, BUTTON_A,
73 BUTTON_B, BUTTON_LEFT_TRIGGER, BUTTON_RIGHT_TRIGGER, BUTTON_START };
75 #define CONTROLLER(x) ((controller_device_t)(x))
77 static maple_device_t controller_new( )
79 controller_device_t dev = malloc( sizeof(struct controller_device) );
80 memcpy( dev, &base_controller, sizeof(base_controller) );
81 return MAPLE_DEVICE(dev);
84 static maple_device_t controller_clone( maple_device_t srcdevice )
86 controller_device_t src = (controller_device_t)srcdevice;
87 controller_device_t dev = (controller_device_t)controller_new();
88 lxdream_copy_config_list( dev->config, src->config );
89 memcpy( dev->condition, src->condition, sizeof(src->condition) );
90 return MAPLE_DEVICE(dev);
96 static void controller_key_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
98 controller_device_t dev = (controller_device_t)mdev;
102 dev->condition[1] &= ~JOY_X_AXIS;
105 dev->condition[1] |= JOY_X_AXIS;
108 dev->condition[1] &= ~JOY_Y_AXIS;
111 dev->condition[1] |= JOY_Y_AXIS;
113 case BUTTON_LEFT_TRIGGER:
114 case BUTTON_RIGHT_TRIGGER:
115 dev->condition[0] |= value;
118 dev->condition[0] &= ~value;
124 dev->condition[1] = (dev->condition[1] & ~JOY_X_AXIS)| JOY_X_AXIS_CENTER;
128 dev->condition[1] = (dev->condition[1] & ~JOY_Y_AXIS)| JOY_Y_AXIS_CENTER;
130 case BUTTON_LEFT_TRIGGER:
131 case BUTTON_RIGHT_TRIGGER:
132 dev->condition[0] &= ~value;
135 dev->condition[0] |= value;
140 static lxdream_config_entry_t controller_get_config( maple_device_t mdev )
142 controller_device_t dev = (controller_device_t)mdev;
146 static void controller_set_config_value( maple_device_t mdev, unsigned int key, const gchar *value )
148 controller_device_t dev = (controller_device_t)mdev;
149 assert( key < CONTROLLER_CONFIG_ENTRIES );
151 input_unregister_key( dev->config[key].value, controller_key_callback, dev, config_button_map[key] );
152 lxdream_set_config_value( &dev->config[key], value );
153 input_register_key( dev->config[key].value, controller_key_callback, dev, config_button_map[key] );
156 static void controller_destroy( maple_device_t mdev )
162 * Device is being attached to the bus. Go through the config and reserve the
165 static void controller_attach( maple_device_t mdev )
167 controller_device_t dev = (controller_device_t)mdev;
169 for( i=0; i<CONTROLLER_CONFIG_ENTRIES; i++ ) {
170 input_register_key( dev->config[i].value, controller_key_callback, dev, config_button_map[i] );
174 static void controller_detach( maple_device_t mdev )
176 controller_device_t dev = (controller_device_t)mdev;
178 for( i=0; i<CONTROLLER_CONFIG_ENTRIES; i++ ) {
179 input_unregister_key( dev->config[i].value, controller_key_callback, dev, config_button_map[i] );
185 static int controller_get_cond( maple_device_t mdev, int function, unsigned char *outbuf,
186 unsigned int *outlen )
188 controller_device_t dev = (controller_device_t)mdev;
189 if( function == MAPLE_FUNC_CONTROLLER ) {
191 memcpy( outbuf, dev->condition, 8 );
194 return MAPLE_ERR_FUNC_UNSUP;
.