nvsofts / SNES-HID

Turn SNES joypad into HID compliant USB device using Arduino

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

4 player support possible?

RodentVienna opened this issue · comments

Hello, do you think 4 Player (4 Snes pads on one Arduino) support is possible with little modification to the code?
thank you!

commented

I think there is a need to much modification to support non-standard SNES controller (such as SNES mouse, SNES multitap, ...)
Moreover, I cannot test the multitap feature because I don't own SNES multitap.

Hello,

I actually don't mean more device support like snes mouse or multitap, but simply to make it possible to connect 4 controllers instead of 2.

...

#define P3_CLK (10)
#define P3_DATA1 (8)
#define P3_DATA2 (9)
#define P3_IO (4)

#define P4_CLK (16)
#define P4_DATA1 (6)
#define P4_DATA2 (7)
#define P4_IO (5)

also, you can always look at how raphael assenat did it (but not atmega32u4), this actually supports mouse and multitap.:
http://www.raphnet.net/electronique/4nes4snes/4nes4snes-1.5.tar.gz

commented

Multitap uses IO pin for multiplexing controllers I/O.
Therefore, simply add controller definition for P3/P4 is not working.

commented

I cannot adopt 4nes4snes code to SNES-HID project because it is licensed under the GPL.

commented

Sorry, I misread the comment.

I don't intended to add 4-player support without multitap to the code.
But, you may follow these instructions to add the support.

  1. Add P3/P4 Joystick_ definition
  2. Add a code for reading P3/P4 controller status (requires corresponding CLK/DATA/LATCH pin)
  3. Apply controller statuses using joyWrite()

thank you. would you see requirement of adding port4 and port5 functions as well:

void pulseWrite(int port, int port2, int port3)
{
  digitalWrite(port, HIGH);
  digitalWrite(port2, HIGH);
  digitalWrite(port3, HIGH);
  digitalWrite(port, LOW);
  digitalWrite(port2, LOW);
  digitalWrite(port3, LOW);
}

here is the code i hacked together for 4-player-support (aka 4 gamepads on 1 pro-micro)
a) tested successfully with 4x ASCII Pad.
b) some pins are actually not required. I only soldered CLK and DATA1 of each port (not DATA2 and not IO)
c) compiled using Joystick Library 2.0.4 and Arduino IDE 1.8.5

#include <Joystick.h>

#define P1_CLK (2)
#define P1_DATA1 (3) //
#define P1_DATA2 (4)
#define P1_IO (5)

#define P2_CLK (6)
#define P2_DATA1 (7) //
#define P2_DATA2 (8)
#define P2_IO (9)

#define P3_CLK (10)
#define P3_DATA1 (16) //
#define P3_DATA2 (14)
#define P3_IO (15)

#define P4_CLK (18)
#define P4_DATA1 (19) //
#define P4_DATA2 (20)
#define P4_IO (21)

#define P1234_LATCH (1)

Joystick_ joystick[4] = {
  Joystick_(0x03, JOYSTICK_TYPE_GAMEPAD, 12, 0, false, false, false, false, false, false, false, false, false, false, false),
  Joystick_(0x04, JOYSTICK_TYPE_GAMEPAD, 12, 0, false, false, false, false, false, false, false, false, false, false, false),
  Joystick_(0x05, JOYSTICK_TYPE_GAMEPAD, 12, 0, false, false, false, false, false, false, false, false, false, false, false),
  Joystick_(0x06, JOYSTICK_TYPE_GAMEPAD, 12, 0, false, false, false, false, false, false, false, false, false, false, false)
};

