Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 25075
b: refs/heads/master
c: b157d55
h: refs/heads/master
i:
  25073: a00da83
  25071: 9e98983
v: v3
  • Loading branch information
Raphael Assenat authored and Dmitry Torokhov committed Apr 2, 2006
1 parent 186b4c6 commit 5d97e2d
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ac648a6a704f73cc2a0f128d9deeb57aa6d76f6d
refs/heads/master: b157d55eef38f014015b8058a9f733d1c1c49cb4
11 changes: 6 additions & 5 deletions trunk/Documentation/input/joystick-parport.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ with them.

All NES and SNES use the same synchronous serial protocol, clocked from
the computer's side (and thus timing insensitive). To allow up to 5 NES
and/or SNES gamepads connected to the parallel port at once, the output
lines of the parallel port are shared, while one of 5 available input lines
is assigned to each gamepad.
and/or SNES gamepads and/or SNES mice connected to the parallel port at once,
the output lines of the parallel port are shared, while one of 5 available
input lines is assigned to each gamepad.

This protocol is handled by the gamecon.c driver, so that's the one
you'll use for NES and SNES gamepads.
you'll use for NES, SNES gamepads and SNES mice.

The main problem with PC parallel ports is that they don't have +5V power
source on any of their pins. So, if you want a reliable source of power
Expand Down Expand Up @@ -106,7 +106,7 @@ A, Turbo B, Select and Start, and is connected through 5 wires, then it is
either a NES or NES clone and will work with this connection. SNES gamepads
also use 5 wires, but have more buttons. They will work as well, of course.

Pinout for NES gamepads Pinout for SNES gamepads
Pinout for NES gamepads Pinout for SNES gamepads and mice

+----> Power +-----------------------\
| 7 | o o o o | x x o | 1
Expand Down Expand Up @@ -454,6 +454,7 @@ uses the following kernel/module command line:
6 | N64 pad
7 | Sony PSX controller
8 | Sony PSX DDR controller
9 | SNES mouse

The exact type of the PSX controller type is autoprobed when used so
hot swapping should work (but is not recomended).
Expand Down
83 changes: 70 additions & 13 deletions trunk/drivers/input/joystick/gamecon.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Based on the work of:
* Andree Borrmann John Dahlstrom
* David Kuder Nathan Hand
* Raphael Assenat
*/

/*
Expand Down Expand Up @@ -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

Expand All @@ -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.
*/
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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++) {

Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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);

/*
Expand Down Expand Up @@ -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];
Expand All @@ -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);
Expand Down

0 comments on commit 5d97e2d

Please sign in to comment.