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