void setup() {
  joystick[0].begin();
  joystick[1].begin();
  joystick[2].begin();
  joystick[3].begin(); 
  
  pinMode(P1_CLK, OUTPUT);
  pinMode(P1_DATA1, INPUT_PULLUP);
  pinMode(P1_DATA2, INPUT_PULLUP);
  pinMode(P1_IO, INPUT_PULLUP);
  digitalWrite(P1_CLK, LOW);

  pinMode(P2_CLK, OUTPUT);
  pinMode(P2_DATA1, INPUT_PULLUP);
  pinMode(P2_DATA2, INPUT_PULLUP);
  pinMode(P2_IO, INPUT_PULLUP);
  digitalWrite(P2_CLK, LOW);

  pinMode(P3_CLK, OUTPUT);
  pinMode(P3_DATA1, INPUT_PULLUP);
  pinMode(P3_DATA2, INPUT_PULLUP);
  pinMode(P3_IO, INPUT_PULLUP);
  digitalWrite(P3_CLK, LOW);

  pinMode(P4_CLK, OUTPUT);
  pinMode(P4_DATA1, INPUT_PULLUP);
  pinMode(P4_DATA2, INPUT_PULLUP);
  pinMode(P4_IO, INPUT_PULLUP);
  digitalWrite(P4_CLK, LOW);
  
  pinMode(P1234_LATCH, OUTPUT);
}

void pulseWrite(int port)
{
  digitalWrite(port, HIGH);
  digitalWrite(port, LOW);
}

void pulseWrite(int port, int port2)
{
  digitalWrite(port, HIGH);
  digitalWrite(port2, HIGH);
  digitalWrite(port, LOW);
  digitalWrite(port2, LOW);
}

void pulseWrite(int port, int port2, int port3)
{
  digitalWrite(port, HIGH);
  digitalWrite(port2, HIGH);
  digitalWrite(port3, HIGH);
  digitalWrite(port, LOW);
  digitalWrite(port2, LOW);
  digitalWrite(port3, LOW);
}

void pulseWrite(int port, int port2, int port3, int port4)
{
  digitalWrite(port, HIGH);
  digitalWrite(port2, HIGH);
  digitalWrite(port3, HIGH);
  digitalWrite(port4, HIGH);
  digitalWrite(port, LOW);
  digitalWrite(port2, LOW);
  digitalWrite(port3, LOW);
  digitalWrite(port4, LOW);
}

void pulseWrite(int port, int port2, int port3, int port4, int port5)
{
  digitalWrite(port, HIGH);
  digitalWrite(port2, HIGH);
  digitalWrite(port3, HIGH);
  digitalWrite(port4, HIGH);
  digitalWrite(port5, HIGH);
  digitalWrite(port, LOW);
  digitalWrite(port2, LOW);
  digitalWrite(port3, LOW);
  digitalWrite(port4, LOW);
  digitalWrite(port5, LOW);
}

void joyWrite(int num, int btn, int digital)
{
  if (!digital) {
    joystick[num].pressButton(btn);
  }else{
    joystick[num].releaseButton(btn);
  }
}

void loop() {
  int i;

  pulseWrite(P1234_LATCH, P1_CLK, P2_CLK, P3_CLK, P4_CLK);
  joyWrite(0, 0, digitalRead(P1_DATA1));
  joyWrite(1, 0, digitalRead(P2_DATA1));
  joyWrite(2, 0, digitalRead(P3_DATA1));
  joyWrite(3, 0, digitalRead(P4_DATA1));
  
  for (i = 1; i < 16; i++) {
    pulseWrite(P1_CLK);
    pulseWrite(P2_CLK);
    pulseWrite(P3_CLK);
    pulseWrite(P4_CLK);
    
    joyWrite(0, i, digitalRead(P1_DATA1));
    joyWrite(1, i, digitalRead(P2_DATA1));
    joyWrite(2, i, digitalRead(P3_DATA1));
    joyWrite(3, i, digitalRead(P4_DATA1));
  }

  delay(10);
}

Thank you for playing!

and sorry for spamming, here, have some images :) I hacked this into a 3rd-Party Multitap.
1
2

and you may consider linking to this graphic from Eric Hettervik, which gives a IMPO better representation of the pinout: http://i.imgur.com/3deHaFa.png