nkeynes@31: /** nkeynes@144: * $Id: controller.c,v 1.3 2006-05-15 08:28:52 nkeynes Exp $ nkeynes@31: * nkeynes@31: * Implements the standard dreamcast controller nkeynes@31: * nkeynes@31: * Copyright (c) 2005 Nathan Keynes. nkeynes@31: * nkeynes@31: * This program is free software; you can redistribute it and/or modify nkeynes@31: * it under the terms of the GNU General Public License as published by nkeynes@31: * the Free Software Foundation; either version 2 of the License, or nkeynes@31: * (at your option) any later version. nkeynes@31: * nkeynes@31: * This program is distributed in the hope that it will be useful, nkeynes@31: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@31: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@31: * GNU General Public License for more details. nkeynes@31: */ nkeynes@31: nkeynes@2: #include nkeynes@2: #include "dream.h" nkeynes@144: #include "dreamcast.h" nkeynes@2: #include "maple.h" nkeynes@2: #include "maple/controller.h" nkeynes@2: nkeynes@144: #define CONTROLLER_CONFIG_ENTRIES 16 nkeynes@144: nkeynes@2: void controller_attach( maple_device_t dev ); nkeynes@2: void controller_detach( maple_device_t dev ); nkeynes@144: void controller_destroy( maple_device_t dev ); nkeynes@144: maple_device_t controller_new(); nkeynes@144: dreamcast_config_entry_t controller_get_config( maple_device_t dev ); nkeynes@2: int controller_get_cond( maple_device_t dev, int function, char *outbuf, nkeynes@2: int *outlen ); nkeynes@2: nkeynes@2: typedef struct controller_device { nkeynes@2: struct maple_device dev; nkeynes@2: uint32_t condition[2]; nkeynes@144: struct dreamcast_config_entry config[CONTROLLER_CONFIG_ENTRIES]; nkeynes@2: } *controller_device_t; nkeynes@2: nkeynes@144: struct maple_device_class controller_class = { "Sega Controller", controller_new }; nkeynes@2: nkeynes@144: static struct controller_device base_controller = { nkeynes@144: { MAPLE_DEVICE_TAG, &controller_class, CONTROLLER_IDENT, CONTROLLER_VERSION, nkeynes@144: controller_get_config, controller_attach, controller_detach, controller_destroy, nkeynes@144: NULL, NULL, controller_get_cond, NULL, NULL, NULL }, nkeynes@144: {0x0000FFFF, 0}, nkeynes@144: {{ "dpad left", CONFIG_TYPE_KEY }, nkeynes@144: { "dpad right", CONFIG_TYPE_KEY }, nkeynes@144: { "dpad up", CONFIG_TYPE_KEY }, nkeynes@144: { "dpad down", CONFIG_TYPE_KEY }, nkeynes@144: { "analog left", CONFIG_TYPE_KEY }, nkeynes@144: { "analog right", CONFIG_TYPE_KEY }, nkeynes@144: { "analog up", CONFIG_TYPE_KEY }, nkeynes@144: { "analog down", CONFIG_TYPE_KEY }, nkeynes@144: { "button X", CONFIG_TYPE_KEY }, nkeynes@144: { "button Y", CONFIG_TYPE_KEY }, nkeynes@144: { "button A", CONFIG_TYPE_KEY }, nkeynes@144: { "button B", CONFIG_TYPE_KEY }, nkeynes@144: { "trigger left", CONFIG_TYPE_KEY }, nkeynes@144: { "trigger right", CONFIG_TYPE_KEY }, nkeynes@144: { "start", CONFIG_TYPE_KEY }, nkeynes@144: { NULL, CONFIG_TYPE_NONE }} }; nkeynes@144: nkeynes@144: #define CONTROLLER(x) ((controller_device_t)(x)) nkeynes@2: nkeynes@2: maple_device_t controller_new( ) nkeynes@2: { nkeynes@2: controller_device_t dev = malloc( sizeof(struct controller_device) ); nkeynes@2: memcpy( dev, &base_controller, sizeof(base_controller) ); nkeynes@2: memset( dev->condition, 0, 8 ); nkeynes@2: dev->condition[0] = 0x0000FFFF; nkeynes@2: return MAPLE_DEVICE(dev); nkeynes@2: } nkeynes@2: nkeynes@144: /** nkeynes@144: * Input callback nkeynes@144: */ nkeynes@144: void controller_key_callback( void *mdev, uint32_t value, gboolean isKeyDown ) nkeynes@144: { nkeynes@144: controller_device_t dev = (controller_device_t)mdev; nkeynes@144: if( isKeyDown ) { nkeynes@144: dev->condition[0] |= value; nkeynes@144: fprintf( stderr, "Key %08X DOWN\n", value ); nkeynes@144: } else { nkeynes@144: dev->condition[0] &= ~value; nkeynes@144: fprintf( stderr, "Key %08X UP\n", value ); nkeynes@144: } nkeynes@144: } nkeynes@2: nkeynes@144: dreamcast_config_entry_t controller_get_config( maple_device_t mdev ) nkeynes@2: { nkeynes@144: controller_device_t dev = (controller_device_t)mdev; nkeynes@144: return dev->config; nkeynes@144: } nkeynes@2: nkeynes@144: void controller_destroy( maple_device_t mdev ) nkeynes@144: { nkeynes@144: free( mdev ); nkeynes@144: } nkeynes@144: nkeynes@144: /** nkeynes@144: * Device is being attached to the bus. Go through the config and reserve the nkeynes@144: * keys we need. nkeynes@144: */ nkeynes@144: void controller_attach( maple_device_t mdev ) nkeynes@144: { nkeynes@144: controller_device_t dev = (controller_device_t)mdev; nkeynes@144: input_register_key( dev->config[0].value, controller_key_callback, dev, BUTTON_DPAD_LEFT ); nkeynes@144: input_register_key( dev->config[1].value, controller_key_callback, dev, BUTTON_DPAD_RIGHT ); nkeynes@144: input_register_key( dev->config[2].value, controller_key_callback, dev, BUTTON_DPAD_UP ); nkeynes@144: input_register_key( dev->config[3].value, controller_key_callback, dev, BUTTON_DPAD_DOWN ); nkeynes@144: input_register_key( dev->config[4].value, controller_key_callback, dev, 0 ); nkeynes@144: input_register_key( dev->config[5].value, controller_key_callback, dev, 0 ); nkeynes@144: input_register_key( dev->config[6].value, controller_key_callback, dev, 0 ); nkeynes@144: input_register_key( dev->config[7].value, controller_key_callback, dev, 0 ); nkeynes@144: input_register_key( dev->config[8].value, controller_key_callback, dev, BUTTON_X ); nkeynes@144: input_register_key( dev->config[9].value, controller_key_callback, dev, BUTTON_Y ); nkeynes@144: input_register_key( dev->config[10].value, controller_key_callback, dev, BUTTON_A ); nkeynes@144: input_register_key( dev->config[11].value, controller_key_callback, dev, BUTTON_B ); nkeynes@144: input_register_key( dev->config[12].value, controller_key_callback, dev, BUTTON_LEFT_TRIGGER ); nkeynes@144: input_register_key( dev->config[13].value, controller_key_callback, dev, BUTTON_RIGHT_TRIGGER ); nkeynes@144: input_register_key( dev->config[14].value, controller_key_callback, dev, BUTTON_START ); nkeynes@2: } nkeynes@2: nkeynes@2: void controller_detach( maple_device_t dev ) nkeynes@2: { nkeynes@2: nkeynes@2: } nkeynes@2: nkeynes@2: nkeynes@2: int controller_get_cond( maple_device_t mdev, int function, char *outbuf, nkeynes@2: int *outlen ) nkeynes@2: { nkeynes@2: controller_device_t dev = (controller_device_t)mdev; nkeynes@2: if( function == MAPLE_FUNC_CONTROLLER ) { nkeynes@2: *outlen = 2; nkeynes@2: memcpy( outbuf, dev->condition, 8 ); nkeynes@2: return 0; nkeynes@2: } else { nkeynes@2: return MAPLE_ERR_FUNC_UNSUP; nkeynes@2: } nkeynes@2: } nkeynes@2: