Search
lxdream.org :: lxdream/src/maple/lightgun.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/maple/lightgun.c
changeset 1072:d82e04e6d497
prev1034:7044e01148f0
next1298:d0eb2307b847
author nkeynes
date Fri Dec 23 08:20:17 2011 +1000 (12 years ago)
permissions -rw-r--r--
last change Move the exception exit macros up to sh4core.h
file annotate diff log raw
nkeynes@850
     1
/**
nkeynes@1021
     2
 * $Id$
nkeynes@850
     3
 *
nkeynes@850
     4
 * Implementation of the SEGA lightgun device
nkeynes@850
     5
 * Part No. HKT-7800
nkeynes@850
     6
 *
nkeynes@850
     7
 * Copyright (c) 2008 Nathan Keynes.
nkeynes@850
     8
 *
nkeynes@850
     9
 * This program is free software; you can redistribute it and/or modify
nkeynes@850
    10
 * it under the terms of the GNU General Public License as published by
nkeynes@850
    11
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@850
    12
 * (at your option) any later version.
nkeynes@850
    13
 *
nkeynes@850
    14
 * This program is distributed in the hope that it will be useful,
nkeynes@850
    15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@850
    16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@850
    17
 * GNU General Public License for more details.
nkeynes@850
    18
 */
nkeynes@850
    19
nkeynes@850
    20
#include <stdlib.h>
nkeynes@850
    21
#include <stdio.h>
nkeynes@850
    22
#include <string.h>
nkeynes@850
    23
#include <assert.h>
nkeynes@850
    24
#include "display.h"
nkeynes@850
    25
#include "eventq.h"
nkeynes@850
    26
#include "pvr2/pvr2.h"
nkeynes@850
    27
#include "maple/maple.h"
nkeynes@850
    28
nkeynes@850
    29
#define BUTTON_B            0x00000002
nkeynes@850
    30
#define BUTTON_A            0x00000004
nkeynes@850
    31
#define BUTTON_START        0x00000008
nkeynes@850
    32
#define BUTTON_DPAD_UP      0x00000010
nkeynes@850
    33
#define BUTTON_DPAD_DOWN    0x00000020
nkeynes@850
    34
#define BUTTON_DPAD_LEFT    0x00000040
nkeynes@850
    35
#define BUTTON_DPAD_RIGHT   0x00000080
nkeynes@850
    36
nkeynes@850
    37
#define LIGHTGUN_IDENT {     0x00, 0x00, 0x00, 0x81,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0xFE, \
nkeynes@850
    38
	0x00, 0x00, 0x00, 0x00,  0xFF, 0x01, 0x44, 0x72,  0x65, 0x61, 0x6D, 0x63,  0x61, 0x73, 0x74, 0x20, \
nkeynes@850
    39
	0x47, 0x75, 0x6E, 0x20,  0x20, 0x20, 0x20, 0x20,  0x20, 0x20, 0x20, 0x20,  0x20, 0x20, 0x20, 0x20, \
nkeynes@850
    40
	0x20, 0x20, 0x20, 0x20,  0x50, 0x72, 0x6F, 0x64,  0x75, 0x63, 0x65, 0x64,  0x20, 0x42, 0x79, 0x20, \
nkeynes@850
    41
	0x6F, 0x72, 0x20, 0x55,  0x6E, 0x64, 0x65, 0x72,  0x20, 0x4C, 0x69, 0x63,  0x65, 0x6E, 0x73, 0x65, \
nkeynes@850
    42
	0x20, 0x46, 0x72, 0x6F,  0x6D, 0x20, 0x53, 0x45,  0x47, 0x41, 0x20, 0x45,  0x4E, 0x54, 0x45, 0x52, \
nkeynes@850
    43
	0x50, 0x52, 0x49, 0x53,  0x45, 0x53, 0x2C, 0x4C,  0x54, 0x44, 0x2E, 0x20,  0x20, 0x20, 0x20, 0x20, \
