Add support for 2 drums!

This commit is contained in:
ShikyC 2024-01-05 01:24:20 -08:00
parent 73470d1507
commit ba814d0d49
5 changed files with 108 additions and 83 deletions

View File

@ -1,3 +1,4 @@
#define PLAYERS 2
#define CHANNELS 4 #define CHANNELS 4
// SAMPLE_CACHE_LENGTH must be power of 2 (8, 16, 32, etc.) // SAMPLE_CACHE_LENGTH must be power of 2 (8, 16, 32, etc.)
@ -16,121 +17,145 @@
#define RESET_TIME 40 #define RESET_TIME 40
// Sensitivity multipliers for each channel, 1.0 as the baseline // Sensitivity multipliers for each channel, 1.0 as the baseline
#define L_DON_SENS 1.0 #define P1_L_DON_SENS 1.0
#define L_KAT_SENS 1.0 #define P1_L_KAT_SENS 1.0
#define R_DON_SENS 1.0 #define P1_R_DON_SENS 1.0
#define R_KAT_SENS 1.0 #define P1_R_KAT_SENS 1.0
#define P2_L_DON_SENS 1.0
#define P2_L_KAT_SENS 1.0
#define P2_R_DON_SENS 1.0
#define P2_R_KAT_SENS 1.0
// Input pins for each channel // Input pins for each channel
#define L_DON_IN 4 #define P1_L_DON_IN 4
#define L_KAT_IN 5 #define P1_L_KAT_IN 5
#define R_DON_IN 6 #define P1_R_DON_IN 6
#define R_KAT_IN 7 #define P1_R_KAT_IN 7
#define P2_L_DON_IN 8
#define P2_L_KAT_IN 3
#define P2_R_DON_IN 9
#define P2_R_KAT_IN 10
// Output LED pins for each channel (just for visualization) // Output LED pins for each channel (just for visualization)
#define L_DON_LED 10 #define P1_L_DON_LED 11
#define L_KAT_LED 11 #define P1_L_KAT_LED 12
#define R_DON_LED 12 #define P1_R_DON_LED 13
#define R_KAT_LED 13 #define P1_R_KAT_LED 14
#define P2_L_DON_LED 42
#define P2_L_KAT_LED 41
#define P2_R_DON_LED 40
#define P2_R_KAT_LED 39
#define AXIS_RANGE 1023
#include "USB.h" #include "USB.h"
#include "Joystick_ESP32S2.h" #include "Joystick_ESP32S2.h"
#include "cache.h" #include "cache.h"
Cache<int, SAMPLE_CACHE_LENGTH> inputWindow[CHANNELS]; Cache<int, SAMPLE_CACHE_LENGTH> inputWindow[PLAYERS][CHANNELS];
unsigned long power[CHANNELS]; unsigned long power[PLAYERS][CHANNELS];
unsigned long lastPower[CHANNELS]; unsigned long lastPower[PLAYERS][CHANNELS];
bool triggered; bool triggered[PLAYERS];
unsigned long triggeredTime[CHANNELS]; unsigned long triggeredTime[PLAYERS][CHANNELS];
const byte inPins[] = {L_DON_IN, L_KAT_IN, R_DON_IN, R_KAT_IN}; const byte inPins[PLAYERS][CHANNELS] = {
const byte outPins[] = {L_DON_LED, L_KAT_LED, R_DON_LED, R_KAT_LED}; P1_L_DON_IN, P1_L_KAT_IN, P1_R_DON_IN, P1_R_KAT_IN,
const float sensitivities[] = {L_DON_SENS, L_KAT_SENS, R_DON_SENS, R_KAT_SENS}; P2_L_DON_IN, P2_L_KAT_IN, P2_R_DON_IN, P2_R_KAT_IN
uint axisValues[] = {0, 0, 0, 0}; };
const byte outPins[PLAYERS][CHANNELS] = {
P1_L_DON_LED, P1_L_KAT_LED, P1_R_DON_LED, P1_R_KAT_LED,
P2_L_DON_LED, P2_L_KAT_LED, P2_R_DON_LED, P2_R_KAT_LED
};
const float sensitivities[PLAYERS][CHANNELS] = {
P1_L_DON_SENS, P1_L_KAT_SENS, P1_R_DON_SENS, P1_R_KAT_SENS,
P2_L_DON_SENS, P2_L_KAT_SENS, P2_R_DON_SENS, P2_R_KAT_SENS
};
uint axisValues[PLAYERS][CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0};
int outputValue[PLAYERS] = {0, 0};
uint resetTimer[PLAYERS] = {0, 0};
short maxIndex[PLAYERS] = {0, 0};
float maxPower[PLAYERS] = {0, 0};
uint shifter = 0; uint shifter = 0;
int outputValue = 0;
uint resetTimer = 0;
short maxIndex;
float maxPower;
unsigned long lastTime;
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 10, 4, Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 10, 4,
true, true, true, true, true, true, true, true, false, true, true, false,
false, false, false, false, false); false, false, false, false, false);
void setup() { void setup() {
Serial.begin(250000); for (byte p = 0; p < PLAYERS; p++) {
for (byte i = 0; i < CHANNELS; i++) { for (byte i = 0; i < CHANNELS; i++) {
power[i] = 0; power[p][i] = 0;
lastPower[i] = 0; lastPower[p][i] = 0;
triggered = false; triggered[p] = false;
pinMode(inPins[i], INPUT); pinMode(inPins[p][i], INPUT);
pinMode(outPins[i], OUTPUT); pinMode(outPins[p][i], OUTPUT);
}
maxIndex[p] = -1;
maxPower[p] = 0;
} }
maxIndex = -1;
maxPower = 0;
lastTime = micros();
USB.PID(0x4869); USB.PID(0x4869);
USB.VID(0x4869); USB.VID(0x4869);
USB.productName("Taiko Controller"); USB.productName("Taiko Controller");
USB.manufacturerName("GitHub Community"); USB.manufacturerName("GitHub Community");
USB.begin(); USB.begin();
Joystick.begin(false); Joystick.begin(false);
Joystick.setXAxisRange(-1024, 1023); Joystick.setXAxisRange(-AXIS_RANGE, AXIS_RANGE);
Joystick.setYAxisRange(-1024, 1023); Joystick.setYAxisRange(-AXIS_RANGE, AXIS_RANGE);
Joystick.setZAxisRange(-1024, 1023); Joystick.setRxAxisRange(-AXIS_RANGE, AXIS_RANGE);
Joystick.setRxAxisRange(-1024, 1023); Joystick.setRyAxisRange(-AXIS_RANGE, AXIS_RANGE);
Joystick.setRyAxisRange(-1024, 1023);
Joystick.setRzAxisRange(-1024, 1023);
} }
void loop() { void loop() {
for (byte p = 0; p < PLAYERS; p++) {
for (byte i = 0; i < CHANNELS; i++) { for (byte i = 0; i < CHANNELS; i++) {
inputWindow[i].put(analogRead(inPins[i])); inputWindow[p][i].put(analogRead(inPins[p][i]));
power[i] = sensitivities[i] * (power[i] - inputWindow[i].get(1) + inputWindow[i].get()); power[p][i] = sensitivities[p][i] * (power[p][i] - inputWindow[p][i].get(1) + inputWindow[p][i].get());
if (lastPower[i] > maxPower && power[i] < lastPower[i]) { if (lastPower[p][i] > maxPower[p] && power[p][i] < lastPower[p][i]) {
maxPower = lastPower[i]; maxPower[p] = lastPower[p][i];
maxIndex = i; maxIndex[p] = i;
} }
lastPower[i] = power[i]; lastPower[p][i] = power[p][i];
} }
if (!triggered && maxPower >= HIT_THRES) { if (!triggered[p] && maxPower[p] >= HIT_THRES) {
triggered = true; triggered[p] = true;
digitalWrite(outPins[maxIndex], HIGH); digitalWrite(outPins[p][maxIndex[p]], HIGH);
outputValue = (int)(1023 * (maxPower >= MAX_THRES ? 1 : maxPower / MAX_THRES)); outputValue[p] = (int)(AXIS_RANGE * (maxPower[p] >= MAX_THRES ? 1 : maxPower[p] / MAX_THRES));
} }
if (triggered && resetTimer >= RESET_TIME) { if (triggered[p] && resetTimer[p] >= RESET_TIME) {
triggered = false; triggered[p] = false;
resetTimer = 0; resetTimer[p] = 0;
digitalWrite(outPins[maxIndex], LOW); digitalWrite(outPins[p][maxIndex[p]], LOW);
maxPower = 0; maxPower[p] = 0;
maxIndex = -1; maxIndex[p] = -1;
outputValue = 0; outputValue[p] = 0;
} }
for (byte i = 0; i < CHANNELS; i++) { for (byte i = 0; i < CHANNELS; i++) {
if (triggered && i == maxIndex) { if (triggered[p] && i == maxIndex[p]) {
axisValues[i] = outputValue; axisValues[p][i] = outputValue[p];
} else { } else {
axisValues[i] = 0; axisValues[p][i] = 0;
} }
} }
Joystick.setXAxis(axisValues[0]); if (triggered[p]) {
Joystick.setYAxis(axisValues[1]); resetTimer[p]++;
Joystick.setRxAxis(axisValues[2]); }
Joystick.setRyAxis(axisValues[3]); }
Joystick.setXAxis((axisValues[0][0] > 0 ? axisValues[0][0] : -axisValues[0][1]));
Joystick.setYAxis((axisValues[0][2] > 0 ? axisValues[0][2] : -axisValues[0][3]));
Joystick.setRxAxis((axisValues[1][0] > 0 ? axisValues[1][0] : -axisValues[1][1]));
Joystick.setRyAxis((axisValues[1][2] > 0 ? axisValues[1][2] : -axisValues[1][3]));
Joystick.sendState(); Joystick.sendState();
if (triggered) {
resetTimer++;
}
} }

