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 Tue Jun 02 23:16:26 2009 +0000 (14 years ago)
permissions -rw-r--r--
last change "MythTV" patch from Wahrhaft, thanks!:
* Add support for LIRC input devices
* Add hotkey input support
* Add command-line option for immediate fullscreen
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 }
.