nkeynes@850
    44
	0xDC, 0x00, 0x2C, 0x01 }
nkeynes@850
    45
#define LIGHTGUN_VERSION {   0x56, 0x65, 0x72, 0x73,  0x69, 0x6F, 0x6E, 0x20,  0x31, 0x2E, 0x30, 0x30, \
nkeynes@850
    46
	0x30, 0x2C, 0x31, 0x39,  0x39, 0x38, 0x2F, 0x30,  0x39, 0x2F, 0x31, 0x36,  0x2C, 0x33, 0x31, 0x35, \
nkeynes@850
    47
	0x2D, 0x36, 0x31, 0x32,  0x35, 0x2D, 0x41, 0x47,  0x20, 0x20, 0x20, 0x2C,  0x55, 0x2C, 0x44, 0x2C, \
nkeynes@850
    48
	0x4C, 0x2C, 0x52, 0x2C,  0x53, 0x2C, 0x41, 0x2C,  0x42, 0x20, 0x4B, 0x65,  0x79, 0x20, 0x26, 0x20, \
nkeynes@850
    49
	0x53, 0x63, 0x61, 0x6E,  0x6E, 0x69, 0x6E, 0x67,  0x20, 0x4C, 0x69, 0x6E,  0x65, 0x20, 0x41, 0x6D, \
nkeynes@850
    50
	0x70, 0x2E, 0x20, 0x20 }                                       
nkeynes@850
    51
nkeynes@850
    52
nkeynes@850
    53
#define LIGHTGUN_CONFIG_ENTRIES 7
nkeynes@850
    54
nkeynes@850
    55
static void lightgun_attach( maple_device_t dev );
nkeynes@850
    56
static void lightgun_detach( maple_device_t dev );
nkeynes@850
    57
static void lightgun_destroy( maple_device_t dev );
nkeynes@850
    58
static maple_device_t lightgun_clone( maple_device_t dev );
nkeynes@850
    59
static maple_device_t lightgun_new();
nkeynes@1072
    60
static void lightgun_key_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown );
nkeynes@1072
    61
static lxdream_config_group_t lightgun_get_config( maple_device_t dev );
nkeynes@850
    62
static int lightgun_get_cond( maple_device_t dev, int function, unsigned char *outbuf,
nkeynes@850
    63
                         unsigned int *outlen );
nkeynes@850
    64
static void lightgun_start_gun( maple_device_t dev );
nkeynes@850
    65
static void lightgun_stop_gun( maple_device_t dev );
nkeynes@850
    66
nkeynes@1072
    67
static gboolean lightgun_set_config_value( lxdream_config_group_t group, unsigned int key,
nkeynes@1072
    68
                                           const gchar *oldvalue, const gchar *value );
nkeynes@1072
    69
nkeynes@850
    70
typedef struct lightgun_device {
nkeynes@850
    71
    struct maple_device dev;
nkeynes@850
    72
    uint32_t condition[2];
nkeynes@850
    73
    int gun_active;
nkeynes@850
    74
    int mouse_x, mouse_y;
nkeynes@1072
    75
    struct lxdream_config_group config;
nkeynes@850
    76
} *lightgun_device_t;
nkeynes@850
    77
nkeynes@1034
    78
struct maple_device_class lightgun_class = { "Sega Lightgun", 
nkeynes@1034
    79
        MAPLE_TYPE_PRIMARY|MAPLE_GRAB_NO|MAPLE_SLOTS_2, lightgun_new };
nkeynes@850
    80
nkeynes@850
    81
