nkeynes@31 | 1 | /**
|
nkeynes@561 | 2 | * $Id$
|
nkeynes@31 | 3 | *
|
nkeynes@31 | 4 | * Implements the standard dreamcast controller
|
nkeynes@31 | 5 | *
|
nkeynes@31 | 6 | * Copyright (c) 2005 Nathan Keynes.
|
nkeynes@31 | 7 | *
|
nkeynes@31 | 8 | * This program is free software; you can redistribute it and/or modify
|
nkeynes@31 | 9 | * it under the terms of the GNU General Public License as published by
|
nkeynes@31 | 10 | * the Free Software Foundation; either version 2 of the License, or
|
nkeynes@31 | 11 | * (at your option) any later version.
|
nkeynes@31 | 12 | *
|
nkeynes@31 | 13 | * This program is distributed in the hope that it will be useful,
|
nkeynes@31 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nkeynes@31 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nkeynes@31 | 16 | * GNU General Public License for more details.
|
nkeynes@31 | 17 | */
|
nkeynes@31 | 18 |
|
nkeynes@2 | 19 | #include <stdlib.h>
|
nkeynes@770 | 20 | #include <assert.h>
|
nkeynes@2 | 21 | #include "dream.h"
|
nkeynes@144 | 22 | #include "dreamcast.h"
|
nkeynes@429 | 23 | #include "display.h"
|
nkeynes@2 | 24 | #include "maple.h"
|
nkeynes@2 | 25 | #include "maple/controller.h"
|
nkeynes@2 | 26 |
|
nkeynes@770 | 27 | #define CONTROLLER_CONFIG_ENTRIES 15
|
nkeynes@144 | 28 |
|
nkeynes@770 | 29 | static void controller_attach( maple_device_t dev );
|
nkeynes@770 | 30 | static void controller_detach( maple_device_t dev );
|
nkeynes@770 | 31 | static void controller_destroy( maple_device_t dev );
|
nkeynes@770 | 32 | static maple_device_t controller_clone( maple_device_t dev );
|
nkeynes@770 | 33 | static maple_device_t controller_new();
|
nkeynes@770 | 34 | static lxdream_config_entry_t controller_get_config( maple_device_t dev );
|
nkeynes@770 | 35 | static void controller_set_config_value( maple_device_t dev, unsigned int key, const gchar *value );
|
nkeynes@770 | 36 | static int controller_get_cond( maple_device_t dev, int function, unsigned char *outbuf,
|
nkeynes@502 | 37 | unsigned int *outlen );
|
nkeynes@2 | 38 |
|
nkeynes@2 | 39 | typedef struct controller_device {
|
nkeynes@2 | 40 | struct maple_device dev;
|
nkeynes@2 | 41 | uint32_t condition[2];
|
nkeynes@770 | 42 | struct lxdream_config_entry config[CONTROLLER_CONFIG_ENTRIES+1];
|
nkeynes@2 | 43 | } *controller_device_t;
|
nkeynes@2 | 44 |
|
nkeynes@144 | 45 | struct maple_device_class controller_class = { "Sega Controller", controller_new };
|
nkeynes@2 | 46 |
|
nkeynes@144 | 47 | static struct controller_device base_controller = {
|
nkeynes@838 | 48 | { MAPLE_DEVICE_TAG, &controller_class, MAPLE_GRAB_DONTCARE,
|
nkeynes@838 | 49 | CONTROLLER_IDENT, CONTROLLER_VERSION,
|
nkeynes@770 | 50 | controller_get_config, controller_set_config_value,
|
nkeynes@770 | 51 | controller_attach, controller_detach, controller_destroy,
|
nkeynes@736 | 52 | controller_clone, NULL, NULL, controller_get_cond, NULL, NULL, NULL },
|
nkeynes@736 | 53 | {0x0000FFFF, 0x80808080},
|
nkeynes@736 | 54 | {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 55 | { "dpad right", N_("Dpad right"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 56 | { "dpad up", N_("Dpad up"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 57 | { "dpad down", N_("Dpad down"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 58 | { "analog left", N_("Analog left"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 59 | { "analog right", N_("Analog right"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 60 | { "analog up", N_("Analog up"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 61 | { "analog down", N_("Analog down"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 62 | { "button X", N_("Button X"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 63 | { "button Y", N_("Button Y"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 64 | { "button A", N_("Button A"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 65 | { "button B", N_("Button B"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 66 | { "trigger left", N_("Trigger left"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 67 | { "trigger right", N_("Trigger right"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 68 | { "start", N_("Start button"), CONFIG_TYPE_KEY },
|
nkeynes@736 | 69 | { NULL, CONFIG_TYPE_NONE }} };
|
nkeynes@144 | 70 |
|
nkeynes@770 | 71 | static int config_button_map[] = {
|
nkeynes@770 | 72 | BUTTON_DPAD_LEFT, BUTTON_DPAD_RIGHT, BUTTON_DPAD_UP, BUTTON_DPAD_DOWN,
|
nkeynes@770 | 73 | JOY_LEFT, JOY_RIGHT, JOY_UP, JOY_DOWN, BUTTON_X, BUTTON_Y, BUTTON_A,
|
nkeynes@770 | 74 | BUTTON_B, BUTTON_LEFT_TRIGGER, BUTTON_RIGHT_TRIGGER, BUTTON_START };
|
nkeynes@770 | 75 |
|
nkeynes@144 | 76 | #define CONTROLLER(x) ((controller_device_t)(x))
|
nkeynes@2 | 77 |
|
nkeynes@770 | 78 | static maple_device_t controller_new( )
|
nkeynes@2 | 79 | {
|
nkeynes@2 | 80 | controller_device_t dev = malloc( sizeof(struct controller_device) );
|
nkeynes@2 | 81 | memcpy( dev, &base_controller, sizeof(base_controller) );
|
nkeynes@2 | 82 | return MAPLE_DEVICE(dev);
|
nkeynes@2 | 83 | }
|
nkeynes@2 | 84 |
|
nkeynes@770 | 85 | static maple_device_t controller_clone( maple_device_t srcdevice )
|
nkeynes@460 | 86 | {
|
nkeynes@460 | 87 | controller_device_t src = (controller_device_t)srcdevice;
|
nkeynes@460 | 88 | controller_device_t dev = (controller_device_t)controller_new();
|
nkeynes@460 | 89 | lxdream_copy_config_list( dev->config, src->config );
|
nkeynes@460 | 90 | memcpy( dev->condition, src->condition, sizeof(src->condition) );
|
nkeynes@460 | 91 | return MAPLE_DEVICE(dev);
|
nkeynes@460 | 92 | }
|
nkeynes@460 | 93 |
|
nkeynes@144 | 94 | /**
|
nkeynes@144 | 95 | * Input callback
|
nkeynes@144 | 96 | */
|
nkeynes@770 | 97 | static void controller_key_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
|
nkeynes@144 | 98 | {
|
nkeynes@144 | 99 | controller_device_t dev = (controller_device_t)mdev;
|
nkeynes@144 | 100 | if( isKeyDown ) {
|
nkeynes@736 | 101 | switch( value ) {
|
nkeynes@736 | 102 | case JOY_LEFT:
|
nkeynes@736 | 103 | dev->condition[1] &= ~JOY_X_AXIS;
|
nkeynes@736 | 104 | break;
|
nkeynes@736 | 105 | case JOY_RIGHT:
|
nkeynes@736 | 106 | dev->condition[1] |= JOY_X_AXIS;
|
nkeynes@736 | 107 | break;
|
nkeynes@736 | 108 | case JOY_UP:
|
nkeynes@736 | 109 | dev->condition[1] &= ~JOY_Y_AXIS;
|
nkeynes@736 | 110 | break;
|
nkeynes@736 | 111 | case JOY_DOWN:
|
nkeynes@736 | 112 | dev->condition[1] |= JOY_Y_AXIS;
|
nkeynes@736 | 113 | break;
|
nkeynes@736 | 114 | case BUTTON_LEFT_TRIGGER:
|
nkeynes@736 | 115 | case BUTTON_RIGHT_TRIGGER:
|
nkeynes@736 | 116 | dev->condition[0] |= value;
|
nkeynes@736 | 117 | break;
|
nkeynes@736 | 118 | default:
|
nkeynes@736 | 119 | dev->condition[0] &= ~value;
|
nkeynes@736 | 120 | }
|
nkeynes@144 | 121 | } else {
|
nkeynes@736 | 122 | switch(value ) {
|
nkeynes@736 | 123 | case JOY_LEFT:
|
nkeynes@736 | 124 | case JOY_RIGHT:
|
nkeynes@736 | 125 | dev->condition[1] = (dev->condition[1] & ~JOY_X_AXIS)| JOY_X_AXIS_CENTER;
|
nkeynes@736 | 126 | break;
|
nkeynes@736 | 127 | case JOY_UP:
|
nkeynes@736 | 128 | case JOY_DOWN:
|
nkeynes@736 | 129 | dev->condition[1] = (dev->condition[1] & ~JOY_Y_AXIS)| JOY_Y_AXIS_CENTER;
|
nkeynes@736 | 130 | break;
|
nkeynes@736 | 131 | case BUTTON_LEFT_TRIGGER:
|
nkeynes@736 | 132 | case BUTTON_RIGHT_TRIGGER:
|
nkeynes@736 | 133 | dev->condition[0] &= ~value;
|
nkeynes@736 | 134 | break;
|
nkeynes@736 | 135 | default:
|
nkeynes@736 | 136 | dev->condition[0] |= value;
|
nkeynes@736 | 137 | }
|
nkeynes@144 | 138 | }
|
nkeynes@144 | 139 | }
|
nkeynes@2 | 140 |
|
nkeynes@770 | 141 | static lxdream_config_entry_t controller_get_config( maple_device_t mdev )
|
nkeynes@2 | 142 | {
|
nkeynes@144 | 143 | controller_device_t dev = (controller_device_t)mdev;
|
nkeynes@144 | 144 | return dev->config;
|
nkeynes@144 | 145 | }
|
nkeynes@2 | 146 |
|
nkeynes@770 | 147 | static void controller_set_config_value( maple_device_t mdev, unsigned int key, const gchar *value )
|
nkeynes@770 | 148 | {
|
nkeynes@770 | 149 | controller_device_t dev = (controller_device_t)mdev;
|
nkeynes@770 | 150 | assert( key < CONTROLLER_CONFIG_ENTRIES );
|
nkeynes@770 | 151 |
|
nkeynes@770 | 152 | input_unregister_key( dev->config[key].value, controller_key_callback, dev, config_button_map[key] );
|
nkeynes@770 | 153 | lxdream_set_config_value( &dev->config[key], value );
|
nkeynes@770 | 154 | input_register_key( dev->config[key].value, controller_key_callback, dev, config_button_map[key] );
|
nkeynes@770 | 155 | }
|
nkeynes@770 | 156 |
|
nkeynes@770 | 157 | static void controller_destroy( maple_device_t mdev )
|
nkeynes@144 | 158 | {
|
nkeynes@144 | 159 | free( mdev );
|
nkeynes@144 | 160 | }
|
nkeynes@144 | 161 |
|
nkeynes@144 | 162 | /**
|
nkeynes@144 | 163 | * Device is being attached to the bus. Go through the config and reserve the
|
nkeynes@144 | 164 | * keys we need.
|
nkeynes@144 | 165 | */
|
nkeynes@770 | 166 | static void controller_attach( maple_device_t mdev )
|
nkeynes@144 | 167 | {
|
nkeynes@144 | 168 | controller_device_t dev = (controller_device_t)mdev;
|
nkeynes@770 | 169 | int i;
|
nkeynes@770 | 170 | for( i=0; i<CONTROLLER_CONFIG_ENTRIES; i++ ) {
|
nkeynes@770 | 171 | input_register_key( dev->config[i].value, controller_key_callback, dev, config_button_map[i] );
|
nkeynes@770 | 172 | }
|
nkeynes@2 | 173 | }
|
nkeynes@2 | 174 |
|
nkeynes@770 | 175 | static void controller_detach( maple_device_t mdev )
|
nkeynes@2 | 176 | {
|
nkeynes@451 | 177 | controller_device_t dev = (controller_device_t)mdev;
|
nkeynes@770 | 178 | int i;
|
nkeynes@770 | 179 | for( i=0; i<CONTROLLER_CONFIG_ENTRIES; i++ ) {
|
nkeynes@770 | 180 | input_unregister_key( dev->config[i].value, controller_key_callback, dev, config_button_map[i] );
|
nkeynes@770 | 181 | }
|
nkeynes@2 | 182 |
|
nkeynes@2 | 183 | }
|
nkeynes@2 | 184 |
|
nkeynes@2 | 185 |
|
nkeynes@770 | 186 | static int controller_get_cond( maple_device_t mdev, int function, unsigned char *outbuf,
|
nkeynes@502 | 187 | unsigned int *outlen )
|
nkeynes@2 | 188 | {
|
nkeynes@2 | 189 | controller_device_t dev = (controller_device_t)mdev;
|
nkeynes@2 | 190 | if( function == MAPLE_FUNC_CONTROLLER ) {
|
nkeynes@2 | 191 | *outlen = 2;
|
nkeynes@2 | 192 | memcpy( outbuf, dev->condition, 8 );
|
nkeynes@2 | 193 | return 0;
|
nkeynes@2 | 194 | } else {
|
nkeynes@2 | 195 | return MAPLE_ERR_FUNC_UNSUP;
|
nkeynes@2 | 196 | }
|
nkeynes@2 | 197 | }
|
nkeynes@2 | 198 |
|