Might have bit off more than I can chew. 56 buttons, 5 rotaries and 2 joys

Thank you for continued help!! I am not using any diodes. I didn't think they were needed as I can use the code (which I have updated below based on your help and in another thread) and I can see all 56 (64 once rotary code is added) button presses as well as able to press buttons simultaneously with no issues. The 32 limitation I refer to is when you open game controller properties (devices and printers) for windows the max displayed is 32 buttons and the joystick library can create multiple HID devices so I split the matrixes into 2 8x8s giving me 32 buttons per "controller".

Since this does eat up 16 wires I only have 4 inputs left which is where I thought the IO expander would come into play giving me 12 analog inputs to use for the 2 3-axis controllers or use the analogs on the LEO for the joysticks and the 16 pins on the expander for the matrixes.

I'm definitely open to suggestions on getting this completed.

#include <Keypad.h>
#include <Joystick.h>

#define ENABLE_PULLUPS

#define NUMBUTTONS0 28
#define NUMBUTTONS1 28
#define NUMROWS0 4
#define NUMCOLS0 7
#define NUMROWS1 4
#define NUMCOLS1 7

#define JOYSTICK_COUNT 2

byte buttons0[NUMROWS0][NUMCOLS0] = {
  {0, 1, 2, 3, 4, 5, 6},
  {7, 8, 9, 10, 11, 12, 13},
  {14, 15, 16, 17, 18, 19, 20},
  {21, 22, 23, 24, 25, 26, 27}
};

byte buttons1[NUMROWS1][NUMCOLS1] = {
  {0, 1, 2, 3, 4, 5, 6},
  {7, 8, 9, 10, 11, 12, 13},
  {14, 15, 16, 17, 18, 19, 20},
  {21, 22, 23, 24, 25, 26, 27}
};
byte rowPins0[NUMROWS0] = {A4, A5, 0, 1};
byte colPins0[NUMCOLS0] = {2, 3, 4, 5, 6, 7, 8};

byte rowPins1[NUMROWS1] = {A0, A1, A2, A3};
byte colPins1[NUMCOLS1] = {2, 3, 4, 5, 6, 7, 8};

Keypad buttbx = Keypad( makeKeymap(buttons0), rowPins0, colPins0, NUMROWS0, NUMCOLS0);
Keypad buttbx1 = Keypad( makeKeymap(buttons1), rowPins1, colPins1, NUMROWS1, NUMCOLS1);

Joystick_ Joystick[JOYSTICK_COUNT] = {
  Joystick_ (0x04, JOYSTICK_TYPE_JOYSTICK, 32, 0, true, true, true, true, true, true, false, false, false, false, false),
  Joystick_ (0x05, JOYSTICK_TYPE_MULTI_AXIS, 32, 2, true, true, true, true, true, true, false, false, false, false, false)
};

void setup() {
  Joystick[0].begin();
  Joystick[1].begin();

}

void loop() {
  CheckAllButtons0();
  CheckAllButtons1();

}

void CheckAllButtons0(void) {
  if (buttbx.getKeys())
  {
    for (int i = 0; i < LIST_MAX; i++)
    {
      if ( buttbx.key[i].stateChanged )
      {
        switch (buttbx.key[i].kstate) {
          case PRESSED:
          case HOLD:
            Joystick[0].setButton(buttbx.key[i].kchar, 1);
            break;
          case RELEASED:
          case IDLE:
            Joystick[0].setButton(buttbx.key[i].kchar, 0);
            break;
        }
      }
    }
  }
}
  void CheckAllButtons1(void) {
    if (buttbx1.getKeys())
    {
      for (int i = 0; i < LIST_MAX; i++)
      {
        if ( buttbx1.key[i].stateChanged )
        {
          switch (buttbx1.key[i].kstate) {
            case PRESSED:
            case HOLD:
              Joystick[1].setButton(buttbx1.key[i].kchar, 1);
              break;
            case RELEASED:
            case IDLE:
              Joystick[1].setButton(buttbx1.key[i].kchar, 0);
              break;
          }
        }
      }
    }
  }

Here is the code that will include the rotaries as joystick buttons as well once I solder them in

#define NUMROTARIES 4

struct rotariesdef {
  byte pin1;
  byte pin2;
  int ccwchar;
  int cwchar;
  volatile unsigned char state;
};

rotariesdef rotaries[NUMROTARIES] {
  {9,10,24,25,0},
  {11,12,26,27,0},
  {13,14,28,29,0},
  {15,16,30,31,0},
};

#define DIR_CCW 0x10
#define DIR_CW 0x20
#define R_START 0x0

#ifdef HALF_STEP
#define R_CCW_BEGIN 0x1
#define R_CW_BEGIN 0x2
#define R_START_M 0x3
#define R_CW_BEGIN_M 0x4
#define R_CCW_BEGIN_M 0x5
const unsigned char ttable[6][4] = {
  // R_START (00)
  {R_START_M,            R_CW_BEGIN,     R_CCW_BEGIN,  R_START},
  // R_CCW_BEGIN
  {R_START_M | DIR_CCW, R_START,        R_CCW_BEGIN,  R_START},
  // R_CW_BEGIN
  {R_START_M | DIR_CW,  R_CW_BEGIN,     R_START,      R_START},
  // R_START_M (11)
  {R_START_M,            R_CCW_BEGIN_M,  R_CW_BEGIN_M, R_START},
  // R_CW_BEGIN_M
  {R_START_M,            R_START_M,      R_CW_BEGIN_M, R_START | DIR_CW},
  // R_CCW_BEGIN_M
  {R_START_M,            R_CCW_BEGIN_M,  R_START_M,    R_START | DIR_CCW},
};
#else
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6

const unsigned char ttable[7][4] = {
  // R_START
  {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
  // R_CW_FINAL
  {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
  // R_CW_BEGIN
  {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
  // R_CW_NEXT
  {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
  // R_CCW_BEGIN
  {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
  // R_CCW_FINAL
  {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
  // R_CCW_NEXT
  {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};
#endif


void setup() {
  rotary_init();}

void loop() { 

  CheckAllEncoders();


}


void rotary_init() {
  for (int i=0;i<NUMROTARIES;i++) {
    pinMode(rotaries[i].pin1, INPUT);
    pinMode(rotaries[i].pin2, INPUT);
    #ifdef ENABLE_PULLUPS
      digitalWrite(rotaries[i].pin1, HIGH);
      digitalWrite(rotaries[i].pin2, HIGH);
    #endif
  }
}


unsigned char rotary_process(int _i) {
   unsigned char pinstate = (digitalRead(rotaries[_i].pin2) << 1) | digitalRead(rotaries[_i].pin1);
  rotaries[_i].state = ttable[rotaries[_i].state & 0xf][pinstate];
  return (rotaries[_i].state & 0x30);
}

void CheckAllEncoders(void) {
  for (int i=0;i<NUMROTARIES;i++) {
    unsigned char result = rotary_process(i);
    if (result == DIR_CCW) {
      Joystick.setButton(rotaries[i].ccwchar, 1); delay(50); Joystick.setButton(rotaries[i].ccwchar, 0);
    };
    if (result == DIR_CW) {
      Joystick.setButton(rotaries[i].cwchar, 1); delay(50); Joystick.setButton(rotaries[i].cwchar, 0);
    };
  }
}