static struct lightgun_device base_lightgun = {
nkeynes@1034
    82
        { MAPLE_DEVICE_TAG, &lightgun_class,
nkeynes@850
    83
          LIGHTGUN_IDENT, LIGHTGUN_VERSION, 
nkeynes@1072
    84
          lightgun_get_config,
nkeynes@850
    85
          lightgun_attach, lightgun_detach, lightgun_destroy,
nkeynes@1034
    86
          lightgun_clone, NULL, NULL, lightgun_get_cond, NULL, NULL, NULL, NULL,
nkeynes@850
    87
          lightgun_start_gun, lightgun_stop_gun},
nkeynes@1072
    88
          {0x0000FFFF, 0x80808080}, 0, -1, -1,
nkeynes@1072
    89
          {"Sega Lightgun", NULL, lightgun_key_callback, NULL,
nkeynes@1072
    90
           {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_LEFT },
nkeynes@1072
    91
            { "dpad right", N_("Dpad right"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_RIGHT },
nkeynes@1072
    92
            { "dpad up", N_("Dpad up"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_UP },
nkeynes@1072
    93
            { "dpad down", N_("Dpad down"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_DOWN },
nkeynes@1072
    94
            { "button A", N_("Button A"), CONFIG_TYPE_KEY, NULL, BUTTON_A },
nkeynes@1072
    95
            { "button B", N_("Button B"), CONFIG_TYPE_KEY, NULL, BUTTON_B },
nkeynes@1072
    96
            { "start", N_("Start button"), CONFIG_TYPE_KEY, NULL, BUTTON_START },
nkeynes@1072
    97
            { NULL, CONFIG_TYPE_NONE }}}  };
nkeynes@850
    98
nkeynes@1072
    99
nkeynes@850
   100
#define lightgun(x) ((lightgun_device_t)(x))
nkeynes@850
   101
nkeynes@850
   102
static maple_device_t lightgun_new( )
nkeynes@850
   103
{
nkeynes@850
   104
    lightgun_device_t dev = malloc( sizeof(struct lightgun_device) );
nkeynes@850
   105
    memcpy( dev, &base_lightgun, sizeof(base_lightgun) );
nkeynes@1072
   106
    dev->config.data = dev;
nkeynes@850
   107
    return MAPLE_DEVICE(dev);
nkeynes@850
   108
}
nkeynes@850
   109
nkeynes@850
   110
static maple_device_t lightgun_clone( maple_device_t srcdevice )
nkeynes@850
   111
{
nkeynes@850
   112
    lightgun_device_t src = (lightgun_device_t)srcdevice;
nkeynes@850
   113
    lightgun_device_t dev = (lightgun_device_t)lightgun_new();
nkeynes@1072
   114
    lxdream_copy_config_group( &dev->config, &src->config );
nkeynes@850
   115
    memcpy( dev->condition, src->condition, sizeof(src->condition) );
nkeynes@850
   116
    return MAPLE_DEVICE(dev);
nkeynes@850
   117
}
nkeynes@850
   118
nkeynes@1072
   119
static lxdream_config_group_t lightgun_get_config( maple_device_t mdev )
nkeynes@1072
   120
{
nkeynes@1072
   121
    lightgun_device_t dev = (lightgun_device_t)mdev;
nkeynes@1072
   122
    return &dev->config;
nkeynes@1072
   123
}
nkeynes@1072
   124
nkeynes@1072
   125
static void lightgun_destroy( maple_device_t mdev )
nkeynes@1072
   126
{
nkeynes@1072
   127
    free( mdev );
nkeynes@1072
   128
}
nkeynes@1072
   129
nkeynes@850
   130
/**
nkeynes@850
   131
 * Input callback 
nkeynes@850
   132
 */
nkeynes@850
   133
static void lightgun_key_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
nkeynes@850
   134
{
nkeynes@850
   135
    lightgun_device_t dev = (lightgun_device_t)mdev;
nkeynes@850
   136
    if( isKeyDown ) {
nkeynes@850
   137
        dev->condition[0] &= ~value;
nkeynes@850
   138
    } else {
nkeynes@850
   139
        dev->condition[0] |= value;
nkeynes@850
   140
    }
nkeynes@850
   141
}
nkeynes@850
   142
nkeynes@850
   143
static void lightgun_mouse_callback( void *mdev, uint32_t buttons, int32_t x, int32_t y, gboolean absolute )
nkeynes@850
   144
{
nkeynes@850
   145
    lightgun_device_t dev = (lightgun_device_t)mdev;
nkeynes@850
   146
    if( absolute ) {
nkeynes@850
   147
        dev->mouse_x = x;
nkeynes@850
   148
        dev->mouse_y = y;
nkeynes@850
   149
        if( dev->gun_active ) {
nkeynes@850
   150
            pvr2_queue_gun_event( x, y );
nkeynes@850
   151
            dev->gun_active = FALSE;
nkeynes@850
   152
        }
nkeynes@850
   153
    }
nkeynes@850
   154
}
nkeynes@850
   155
nkeynes@850
   156
/**
nkeynes@850
   157
 * Device is being attached to the bus. Go through the config and reserve the
nkeynes@850
   158
 * keys we need.
nkeynes@850
   159
 */
nkeynes@850
   160
static void lightgun_attach( maple_device_t mdev )
nkeynes@850
   161
{
nkeynes@850
   162
    lightgun_device_t dev = (lightgun_device_t)mdev;
nkeynes@1072
   163
    dev->config.on_change = input_keygroup_changed;
nkeynes@1072
   164
    input_register_keygroup( &dev->config );
nkeynes@850
   165
    input_register_mouse_hook( TRUE, lightgun_mouse_callback, dev );
nkeynes@850
   166
}
nkeynes@850
   167
nkeynes@850
   168
static void lightgun_detach( maple_device_t mdev )
nkeynes@850
   169
{
nkeynes@850
   170
    lightgun_device_t dev = (lightgun_device_t)mdev;
nkeynes@1072
   171
    input_unregister_keygroup( &dev->config );
nkeynes@1072
   172
    dev->config.on_change = NULL;
nkeynes@850
   173
    input_unregister_mouse_hook( lightgun_mouse_callback, dev );
nkeynes@850
   174
nkeynes@850
   175
}
nkeynes@850
   176
nkeynes@850
   177
nkeynes@850
   178
static int lightgun_get_cond( maple_device_t mdev, int function, unsigned char *outbuf,
nkeynes@850
   179
                         unsigned int *outlen )
nkeynes@850
   180
{
nkeynes@850
   181
    lightgun_device_t dev = (lightgun_device_t)mdev;
nkeynes@850
   182
    if( function == MAPLE_FUNC_CONTROLLER ) {
nkeynes@850
   183
        *outlen = 2;
nkeynes@850
   184
        memcpy( outbuf, dev->condition, 8 );
nkeynes@850
   185
        return 0;
nkeynes@850
   186
    } else {
nkeynes@850
   187
        return MAPLE_ERR_FUNC_UNSUP;
nkeynes@850
   188
    }
nkeynes@850
   189
}
nkeynes@850
   190
nkeynes@850
   191
static void lightgun_start_gun( maple_device_t mdev )
nkeynes@850
   192
{
nkeynes@850
   193
    lightgun_device_t dev = (lightgun_device_t)mdev;
nkeynes@850
   194
    if( dev->mouse_x != -1 && dev->mouse_y != -1 ) {
nkeynes@850
   195
        pvr2_queue_gun_event( dev->mouse_x, dev->mouse_y );
nkeynes@850
   196
    } else {
nkeynes@850
   197
        // Wait for a mouse event
nkeynes@850
   198
        dev->gun_active = 1;
nkeynes@850
   199
    }
nkeynes@850
   200
}
nkeynes@850
   201
nkeynes@850
   202
static void lightgun_stop_gun( maple_device_t mdev )
nkeynes@850
   203
{
nkeynes@850
   204
    lightgun_device_t dev = (lightgun_device_t)mdev;
nkeynes@850
   205
    dev->gun_active = 0;
nkeynes@850
   206
    event_cancel( EVENT_GUNPOS );
nkeynes@850
   207
}
.