From 07cea8839db4dcc94228a66263bf137d6051ac3a Mon Sep 17 00:00:00 2001 From: ShikyC Date: Mon, 27 May 2024 14:00:52 -0700 Subject: [PATCH] Init --- ESP32-S3-Analog/adjustable.h | 66 +------------ ESP32-S3-Analog/params.h | 47 +-------- ESP32-S3-Analog/two_players.h | 181 ++++++++++++++++++++-------------- 3 files changed, 115 insertions(+), 179 deletions(-) diff --git a/ESP32-S3-Analog/adjustable.h b/ESP32-S3-Analog/adjustable.h index 69d0682..bfccc53 100644 --- a/ESP32-S3-Analog/adjustable.h +++ b/ESP32-S3-Analog/adjustable.h @@ -1,5 +1,8 @@ #include "params.h" +// Select which player this board is. 1 for P1 and 2 for P2. +#define PLAYER_SELECT 1 + const byte inPins[CHANNELS] = { P1_L_DON_IN, P1_L_KAT_IN, P1_R_DON_IN, P1_R_KAT_IN }; @@ -10,16 +13,6 @@ const byte sensitivityPins[CHANNELS] = { Cache inputWindow[CHANNELS]; unsigned long power[CHANNELS]; -#ifndef RAW_ANALOG_MODE -unsigned long lastPower[PLAYERS][CHANNELS]; -bool triggered[PLAYERS]; -unsigned long triggeredTime[PLAYERS][CHANNELS]; -int outputValue[PLAYERS] = {0, 0}; -uint resetTimer[PLAYERS] = {0, 0}; -short maxIndex[PLAYERS] = {0, 0}; -float maxPower[PLAYERS] = {0, 0}; -#endif - uint axisValues[CHANNELS] = {0, 0, 0, 0}; Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 10, 4, @@ -29,17 +22,9 @@ Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 10, 4, void setup() { for (byte i = 0; i < CHANNELS; i++) { power[i] = 0; -#ifndef RAW_ANALOG_MODE - lastPower[i] = 0; - triggered = false; -#endif pinMode(inPins[i], INPUT); pinMode(sensitivityPins[i], INPUT); } -#ifndef RAW_ANALOG_MODE - maxIndex = -1; - maxPower = 0; -#endif USB.PID(0x4869); USB.VID(0x4869); USB.productName("Taiko Controller"); @@ -57,65 +42,20 @@ void loop() { for (byte i = 0; i < CHANNELS; i++) { inputWindow[i].put(analogRead(inPins[i])); power[i] = power[i] - inputWindow[i].get(1) + inputWindow[i].get(); -#ifndef RAW_ANALOG_MODE - if (lastPower[i] > maxPower && power[i] < lastPower[i]) { - maxPower = lastPower[i]; - maxIndex = i; - } - lastPower[i] = power[i]; -#else float x = analogRead(sensitivityPins[i]) / 2048.0 - 1; float x2 = x * x; float x3 = x2 * x; float x4 = x3 * x; float v = (1.0 + x + 0.5 * x2 + 0.166667 * x3) * power[i]; axisValues[i] = AXIS_RANGE * (v >= MAX_THRES ? 1 : (v / MAX_THRES)); -#endif } -#ifndef RAW_ANALOG_MODE - if (!triggered && maxPower >= HIT_THRES) { - triggered = true; - digitalWrite(outPins[maxIndex], HIGH); - outputValue = (int)(AXIS_RANGE * (maxPower >= MAX_THRES ? 1 : maxPower / MAX_THRES)); - } - - if (triggered && resetTimer >= RESET_TIME) { - triggered = false; - resetTimer = 0; - digitalWrite(outPins[maxIndex], LOW); - maxPower = 0; - maxIndex = -1; - outputValue = 0; - } - - for (byte i = 0; i < CHANNELS; i++) { - if (triggered && i == maxIndex) { - axisValues[i] = outputValue; - } else { - axisValues[i] = 0; - } - } - - if (triggered) { - resetTimer++; - } -#endif #if PLAYER_SELECT == 1 Joystick.setXAxis(axisValues[0] > axisValues[1] ? axisValues[0] : -axisValues[1]); Joystick.setYAxis(axisValues[2] > axisValues[3] ? axisValues[2] : -axisValues[3]); - Joystick.setRxAxis(0); - Joystick.setRyAxis(0); #elif PLAYER_SELECT == 2 - Joystick.setXAxis(0); - Joystick.setYAxis(0); Joystick.setRxAxis(axisValues[0] > axisValues[1] ? axisValues[0] : -axisValues[1]); Joystick.setRyAxis(axisValues[2] > axisValues[3] ? axisValues[2] : -axisValues[3]); -#else - Joystick.setXAxis(0); - Joystick.setYAxis(0); - Joystick.setRxAxis(0); - Joystick.setRyAxis(0); #endif Joystick.sendState(); diff --git a/ESP32-S3-Analog/params.h b/ESP32-S3-Analog/params.h index 184bd9c..2183962 100644 --- a/ESP32-S3-Analog/params.h +++ b/ESP32-S3-Analog/params.h @@ -1,34 +1,5 @@ -// Enable this mode to pass raw analog data to the game without any post- -// processing. -// The game has a built-in mechanism to calculate which sensor is triggered -// and the force of the hit, so it's recommended to enable this mode. -// This also the provides the most similar experience with the arcade. -// To disable this mode, remove or comment out this line -#define RAW_ANALOG_MODE - -// For MODE_ADJUSTABLE -// Select which player this board is. 1 for P1 and 2 for P2. -#define PLAYER_SELECT 1 - -// For MODE_TWO_PLAYERS -// Sensitivity multipliers for each channel, 1.0 as the baseline. -#define P1_L_DON_SENS 1.0 -#define P1_L_KAT_SENS 1.0 -#define P1_R_DON_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 - -/********************************************** - CHANGING THE FOLLOWING PARAMETERS ARE NOT - RECOMMENDED UNLESS YOU KNOW HOW THEY WORK -***********************************************/ - -// Cache length must be the power of 2 (8, 16, 32, etc.). -// See cache.h for the reason. -#define SAMPLE_CACHE_LENGTH 32 +// Sample window length. Larger values reduce noise but add more latency. +#define SAMPLE_CACHE_LENGTH 64 // The maximum value of a hit (not the minumum value to trigger a heavy hit) // To configure the light and heavy thresholds, do it in the game settings. @@ -51,22 +22,12 @@ #define P1_R_DON_SENS_IN 17 #define P1_R_KAT_SENS_IN 18 +// Controller axis value range #define AXIS_RANGE 1023 -#define PLAYERS 2 +// Number of input channels for each player #define CHANNELS 4 -// The minimum value to trigger a light hit. -// Disabled if RAW_ANALOG_MODE is on. -#define HIT_THRES 1000 - -// If the reset time is too short, the game may not be able to -// receive the input. From testing I found 40 seems to be the -// minimum value so that the game won't miss any hit. If the game -// occassionally miss the drum input, increase this value. -// Disabled if RAW_ANALOG_MODE is on. -#define RESET_TIME 40 - #include #include "joystick.h" #include "cache.h" \ No newline at end of file diff --git a/ESP32-S3-Analog/two_players.h b/ESP32-S3-Analog/two_players.h index adf4526..e2574ca 100644 --- a/ESP32-S3-Analog/two_players.h +++ b/ESP32-S3-Analog/two_players.h @@ -1,48 +1,95 @@ +#include "driver/i2s.h" +#include "freertos/FreeRTOS.h" + #include "params.h" -const byte inPins[PLAYERS][CHANNELS] = { +// Sensitivity multipliers for each channel, 1.0 as the baseline. +#define P1_L_DON_SENS 10.0 +#define P1_L_KAT_SENS 20.0 +#define P1_R_DON_SENS 10.0 +#define P1_R_KAT_SENS 20.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 + +const byte players = 2; + +const byte inPins[players][CHANNELS] = { P1_L_DON_IN, P1_L_KAT_IN, P1_R_DON_IN, P1_R_KAT_IN, P2_L_DON_IN, P2_L_KAT_IN, P2_R_DON_IN, P2_R_KAT_IN }; -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 -}; +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}; -Cache inputWindow[PLAYERS][CHANNELS]; -unsigned long power[PLAYERS][CHANNELS]; +Cache inputWindow[players][CHANNELS]; +unsigned long power[players][CHANNELS]; -#ifndef RAW_ANALOG_MODE -unsigned long lastPower[PLAYERS][CHANNELS]; -bool triggered[PLAYERS]; -unsigned long triggeredTime[PLAYERS][CHANNELS]; -int outputValue[PLAYERS] = {0, 0}; -uint resetTimer[PLAYERS] = {0, 0}; -short maxIndex[PLAYERS] = {0, 0}; -float maxPower[PLAYERS] = {0, 0}; -#endif - -uint axisValues[PLAYERS][CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0}; +uint axisValues[players][CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0}; Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 10, 4, - true, true, false, true, true, false, - false, false, false, false, false); + true, true, false, true, true, false, false, false, false, + false, false); + +uint maxVal[players] = {0, 0}; +uint maxIndex[players] = {-1, -1}; + +void setP1Axes(int index, int value) { + switch (index) { + case 0: + Joystick.setXAxis(value); + Joystick.setYAxis(0); + break; + case 1: + Joystick.setXAxis(-value); + Joystick.setYAxis(0); + break; + case 2: + Joystick.setXAxis(0); + Joystick.setYAxis(value); + break; + case 3: + Joystick.setXAxis(0); + Joystick.setYAxis(-value); + break; + default: + Joystick.setXAxis(0); + Joystick.setYAxis(0); + } +} + +void setP2Axes(int index, int value) { + switch (index) { + case 0: + Joystick.setRxAxis(value); + Joystick.setRyAxis(0); + break; + case 1: + Joystick.setRxAxis(-value); + Joystick.setRyAxis(0); + break; + case 2: + Joystick.setRxAxis(0); + Joystick.setRyAxis(value); + break; + case 3: + Joystick.setRxAxis(0); + Joystick.setRyAxis(-value); + break; + default: + Joystick.setXAxis(0); + Joystick.setYAxis(0); + } +} void setup() { - for (byte p = 0; p < PLAYERS; p++) { + for (byte p = 0; p < players; p++) { for (byte i = 0; i < CHANNELS; i++) { power[p][i] = 0; -#ifndef RAW_ANALOG_MODE - lastPower[p][i] = 0; - triggered[p] = false; -#endif pinMode(inPins[p][i], INPUT); } -#ifndef RAW_ANALOG_MODE - maxIndex[p] = -1; - maxPower[p] = 0; -#endif } USB.PID(0x4869); USB.VID(0x4869); @@ -57,54 +104,42 @@ void setup() { } void loop() { - - for (byte p = 0; p < PLAYERS; p++) { - + for (byte p = 0; p < players; p++) { for (byte i = 0; i < CHANNELS; i++) { inputWindow[p][i].put(analogRead(inPins[p][i])); - power[p][i] = power[p][i] - inputWindow[p][i].get(1) + inputWindow[p][i].get(); -#ifndef RAW_ANALOG_MODE - if (lastPower[p][i] > maxPower[p] && power[p][i] < lastPower[p][i]) { - maxPower[p] = lastPower[p][i]; - maxIndex[p] = i; - } - lastPower[p][i] = power[p][i]; -#else - float v = power[p][i] * sensitivities[p][i]; - axisValues[p][i] = AXIS_RANGE * (v >= MAX_THRES ? 1 : (v / MAX_THRES)); -#endif } -#ifndef RAW_ANALOG_MODE - if (!triggered[p] && maxPower[p] >= HIT_THRES) { - triggered[p] = true; - outputValue[p] = (int)(AXIS_RANGE * (maxPower[p] >= MAX_THRES ? 1 : maxPower[p] / MAX_THRES)); - } - - if (triggered[p] && resetTimer[p] >= RESET_TIME) { - triggered[p] = false; - resetTimer[p] = 0; - maxPower[p] = 0; - maxIndex[p] = -1; - outputValue[p] = 0; - } - - for (byte i = 0; i < CHANNELS; i++) { - if (triggered[p] && i == maxIndex[p]) { - axisValues[p][i] = outputValue[p]; - } else { - axisValues[p][i] = 0; - } - } - - if (triggered[p]) { - resetTimer[p]++; - } -#endif } - Joystick.setXAxis(axisValues[0][0] > axisValues[0][1] ? axisValues[0][0] : -axisValues[0][1]); - Joystick.setYAxis(axisValues[0][2] > axisValues[0][3] ? axisValues[0][2] : -axisValues[0][3]); - Joystick.setRxAxis(axisValues[1][0] > axisValues[1][1] ? axisValues[1][0] : -axisValues[1][1]); - Joystick.setRyAxis(axisValues[1][2] > axisValues[1][3] ? axisValues[1][2] : -axisValues[1][3]); + for (byte p = 0; p < players; p++) { + maxVal[p] = 0; + maxIndex[p] = -1; + + for (byte i = 0; i < CHANNELS; i++) { + power[p][i] = power[p][i] - inputWindow[p][i].get(1) + + inputWindow[p][i].get(); + float v = power[p][i] * sensitivities[p][i]; + axisValues[p][i] = + AXIS_RANGE * (v >= MAX_THRES ? 1 : (v / MAX_THRES)); + if (axisValues[p][i] > maxVal[p]) { + maxVal[p] = axisValues[p][i]; + maxIndex[p] = i; + } + } + + if (maxIndex[p] >= 0) { + if (p == 0) { + setP1Axes(maxIndex[p], maxVal[p]); + } else if (p == 1) { + setP2Axes(maxIndex[p], maxVal[p]); + } + } else { + if (p == 0) { + setP1Axes(-1, 0); + } else if (p == 1) { + setP2Axes(-1, 0); + } + } + } + Joystick.sendState(); }