|
@@ -7,6 +7,7 @@
|
|
|
* Based on the work of:
|
|
|
* Andree Borrmann John Dahlstrom
|
|
|
* David Kuder Nathan Hand
|
|
|
+ * Raphael Assenat
|
|
|
*/
|
|
|
|
|
|
/*
|
|
@@ -73,8 +74,9 @@ __obsolete_setup("gc_3=");
|
|
|
#define GC_N64 6
|
|
|
#define GC_PSX 7
|
|
|
#define GC_DDR 8
|
|
|
+#define GC_SNESMOUSE 9
|
|
|
|
|
|
-#define GC_MAX 8
|
|
|
+#define GC_MAX 9
|
|
|
|
|
|
#define GC_REFRESH_TIME HZ/100
|
|
|
|
|
@@ -94,7 +96,7 @@ static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };
|
|
|
|
|
|
static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick",
|
|
|
"Multisystem 2-button joystick", "N64 controller", "PSX controller",
|
|
|
- "PSX DDR controller" };
|
|
|
+ "PSX DDR controller", "SNES mouse" };
|
|
|
/*
|
|
|
* N64 support.
|
|
|
*/
|
|
@@ -206,9 +208,12 @@ static void gc_n64_process_packet(struct gc *gc)
|
|
|
* NES/SNES support.
|
|
|
*/
|
|
|
|
|
|
-#define GC_NES_DELAY 6 /* Delay between bits - 6us */
|
|
|
-#define GC_NES_LENGTH 8 /* The NES pads use 8 bits of data */
|
|
|
-#define GC_SNES_LENGTH 12 /* The SNES true length is 16, but the last 4 bits are unused */
|
|
|
+#define GC_NES_DELAY 6 /* Delay between bits - 6us */
|
|
|
+#define GC_NES_LENGTH 8 /* The NES pads use 8 bits of data */
|
|
|
+#define GC_SNES_LENGTH 12 /* The SNES true length is 16, but the
|
|
|
+ last 4 bits are unused */
|
|
|
+#define GC_SNESMOUSE_LENGTH 32 /* The SNES mouse uses 32 bits, the first
|
|
|
+ 16 bits are equivalent to a gamepad */
|
|
|
|
|
|
#define GC_NES_POWER 0xfc
|
|
|
#define GC_NES_CLOCK 0x01
|
|
@@ -243,11 +248,15 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data)
|
|
|
|
|
|
static void gc_nes_process_packet(struct gc *gc)
|
|
|
{
|
|
|
- unsigned char data[GC_SNES_LENGTH];
|
|
|
+ unsigned char data[GC_SNESMOUSE_LENGTH];
|
|
|
struct input_dev *dev;
|
|
|
- int i, j, s;
|
|
|
+ int i, j, s, len;
|
|
|
+ char x_rel, y_rel;
|
|
|
+
|
|
|
+ len = gc->pads[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH :
|
|
|
+ (gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH);
|
|
|
|
|
|
- gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data);
|
|
|
+ gc_nes_read_packet(gc, len, data);
|
|
|
|
|
|
for (i = 0; i < GC_MAX_DEVICES; i++) {
|
|
|
|
|
@@ -270,6 +279,44 @@ static void gc_nes_process_packet(struct gc *gc)
|
|
|
for (j = 0; j < 8; j++)
|
|
|
input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
|
|
|
|
|
|
+ if (s & gc->pads[GC_SNESMOUSE]) {
|
|
|
+ /*
|
|
|
+ * The 4 unused bits from SNES controllers appear to be ID bits
|
|
|
+ * so use them to make sure iwe are dealing with a mouse.
|
|
|
+ * gamepad is connected. This is important since
|
|
|
+ * my SNES gamepad sends 1's for bits 16-31, which
|
|
|
+ * cause the mouse pointer to quickly move to the
|
|
|
+ * upper left corner of the screen.
|
|
|
+ */
|
|
|
+ if (!(s & data[12]) && !(s & data[13]) &&
|
|
|
+ !(s & data[14]) && (s & data[15])) {
|
|
|
+ input_report_key(dev, BTN_LEFT, s & data[9]);
|
|
|
+ input_report_key(dev, BTN_RIGHT, s & data[8]);
|
|
|
+
|
|
|
+ x_rel = y_rel = 0;
|
|
|
+ for (j = 0; j < 7; j++) {
|
|
|
+ x_rel <<= 1;
|
|
|
+ if (data[25 + j] & s)
|
|
|
+ x_rel |= 1;
|
|
|
+
|
|
|
+ y_rel <<= 1;
|
|
|
+ if (data[17 + j] & s)
|
|
|
+ y_rel |= 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (x_rel) {
|
|
|
+ if (data[24] & s)
|
|
|
+ x_rel = -x_rel;
|
|
|
+ input_report_rel(dev, REL_X, x_rel);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (y_rel) {
|
|
|
+ if (data[16] & s)
|
|
|
+ y_rel = -y_rel;
|
|
|
+ input_report_rel(dev, REL_Y, y_rel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
input_sync(dev);
|
|
|
}
|
|
|
}
|
|
@@ -525,10 +572,10 @@ static void gc_timer(unsigned long private)
|
|
|
gc_n64_process_packet(gc);
|
|
|
|
|
|
/*
|
|
|
- * NES and SNES pads
|
|
|
+ * NES and SNES pads or mouse
|
|
|
*/
|
|
|
|
|
|
- if (gc->pads[GC_NES] || gc->pads[GC_SNES])
|
|
|
+ if (gc->pads[GC_NES] || gc->pads[GC_SNES] || gc->pads[GC_SNESMOUSE])
|
|
|
gc_nes_process_packet(gc);
|
|
|
|
|
|
/*
|
|
@@ -610,10 +657,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
|
|
|
input_dev->open = gc_open;
|
|
|
input_dev->close = gc_close;
|
|
|
|
|
|
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
|
|
|
+ if (pad_type != GC_SNESMOUSE) {
|
|
|
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
|
|
|
|
|
|
- for (i = 0; i < 2; i++)
|
|
|
- input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
|
|
|
+ for (i = 0; i < 2; i++)
|
|
|
+ input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
|
|
|
+ } else
|
|
|
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
|
|
|
|
|
|
gc->pads[0] |= gc_status_bit[idx];
|
|
|
gc->pads[pad_type] |= gc_status_bit[idx];
|
|
@@ -631,6 +681,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
|
|
|
|
|
|
break;
|
|
|
|
|
|
+ case GC_SNESMOUSE:
|
|
|
+ set_bit(BTN_LEFT, input_dev->keybit);
|
|
|
+ set_bit(BTN_RIGHT, input_dev->keybit);
|
|
|
+ set_bit(REL_X, input_dev->relbit);
|
|
|
+ set_bit(REL_Y, input_dev->relbit);
|
|
|
+ break;
|
|
|
+
|
|
|
case GC_SNES:
|
|
|
for (i = 4; i < 8; i++)
|
|
|
set_bit(gc_snes_btn[i], input_dev->keybit);
|