Binary file not shown.

View File

@ -114,7 +114,7 @@ If you prefer to use the Arduino Micro/Leonardo board, please refer to the [Ardu
- Open the `gamecontrollerdb.txt` file in the game folder and add one entry under `#Windows`: - Open the `gamecontrollerdb.txt` file in the game folder and add one entry under `#Windows`:
`030052a8694800006948000000000000,Taiko Controller,+leftx:+a0,+lefty:+a1,+rightx:+a3,+righty:+a4,platform:Windows,` `030052a8694800006948000000000000,Taiko Controller,-leftx:-a0,+leftx:+a0,-lefty:-a1,+lefty:+a1,-rightx:-a3,+rightx:+a3,-righty:-a4,+righty:+a4,platform:Windows,`
This will tell the game that our ESP32 controller is a gamepad called "Taiko Controller", and map the axis to the standard SDL2 library so that the game can recognize the analog inputs. This will tell the game that our ESP32 controller is a gamepad called "Taiko Controller", and map the axis to the standard SDL2 library so that the game can recognize the analog inputs.

View File

@ -114,7 +114,7 @@ Arduino Micro/Leonardoボードを使用する場合は、[Arduino XInputライ
- ゲームフォルダ内の`gamecontrollerdb.txt`ファイルを開き、`#Windows`の下に次のエントリを追加します: - ゲームフォルダ内の`gamecontrollerdb.txt`ファイルを開き、`#Windows`の下に次のエントリを追加します:
`030052a8694800006948000000000000,Taiko Controller,+leftx:+a0,+lefty:+a1,+rightx:+a3,+righty:+a4,platform:Windows,` `030052a8694800006948000000000000,Taiko Controller,-leftx:-a0,+leftx:+a0,-lefty:-a1,+lefty:+a1,-rightx:-a3,+rightx:+a3,-righty:-a4,+righty:+a4,platform:Windows,`
これにより、ゲームはESP32コントローラーが「Taiko Controller」というゲームパッドであることを認識し、標準のSDL2ライブラリに軸をマップするため、ゲームがアナログ入力を認識できるようになります。 これにより、ゲームはESP32コントローラーが「Taiko Controller」というゲームパッドであることを認識し、標準のSDL2ライブラリに軸をマップするため、ゲームがアナログ入力を認識できるようになります。

View File

@ -114,7 +114,7 @@
- 打开游戏文件夹中的`gamecontrollerdb.txt`文件,并在`#Windows`下添加一条条目: - 打开游戏文件夹中的`gamecontrollerdb.txt`文件,并在`#Windows`下添加一条条目:
`030052a8694800006948000000000000,Taiko Controller,+leftx:+a0,+lefty:+a1,+rightx:+a3,+righty:+a4,platform:Windows,` `030052a8694800006948000000000000,Taiko Controller,-leftx:-a0,+leftx:+a0,-lefty:-a1,+lefty:+a1,-rightx:-a3,+rightx:+a3,-righty:-a4,+righty:+a4,platform:Windows,`
这将告诉游戏我们的ESP32控制器是一个名为“Taiko Controller”的游戏手柄并将轴映射到标准SDL2库以便游戏能够识别模拟输入。 这将告诉游戏我们的ESP32控制器是一个名为“Taiko Controller”的游戏手柄并将轴映射到标准SDL2库以便游戏能够识别模拟输入。