diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index fc35e44..ee9b3e8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -27,6 +27,10 @@ Kadano - Testing Vurj - Hardware Design +Altimor - Stickmap visualizer + +venus23gg - Stickmaps + # Libraries DogeSSBM - DogeBawx - 2021-12-18 - GPLv3 - Modified diff --git a/PhobGCC/PhobGCC.ino b/PhobGCC/PhobGCC.ino index ce06556..a4b4dbb 100644 --- a/PhobGCC/PhobGCC.ino +++ b/PhobGCC/PhobGCC.ino @@ -92,7 +92,7 @@ void loop() { }else{//just show desired stick position displayNotch(currentCalStep, true, _notchAngleDefaults, _btn); } - readSticks(true,false, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, currentCalStep, false); + readSticks(true,false, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, currentCalStep); } else{//WHICHSTICK == CSTICK if(currentCalStep >= _noOfCalibrationPoints){//adjust notch angles @@ -112,11 +112,11 @@ void loop() { }else{//just show desired stick position displayNotch(currentCalStep, false, _notchAngleDefaults, _btn); } - readSticks(false,true, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, currentCalStep, false); + readSticks(false,true, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, currentCalStep); } } else if(running){ //if not calibrating read the sticks normally - readSticks(true,true, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, currentCalStep, false); + readSticks(true,true, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, currentCalStep); } } diff --git a/PhobGCC/common/filter.h b/PhobGCC/common/filter.h index 00ef381..0f4b45d 100644 --- a/PhobGCC/common/filter.h +++ b/PhobGCC/common/filter.h @@ -44,7 +44,25 @@ void runMedian(float &val, float valArray[MEDIANLEN], unsigned int &medianIndex) #endif } -void recomputeGains(const FilterGains &gains, FilterGains &normGains){ +float velDampFromSnapback(const int snapback) { + if(snapback >= 0) { + return 0.125 * pow(2, (snapback-4)/3.0);//4 should yield 0.125, 10 should yield 0.5, don't care about 0 + } else { + return 1 - 0.25 * pow(2, (snapback+4)/3.0);//-1 should yield 0.5, -10 should yield 0.938, don't care about 0 + } +} + +void recomputeGains(const ControlConfig controls, FilterGains &gains, FilterGains &normGains) { + //Adjust the snapback and smoothing gains according to the controls config + gains.xVelDamp = velDampFromSnapback(controls.xSnapback); + gains.yVelDamp = velDampFromSnapback(controls.ySnapback); + + gains.xSmoothing = controls.axSmoothing/10.0f; + gains.ySmoothing = controls.aySmoothing/10.0f; + + gains.cXSmoothing = controls.cxSmoothing/10.0f; + gains.cYSmoothing = controls.cySmoothing/10.0f; + //Recompute the intermediate gains used directly by the kalman filter //This happens according to the time between loop iterations. //Before, this happened every iteration of runKalman, but now @@ -59,8 +77,14 @@ void recomputeGains(const FilterGains &gains, FilterGains &normGains){ normGains.yVelDecay = gains.yVelDecay * timeFactor; normGains.xVelPosFactor = gains.xVelPosFactor * timeFactor; normGains.yVelPosFactor = gains.yVelPosFactor * timeFactor; - normGains.xVelDamp = gains.xVelDamp * timeDivisor; - normGains.yVelDamp = gains.yVelDamp * timeDivisor; + normGains.xVelDamp = gains.xVelDamp; + if(controls.xSnapback >= 0) { + normGains.xVelDamp *= timeDivisor; + } + normGains.yVelDamp = gains.yVelDamp; + if(controls.ySnapback >= 0) { + normGains.yVelDamp *= timeDivisor; + } normGains.velThresh = 1/(gains.velThresh * timeFactor);//slight optimization by using the inverse normGains.accelThresh = 1/(gains.accelThresh * timeFactor); normGains.velThresh = normGains.velThresh*normGains.velThresh;//square it because it's used squared @@ -136,7 +160,7 @@ void runKalman(float &xPosFilt, float &yPosFilt, const float xZ,const float yZ, //term 3: the integral error correction term //But if we xSnapback or ySnapback is zero, we skip the calculation - if(controls.xSnapback != 0){ + if(controls.xSnapback > 0){ xVelFilt = velWeight1*xVel + (1-normGains.xVelDecay)*velWeight2*oldXVelFilt + normGains.xVelPosFactor*oldXPosDiff; const float xPosWeightVelAcc = 1 - fmin(1, xVelSmooth*xVelSmooth*normGains.velThresh + xAccel*xAccel*normGains.accelThresh); @@ -145,11 +169,19 @@ void runKalman(float &xPosFilt, float &yPosFilt, const float xZ,const float yZ, xPosFilt = xPosWeight1*xPos + xPosWeight2*(oldXPosFilt + (1-normGains.xVelDamp)*xVelFilt); + } else if(controls.xSnapback < 0) { + const float xLPF = oldXPosFilt*normGains.xVelDamp + xPos*(1-normGains.xVelDamp); + + const float xPosWeightVelAcc = 1 - fmin(1, xVelSmooth*xVelSmooth*normGains.velThresh + xAccel*xAccel*normGains.accelThresh); + const float xPosWeight1 = fmax(xPosWeightVelAcc, stickDistance6); + const float xPosWeight2 = 1-xPosWeight1; + + xPosFilt = xPosWeight1*xPos + xPosWeight2*xLPF; } else { xPosFilt = xPos; } - if(controls.ySnapback != 0){ + if(controls.ySnapback > 0){ yVelFilt = velWeight1*yVel + (1-normGains.yVelDecay)*velWeight2*oldYVelFilt + normGains.yVelPosFactor*oldYPosDiff; const float yPosWeightVelAcc = 1 - fmin(1, yVelSmooth*yVelSmooth*normGains.velThresh + yAccel*yAccel*normGains.accelThresh); @@ -158,6 +190,14 @@ void runKalman(float &xPosFilt, float &yPosFilt, const float xZ,const float yZ, yPosFilt = yPosWeight1*yPos + yPosWeight2*(oldYPosFilt + (1-normGains.yVelDamp)*yVelFilt); + } else if(controls.ySnapback < 0) { + const float yLPF = oldYPosFilt*normGains.yVelDamp + yPos*(1-normGains.yVelDamp); + + const float yPosWeightVelAcc = 1 - fmin(1, yVelSmooth*yVelSmooth*normGains.velThresh + yAccel*yAccel*normGains.accelThresh); + const float yPosWeight1 = fmax(yPosWeightVelAcc, stickDistance6); + const float yPosWeight2 = 1-yPosWeight1; + + yPosFilt = yPosWeight1*yPos + yPosWeight2*yLPF; } else { yPosFilt = yPos; } diff --git a/PhobGCC/common/phobGCC.h b/PhobGCC/common/phobGCC.h index 0b5480f..8f73da6 100644 --- a/PhobGCC/common/phobGCC.h +++ b/PhobGCC/common/phobGCC.h @@ -30,7 +30,7 @@ using std::max; //#define BUILD_DEV //This is just an integer. -#define SW_VERSION 28 +#define SW_VERSION 29 ControlConfig _controls{ .jumpConfig = DEFAULTJUMP, @@ -60,7 +60,7 @@ ControlConfig _controls{ .rTrigInitial = 0, .xSnapback = 4, .ySnapback = 4, - .snapbackMin = 0, + .snapbackMin = -10, .snapbackMax = 10, .snapbackDefault = 4, .snapbackFactoryAX = 4, @@ -84,10 +84,28 @@ ControlConfig _controls{ .waveshapingFactoryAX = 0, .waveshapingFactoryAY = 0, .waveshapingFactoryCX = 0, - .waveshapingFactoryCY = 0 + .waveshapingFactoryCY = 0, + .astickCardinalSnapping = 6, + .cstickCardinalSnapping = 6, + .cardinalSnappingMin = -1, + .cardinalSnappingMax = 6, + .cardinalSnappingDefault = 6, + .astickAnalogScaler = 100, + .cstickAnalogScaler = 100, + .analogScalerMin = 82, + .analogScalerMax = 125, + .analogScalerDefault = 100, + .tournamentToggle = 0, + .tournamentToggleMin = 0, + .tournamentToggleMax = 5, +#ifdef PICO_RP2040 + .interlaceOffset = 0, + .interlaceOffsetMin = -150, + .interlaceOffsetMax = 150, +#endif //PICO_RP2040 }; -FilterGains _gains {//these values are for 800 hz, recomputeGains converts them to what is needed for the actual frequenc +FilterGains _gains {//these values are for 800 hz, recomputeGains converts them to what is needed for the actual frequency (1000 Hz) .maxStick = 100, .xVelDecay = 0.1, .yVelDecay = 0.1, @@ -135,10 +153,6 @@ int calcRumblePower(const int rumble){ } } -float velDampFromSnapback(const int snapback){ - return 0.125 * pow(2, (snapback-4)/3.0);//4 should yield 0.125, 10 should yield 0.5, don't care about 0 -} - void freezeSticks(const int time, Buttons &btn, Buttons &hardware) { btn.Cx = (uint8_t) (255); btn.Cy = (uint8_t) (255); @@ -235,15 +249,10 @@ void showRumble(const int time, Buttons &btn, Buttons &hardware, ControlConfig & clearButtons(time, btn, hardware); setRumbleSetting(controls.rumble); -#ifdef BATCHSETTINGS - commitSettings(); -#endif //BATCHSETTINGS } void changeRumble(const Increase increase, Buttons &btn, Buttons &hardware, ControlConfig &controls) { -#ifdef ARDUINO - Serial.println("changing rumble"); -#endif //ARDUINO + debug_println("changing rumble"); if(increase == INCREASE) { controls.rumble += 1; } else { @@ -274,50 +283,34 @@ void changeAutoInit(Buttons &btn, Buttons &hardware, ControlConfig &controls) { freezeSticksToggleIndicator(2000, btn, hardware, (controls.autoInit == 1)); setAutoInitSetting(controls.autoInit); -#ifdef BATCHSETTINGS - commitSettings(); -#endif //BATCHSETTINGS } void adjustSnapback(const WhichAxis axis, const Increase increase, Buttons &btn, Buttons &hardware, ControlConfig &controls, FilterGains &gains, FilterGains &normGains){ -#ifdef ARDUINO - Serial.println("adjusting snapback filtering"); -#endif //ARDUINO + debug_println("adjusting snapback filtering"); if(axis == XAXIS && increase == INCREASE){ controls.xSnapback = min(controls.xSnapback+1, controls.snapbackMax); -#ifdef ARDUINO - Serial.print("x snapback filtering increased to:"); - Serial.println(controls.xSnapback); -#endif //ARDUINO + debug_print("x snapback filtering increased to:"); + debug_println(controls.xSnapback); } else if(axis == XAXIS && increase == DECREASE){ controls.xSnapback = max(controls.xSnapback-1, controls.snapbackMin); -#ifdef ARDUINO - Serial.print("x snapback filtering decreased to:"); - Serial.println(controls.xSnapback); -#endif //ARDUINO + debug_print("x snapback filtering decreased to:"); + debug_println(controls.xSnapback); } if(axis == YAXIS && increase == INCREASE){ controls.ySnapback = min(controls.ySnapback+1, controls.snapbackMax); -#ifdef ARDUINO - Serial.print("y snapback filtering increased to:"); - Serial.println(controls.ySnapback); -#endif //ARDUINO + debug_print("y snapback filtering increased to:"); + debug_println(controls.ySnapback); } else if(axis == YAXIS && increase == DECREASE){ controls.ySnapback = max(controls.ySnapback-1, controls.snapbackMin); -#ifdef ARDUINO - Serial.print("y snapback filtering decreased to:"); - Serial.println(controls.ySnapback); -#endif //ARDUINO + debug_print("y snapback filtering decreased to:"); + debug_println(controls.ySnapback); } - gains.xVelDamp = velDampFromSnapback(controls.xSnapback); - gains.yVelDamp = velDampFromSnapback(controls.ySnapback); - //recompute the intermediate gains used directly by the kalman filter - recomputeGains(gains, normGains); + recomputeGains(controls, gains, normGains); btn.Cx = (uint8_t) (controls.xSnapback + _floatOrigin); btn.Cy = (uint8_t) (controls.ySnapback + _floatOrigin); @@ -326,15 +319,10 @@ void adjustSnapback(const WhichAxis axis, const Increase increase, Buttons &btn, setXSnapbackSetting(controls.xSnapback); setYSnapbackSetting(controls.ySnapback); -#ifdef BATCHSETTINGS - commitSettings(); -#endif //BATCHSETTINGS } void adjustWaveshaping(const WhichStick whichStick, const WhichAxis axis, const Increase increase, Buttons &btn, Buttons &hardware, ControlConfig &controls){ -#ifdef ARDUINO - Serial.println("adjusting waveshaping"); -#endif //ARDUINO + debug_println("adjusting waveshaping"); if(whichStick == ASTICK){ if(axis == XAXIS){ if(increase == INCREASE){ @@ -372,68 +360,48 @@ void adjustWaveshaping(const WhichStick whichStick, const WhichAxis axis, const btn.Cx = (uint8_t) (controls.cxWaveshaping + _floatOrigin); btn.Cy = (uint8_t) (controls.cyWaveshaping + _floatOrigin); } -#ifdef BATCHSETTINGS - commitSettings(); -#endif //BATCHSETTINGS clearButtons(750, btn, hardware); } void adjustSmoothing(const WhichAxis axis, const Increase increase, Buttons &btn, Buttons &hardware, ControlConfig &controls, FilterGains &gains, FilterGains &normGains) { -#ifdef ARDUINO - Serial.println("Adjusting Smoothing"); -#endif //ARDUINO + debug_println("Adjusting Smoothing"); if (axis == XAXIS && increase == INCREASE) { controls.axSmoothing++; if(controls.axSmoothing > controls.smoothingMax) { controls.axSmoothing = controls.smoothingMax; } - gains.xSmoothing = controls.axSmoothing/10.0f; setXSmoothingSetting(controls.axSmoothing); -#ifdef ARDUINO - Serial.print("X Smoothing increased to:"); - Serial.println(controls.axSmoothing); -#endif //ARDUINO + debug_print("X Smoothing increased to:"); + debug_println(controls.axSmoothing); } else if(axis == XAXIS && increase == DECREASE) { controls.axSmoothing--; if(controls.axSmoothing < controls.smoothingMin) { controls.axSmoothing = controls.smoothingMin; } - gains.xSmoothing = controls.axSmoothing/10.0f; setXSmoothingSetting(controls.axSmoothing); -#ifdef ARDUINO - Serial.print("X Smoothing decreased to:"); - Serial.println(controls.axSmoothing); -#endif //ARDUINO + debug_print("X Smoothing decreased to:"); + debug_println(controls.axSmoothing); } else if(axis == YAXIS && increase == INCREASE) { controls.aySmoothing++; if (controls.aySmoothing > controls.smoothingMax) { controls.aySmoothing = controls.smoothingMax; } - gains.ySmoothing = controls.aySmoothing/10.0f; setYSmoothingSetting(controls.aySmoothing); -#ifdef ARDUINO - Serial.print("Y Smoothing increased to:"); - Serial.println(controls.aySmoothing); -#endif //ARDUINO + debug_print("Y Smoothing increased to:"); + debug_println(controls.aySmoothing); } else if(axis == YAXIS && increase == DECREASE) { controls.aySmoothing--; if (controls.aySmoothing < controls.smoothingMin) { controls.aySmoothing = controls.smoothingMin; } - gains.ySmoothing = controls.aySmoothing/10.0f; setYSmoothingSetting(controls.aySmoothing); -#ifdef ARDUINO - Serial.print("Y Smoothing decreased to:"); - Serial.println(controls.aySmoothing); -#endif //ARDUINO + debug_print("Y Smoothing decreased to:"); + debug_println(controls.aySmoothing); } -#ifdef BATCHSETTINGS - commitSettings(); -#endif //BATCHSETTINGS //recompute the intermediate gains used directly by the kalman filter - recomputeGains(gains, normGains); + recomputeGains(controls, gains, normGains); btn.Cx = (uint8_t) (_floatOrigin + controls.axSmoothing); btn.Cy = (uint8_t) (_floatOrigin + controls.aySmoothing); @@ -458,60 +426,43 @@ void showAstickSettings(Buttons &btn, Buttons &hardware, const ControlConfig &co } void adjustCstickSmoothing(const WhichAxis axis, const Increase increase, Buttons &btn, Buttons &hardware, ControlConfig &controls, FilterGains &gains, FilterGains &normGains) { -#ifdef ARDUINO - Serial.println("Adjusting C-Stick Smoothing"); -#endif //ARDUINO + debug_println("Adjusting C-Stick Smoothing"); if (axis == XAXIS && increase == INCREASE) { controls.cxSmoothing++; if(controls.cxSmoothing > controls.smoothingMax) { controls.cxSmoothing = controls.smoothingMax; } - gains.cXSmoothing = controls.cxSmoothing/10.0f; setCxSmoothingSetting(controls.cxSmoothing); -#ifdef ARDUINO - Serial.print("C-Stick X Smoothing increased to:"); - Serial.println(controls.cxSmoothing); -#endif //ARDUINO + debug_print("C-Stick X Smoothing increased to:"); + debug_println(controls.cxSmoothing); } else if(axis == XAXIS && increase == DECREASE) { controls.cxSmoothing--; if(controls.cxSmoothing < controls.smoothingMin) { controls.cxSmoothing = controls.smoothingMin; } - gains.cXSmoothing = controls.cxSmoothing/10.0f; setCxSmoothingSetting(controls.cxSmoothing); -#ifdef ARDUINO - Serial.print("C-Stick X Smoothing decreased to:"); - Serial.println(controls.cxSmoothing); -#endif //ARDUINO + debug_print("C-Stick X Smoothing decreased to:"); + debug_println(controls.cxSmoothing); } else if(axis == YAXIS && increase == INCREASE) { controls.cySmoothing++; if (controls.cySmoothing > controls.smoothingMax) { controls.cySmoothing = controls.smoothingMax; } - gains.cYSmoothing = controls.cySmoothing/10.0f; setCySmoothingSetting(controls.cySmoothing); -#ifdef ARDUINO - Serial.print("C-Stick Y Smoothing increased to:"); - Serial.println(controls.cySmoothing); -#endif //ARDUINO + debug_print("C-Stick Y Smoothing increased to:"); + debug_println(controls.cySmoothing); } else if(axis == YAXIS && increase == DECREASE) { controls.cySmoothing--; if (controls.cySmoothing < controls.smoothingMin) { controls.cySmoothing = controls.smoothingMin; } - gains.cYSmoothing = controls.cySmoothing/10.0f; setCySmoothingSetting(controls.cySmoothing); -#ifdef ARDUINO - Serial.print("C-Stick Y Smoothing decreased to:"); - Serial.println(controls.cySmoothing); -#endif //ARDUINO + debug_print("C-Stick Y Smoothing decreased to:"); + debug_println(controls.cySmoothing); } -#ifdef BATCHSETTINGS - commitSettings(); -#endif //BATCHSETTINGS //recompute the intermediate gains used directly by the kalman filter - recomputeGains(gains, normGains); + recomputeGains(controls, gains, normGains); btn.Cx = (uint8_t) (_floatOrigin + controls.cxSmoothing); btn.Cy = (uint8_t) (_floatOrigin + controls.cySmoothing); @@ -520,53 +471,40 @@ void adjustCstickSmoothing(const WhichAxis axis, const Increase increase, Button } void adjustCstickOffset(const WhichAxis axis, const Increase increase, Buttons &btn, Buttons &hardware, ControlConfig &controls) { -#ifdef ARDUINO - Serial.println("Adjusting C-stick Offset"); -#endif //ARDUINO + debug_println("Adjusting C-stick Offset"); if(axis == XAXIS && increase == INCREASE) { controls.cXOffset++; if(controls.cXOffset > controls.cMax) { controls.cXOffset = controls.cMax; } setCxOffsetSetting(controls.cXOffset); -#ifdef ARDUINO - Serial.print("X offset increased to:"); - Serial.println(controls.cXOffset); -#endif //ARDUINO + debug_print("X offset increased to:"); + debug_println(controls.cXOffset); } else if(axis == XAXIS && increase == DECREASE) { controls.cXOffset--; if(controls.cXOffset < controls.cMin) { controls.cXOffset = controls.cMin; } setCxOffsetSetting(controls.cXOffset); -#ifdef ARDUINO - Serial.print("X offset decreased to:"); - Serial.println(controls.cXOffset); -#endif //ARDUINO + debug_print("X offset decreased to:"); + debug_println(controls.cXOffset); } else if(axis == YAXIS && increase == INCREASE) { controls.cYOffset++; if(controls.cYOffset > controls.cMax) { controls.cYOffset = controls.cMax; } setCyOffsetSetting(controls.cYOffset); -#ifdef ARDUINO - Serial.print("Y offset increased to:"); - Serial.println(controls.cYOffset); -#endif //ARDUINO + debug_print("Y offset increased to:"); + debug_println(controls.cYOffset); } else if(axis == YAXIS && increase == DECREASE) { controls.cYOffset--; if(controls.cYOffset < controls.cMin) { controls.cYOffset = controls.cMin; } setCyOffsetSetting(controls.cYOffset); -#ifdef ARDUINO - Serial.print("Y offset decreased to:"); - Serial.println(controls.cYOffset); -#endif //ARDUINO + debug_print("Y offset decreased to:"); + debug_println(controls.cYOffset); } -#ifdef BATCHSETTINGS - commitSettings(); -#endif //BATCHSETTINGS btn.Cx = (uint8_t) (_floatOrigin + controls.cXOffset); btn.Cy = (uint8_t) (_floatOrigin + controls.cYOffset); @@ -590,6 +528,79 @@ void showCstickSettings(Buttons &btn, Buttons &hardware, ControlConfig &controls clearButtons(2000, btn, hardware); } +void adjustCardinalSnapping(const WhichStick whichStick, const Increase increase, Buttons &btn, Buttons &hardware, ControlConfig &controls) { + if(whichStick == ASTICK && increase == INCREASE) { + controls.astickCardinalSnapping++; + if(controls.astickCardinalSnapping > controls.cardinalSnappingMax) { + controls.astickCardinalSnapping = controls.cardinalSnappingMax; + } + setCardinalSnappingSetting(controls.astickCardinalSnapping, ASTICK); + } else if(whichStick == ASTICK && increase == DECREASE) { + controls.astickCardinalSnapping--; + if(controls.astickCardinalSnapping < controls.cardinalSnappingMin) { + controls.astickCardinalSnapping = controls.cardinalSnappingMin; + } + setCardinalSnappingSetting(controls.astickCardinalSnapping, ASTICK); + } else if(whichStick == CSTICK && increase == INCREASE) { + controls.cstickCardinalSnapping++; + if(controls.cstickCardinalSnapping > controls.cardinalSnappingMax) { + controls.cstickCardinalSnapping = controls.cardinalSnappingMax; + } + setCardinalSnappingSetting(controls.cstickCardinalSnapping, CSTICK); + } else if(whichStick == CSTICK && increase == DECREASE) { + controls.cstickCardinalSnapping--; + if(controls.cstickCardinalSnapping < controls.cardinalSnappingMin) { + controls.cstickCardinalSnapping = controls.cardinalSnappingMin; + } + setCardinalSnappingSetting(controls.cstickCardinalSnapping, CSTICK); + } + + btn.Ax = (uint8_t) (_floatOrigin + controls.astickCardinalSnapping); + btn.Ay = (uint8_t) (_floatOrigin + controls.astickCardinalSnapping); + + btn.Cx = (uint8_t) (_floatOrigin + controls.cstickCardinalSnapping); + btn.Cy = (uint8_t) (_floatOrigin + controls.cstickCardinalSnapping); + + clearButtons(750, btn, hardware); + +} + +void adjustAnalogScaler(const WhichStick whichStick, const Increase increase, Buttons &btn, Buttons &hardware, ControlConfig &controls) { + if(whichStick == ASTICK && increase == INCREASE) { + controls.astickAnalogScaler++; + if(controls.astickAnalogScaler > controls.analogScalerMax) { + controls.astickAnalogScaler = controls.analogScalerMax; + } + setAnalogScalerSetting(controls.astickAnalogScaler, ASTICK); + } else if(whichStick == ASTICK && increase == DECREASE) { + controls.astickAnalogScaler--; + if(controls.astickAnalogScaler < controls.analogScalerMin) { + controls.astickAnalogScaler = controls.analogScalerMin; + } + setAnalogScalerSetting(controls.astickAnalogScaler, ASTICK); + } else if(whichStick == CSTICK && increase == INCREASE) { + controls.cstickAnalogScaler++; + if(controls.cstickAnalogScaler > controls.analogScalerMax) { + controls.cstickAnalogScaler = controls.analogScalerMax; + } + setAnalogScalerSetting(controls.cstickAnalogScaler, CSTICK); + } else if(whichStick == CSTICK && increase == DECREASE) { + controls.cstickAnalogScaler--; + if(controls.cstickAnalogScaler < controls.analogScalerMin) { + controls.cstickAnalogScaler = controls.analogScalerMin; + } + setAnalogScalerSetting(controls.cstickAnalogScaler, CSTICK); + } + + btn.Ax = (uint8_t) (_floatOrigin + controls.astickAnalogScaler); + btn.Ay = (uint8_t) (_floatOrigin + controls.astickAnalogScaler); + + btn.Cx = (uint8_t) (_floatOrigin + controls.cstickAnalogScaler); + btn.Cy = (uint8_t) (_floatOrigin + controls.cstickAnalogScaler); + + clearButtons(750, btn, hardware); +} + void adjustTriggerOffset(const WhichTrigger trigger, const Increase increase, Buttons &btn, Buttons &hardware, ControlConfig &controls) { if(trigger == LTRIGGER && increase == INCREASE) { controls.lTriggerOffset++; @@ -615,9 +626,6 @@ void adjustTriggerOffset(const WhichTrigger trigger, const Increase increase, Bu setLOffsetSetting(controls.lTriggerOffset); setROffsetSetting(controls.rTriggerOffset); -#ifdef BATCHSETTINGS - commitSettings(); -#endif //BATCHSETTINGS btn.La = (uint8_t) controls.lTriggerOffset; btn.Ra = (uint8_t) controls.rTriggerOffset; @@ -638,6 +646,24 @@ void adjustTriggerOffset(const WhichTrigger trigger, const Increase increase, Bu clearButtons(100, btn, hardware); } +void changeTournamentToggle(Buttons &btn, Buttons &hardware, ControlConfig &controls) { + if(controls.tournamentToggle == controls.tournamentToggleMax) { + controls.tournamentToggle = 0; + } else { + controls.tournamentToggle++; + } + + setTournamentToggleSetting(controls.tournamentToggle); + + btn.Ax = (uint8_t) (_floatOrigin); + btn.Ay = (uint8_t) (_floatOrigin); + + btn.Cx = (uint8_t) (_floatOrigin); + btn.Cy = (uint8_t) (_floatOrigin + controls.tournamentToggle+1); + + clearButtons(750, btn, hardware); +} + //apply digital button swaps for L, R, or Z jumping void applyJump(const ControlConfig &controls, const Buttons &hardware, Buttons &btn){ switch(controls.jumpConfig){ @@ -672,45 +698,36 @@ void applyJump(const ControlConfig &controls, const Buttons &hardware, Buttons & } void setJumpConfig(JumpConfig jumpConfig, ControlConfig &controls){ -#ifdef ARDUINO - Serial.print("setting jump to: "); -#endif //ARDUINO + debug_print("setting jump to: "); if (controls.jumpConfig == jumpConfig) { controls.jumpConfig = DEFAULTJUMP; -#ifdef ARDUINO - Serial.println("normal again"); -#endif //ARDUINO + debug_println("normal again"); } else { controls.jumpConfig = jumpConfig; -#ifdef ARDUINO switch (jumpConfig) { case SWAP_XZ: - Serial.println("X<->Z"); + debug_println("X<->Z"); break; case SWAP_YZ: - Serial.println("Y<->Z"); + debug_println("Y<->Z"); break; case SWAP_XL: - Serial.println("X<->L"); + debug_println("X<->L"); break; case SWAP_YL: - Serial.println("Y<->L"); + debug_println("Y<->L"); break; case SWAP_XR: - Serial.println("X<->R"); + debug_println("X<->R"); break; case SWAP_YR: - Serial.println("Y<->R"); + debug_println("Y<->R"); break; default: - Serial.println("normal"); + debug_println("normal"); } -#endif //ARDUINO } setJumpSetting(controls.jumpConfig); -#ifdef BATCHSETTINGS - commitSettings(); -#endif //BATCHSETTINGS } void toggleExtra(ExtrasSlot slot, Buttons &btn, Buttons &hardware, ControlConfig &controls){ @@ -805,9 +822,6 @@ void nextTriggerState(WhichTrigger trigger, Buttons &btn, Buttons &hardware, Con } setLSetting(controls.lConfig); setRSetting(controls.rConfig); -#ifdef BATCHSETTINGS - commitSettings(); -#endif //BATCHSETTINGS //if the modes are incompatible due to mode 5, make it show -100 on the stick that isn't mode 5 //(user-facing mode 5) @@ -852,7 +866,7 @@ void initializeButtons(const Pins &pin, Buttons &btn,int &startUpLa, int &startU } //Take tempCalPoints and use it to generate new stick cal parameters to be used -void applyCalFromPoints(const WhichStick whichStick, float notchAngles[], const float tempCalPointsX[], const float tempCalPointsY[], NotchStatus notchStatus[], float measuredNotchAngles[], StickParams &stickParams) { +void applyCalFromPoints(const WhichStick whichStick, float notchAngles[], const float tempCalPointsX[], const float tempCalPointsY[], NotchStatus notchStatus[], float measuredNotchAngles[], StickParams &stickParams, const ControlConfig &controls) { //recall previous notch angles getNotchAnglesSetting(notchAngles, whichStick); //make temp temp cal points that are missing all tertiary notches so that we get a neutral grid @@ -871,7 +885,7 @@ void applyCalFromPoints(const WhichStick whichStick, float notchAngles[], const cleanCalPoints(tempCalPointsX, tempCalPointsY, _notchAngleDefaults, cleanedPointsX, cleanedPointsY, notchPointsX, notchPointsY, notchStatus); float transformedX[_noOfNotches+1]; float transformedY[_noOfNotches+1]; - transformCalPoints(cleanedPointsX, cleanedPointsY, transformedX, transformedY, stickParams); + transformCalPoints(cleanedPointsX, cleanedPointsY, transformedX, transformedY, stickParams, controls, whichStick); //compute the angles for those notches into measuredNotchAngles, using the default angles for the diagonals computeStickAngles(transformedX, transformedY, measuredNotchAngles); //clean full cal points again, feeding those angles in @@ -966,10 +980,8 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai //get the x-axis snapback correction controls.xSnapback = getXSnapbackSetting(); -#ifdef ARDUINO - Serial.print("the xSnapback value from eeprom is:"); - Serial.println(controls.xSnapback); -#endif //ARDUINO + debug_print("the xSnapback value from eeprom is:"); + debug_println(controls.xSnapback); if(controls.xSnapback < controls.snapbackMin) { controls.xSnapback = controls.snapbackDefault; numberOfNaN++; @@ -977,18 +989,11 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai controls.xSnapback = controls.snapbackDefault; numberOfNaN++; } - gains.xVelDamp = velDampFromSnapback(controls.xSnapback); -#ifdef ARDUINO - Serial.print("the xVelDamp value from eeprom is:"); - Serial.println(gains.xVelDamp); -#endif //ARDUINO //get the y-ayis snapback correction controls.ySnapback = getYSnapbackSetting(); -#ifdef ARDUINO - Serial.print("the ySnapback value from eeprom is:"); - Serial.println(controls.ySnapback); -#endif //ARDUINO + debug_print("the ySnapback value from eeprom is:"); + debug_println(controls.ySnapback); if(controls.ySnapback < controls.snapbackMin) { controls.ySnapback = controls.snapbackDefault; numberOfNaN++; @@ -996,110 +1001,75 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai controls.ySnapback = controls.snapbackDefault; numberOfNaN++; } - gains.yVelDamp = velDampFromSnapback(controls.ySnapback); -#ifdef ARDUINO - Serial.print("the yVelDamp value from eeprom is:"); - Serial.println(gains.yVelDamp); -#endif //ARDUINO //get the x-axis smoothing value controls.axSmoothing = getXSmoothingSetting(); -#ifdef ARDUINO - Serial.print("the xSmoothing value from eeprom is:"); - Serial.println(controls.axSmoothing); -#endif //ARDUINO + debug_print("the xSmoothing value from eeprom is:"); + debug_println(controls.axSmoothing); if(controls.axSmoothing > controls.smoothingMax) { controls.axSmoothing = controls.smoothingMin; numberOfNaN++; -#ifdef ARDUINO - Serial.print("the xSmoothing value was adjusted to:"); - Serial.println(controls.axSmoothing); -#endif //ARDUINO + debug_print("the xSmoothing value was adjusted to:"); + debug_println(controls.axSmoothing); } else if(controls.axSmoothing < controls.smoothingMin) { controls.axSmoothing = controls.smoothingMin; numberOfNaN++; -#ifdef ARDUINO - Serial.print("the xSmoothing value was adjusted to:"); - Serial.println(controls.axSmoothing); -#endif //ARDUINO + debug_print("the xSmoothing value was adjusted to:"); + debug_println(controls.axSmoothing); } - gains.xSmoothing = controls.axSmoothing / 10.0f; //get the y-axis smoothing value controls.aySmoothing = getYSmoothingSetting(); -#ifdef ARDUINO - Serial.print("the ySmoothing value from eeprom is:"); - Serial.println(controls.aySmoothing); -#endif //ARDUINO + debug_print("the ySmoothing value from eeprom is:"); + debug_println(controls.aySmoothing); if(controls.aySmoothing > controls.smoothingMax) { controls.aySmoothing = controls.smoothingMin; numberOfNaN++; -#ifdef ARDUINO - Serial.print("the ySmoothing value was adjusted to:"); - Serial.println(controls.aySmoothing); -#endif //ARDUINO + debug_print("the ySmoothing value was adjusted to:"); + debug_println(controls.aySmoothing); } else if(controls.aySmoothing < controls.smoothingMin) { controls.aySmoothing = controls.smoothingMin; numberOfNaN++; -#ifdef ARDUINO - Serial.print("the ySmoothing value was adjusted to:"); - Serial.println(controls.aySmoothing); -#endif //ARDUINO + debug_print("the ySmoothing value was adjusted to:"); + debug_println(controls.aySmoothing); } - gains.ySmoothing = controls.aySmoothing / 10.0f; //get the c-stick x-axis smoothing value controls.cxSmoothing = getCxSmoothingSetting(); -#ifdef ARDUINO - Serial.print("the cXSmoothing value from eeprom is:"); - Serial.println(controls.cxSmoothing); -#endif //ARDUINO + debug_print("the cXSmoothing value from eeprom is:"); + debug_println(controls.cxSmoothing); if(controls.cxSmoothing > controls.smoothingMax) { controls.cxSmoothing = controls.smoothingMin; numberOfNaN++; -#ifdef ARDUINO - Serial.print("the cXSmoothing value was adjusted to:"); - Serial.println(controls.cxSmoothing); -#endif //ARDUINO + debug_print("the cXSmoothing value was adjusted to:"); + debug_println(controls.cxSmoothing); } else if(controls.cxSmoothing < controls.smoothingMin) { controls.cxSmoothing = controls.smoothingMin; numberOfNaN++; -#ifdef ARDUINO - Serial.print("the cXSmoothing value was adjusted to:"); - Serial.println(controls.cxSmoothing); -#endif //ARDUINO + debug_print("the cXSmoothing value was adjusted to:"); + debug_println(controls.cxSmoothing); } - gains.cXSmoothing = controls.cxSmoothing / 10.0f; //get the c-stick y-axis smoothing value controls.cySmoothing = getCySmoothingSetting(); -#ifdef ARDUINO - Serial.print("the cYSmoothing value from eeprom is:"); - Serial.println(controls.cySmoothing); -#endif //ARDUINO + debug_print("the cYSmoothing value from eeprom is:"); + debug_println(controls.cySmoothing); if(controls.cySmoothing > controls.smoothingMax) { controls.cySmoothing = controls.smoothingMin; numberOfNaN++; -#ifdef ARDUINO - Serial.print("the cYSmoothing value was adjusted to:"); - Serial.println(controls.cySmoothing); -#endif //ARDUINO + debug_print("the cYSmoothing value was adjusted to:"); + debug_println(controls.cySmoothing); } else if(controls.cySmoothing < controls.smoothingMin) { controls.cySmoothing = controls.smoothingMin; numberOfNaN++; -#ifdef ARDUINO - Serial.print("the cYSmoothing value was adjusted to:"); - Serial.println(controls.cySmoothing); -#endif //ARDUINO + debug_print("the cYSmoothing value was adjusted to:"); + debug_println(controls.cySmoothing); } - gains.cYSmoothing = controls.cySmoothing/10.0f; //get the a-stick x-axis waveshaping value controls.axWaveshaping = getWaveshapingSetting(ASTICK, XAXIS); -#ifdef ARDUINO - Serial.print("the axWaveshaping value from eeprom is:"); - Serial.println(controls.axWaveshaping); -#endif //ARDUINO + debug_print("the axWaveshaping value from eeprom is:"); + debug_println(controls.axWaveshaping); if(controls.axWaveshaping < controls.waveshapingMin) { controls.axWaveshaping = controls.waveshapingMin; numberOfNaN++; @@ -1110,10 +1080,8 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai //get the a-stick y-axis waveshaping value controls.ayWaveshaping = getWaveshapingSetting(ASTICK, YAXIS); -#ifdef ARDUINO - Serial.print("the ayWaveshaping value from eeprom is:"); - Serial.println(controls.ayWaveshaping); -#endif //ARDUINO + debug_print("the ayWaveshaping value from eeprom is:"); + debug_println(controls.ayWaveshaping); if(controls.ayWaveshaping < controls.waveshapingMin) { controls.ayWaveshaping = controls.waveshapingMin; numberOfNaN++; @@ -1124,10 +1092,8 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai //get the c-stick x-axis waveshaping value controls.cxWaveshaping = getWaveshapingSetting(CSTICK, XAXIS); -#ifdef ARDUINO - Serial.print("the cxWaveshaping value from eeprom is:"); - Serial.println(controls.cxWaveshaping); -#endif //ARDUINO + debug_print("the cxWaveshaping value from eeprom is:"); + debug_println(controls.cxWaveshaping); if(controls.cxWaveshaping < controls.waveshapingMin) { controls.cxWaveshaping = controls.waveshapingMin; numberOfNaN++; @@ -1138,10 +1104,8 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai //get the c-stick y-axis waveshaping value controls.cyWaveshaping = getWaveshapingSetting(CSTICK, YAXIS); -#ifdef ARDUINO - Serial.print("the cyWaveshaping value from eeprom is:"); - Serial.println(controls.cyWaveshaping); -#endif //ARDUINO + debug_print("the cyWaveshaping value from eeprom is:"); + debug_println(controls.cyWaveshaping); if(controls.cyWaveshaping < controls.waveshapingMin) { controls.cyWaveshaping = controls.waveshapingMin; numberOfNaN++; @@ -1151,21 +1115,17 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai } if(controls.axWaveshaping != 0){ -#ifdef ARDUINO - Serial.print("the axWaveshaping coefficient is: "); - Serial.println(1/calcWaveshapeMult(controls.axWaveshaping)); -#endif //ARDUINO + debug_print("the axWaveshaping coefficient is: "); + debug_println(1/calcWaveshapeMult(controls.axWaveshaping)); } //recompute the intermediate gains used directly by the kalman filter - recomputeGains(gains, normGains); + recomputeGains(controls, gains, normGains); //Get the rumble value controls.rumble = getRumbleSetting(); -#ifdef ARDUINO - Serial.print("Rumble value before fixing: "); - Serial.println(controls.rumble); -#endif //ARDUINO + debug_print("Rumble value before fixing: "); + debug_println(controls.rumble); if(std::isnan(controls.rumble)) { controls.rumble = controls.rumbleDefault; numberOfNaN++; @@ -1177,12 +1137,10 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai controls.rumble = controls.rumbleDefault; } _rumblePower = calcRumblePower(controls.rumble); -#ifdef ARDUINO - Serial.print("Rumble value: "); - Serial.println(controls.rumble); - Serial.print("Rumble power: "); - Serial.println(_rumblePower); -#endif //ARDUINO + debug_print("Rumble value: "); + debug_println(controls.rumble); + debug_print("Rumble power: "); + debug_println(_rumblePower); //Get the autoinit value controls.autoInit = getAutoInitSetting(); @@ -1194,10 +1152,8 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai controls.autoInit = 0; numberOfNaN++; } -#ifdef ARDUINO - Serial.print("Auto init: "); - Serial.println(controls.autoInit); -#endif //ARDUINO + debug_print("Auto init: "); + debug_println(controls.autoInit); //get the calibration points collected during the last A stick calibration float tempCalPointsX[_noOfCalibrationPoints]; @@ -1214,13 +1170,9 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai NotchStatus notchStatus[_noOfNotches]; cleanCalPoints(tempCalPointsX, tempCalPointsY, notchAngles, cleanedPointsX, cleanedPointsY, notchPointsX, notchPointsY, notchStatus); -#ifdef ARDUINO - Serial.println("calibration points cleaned"); -#endif //ARDUINO + debug_println("calibration points cleaned"); linearizeCal(cleanedPointsX, cleanedPointsY, cleanedPointsX, cleanedPointsY, aStickParams); -#ifdef ARDUINO - Serial.println("A stick linearized"); -#endif //ARDUINO + debug_println("A stick linearized"); notchCalibrate(cleanedPointsX, cleanedPointsY, notchPointsX, notchPointsY, _noOfNotches, aStickParams); //get the calibration points collected during the last A stick calibration @@ -1228,13 +1180,9 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai getPointsSetting(tempCalPointsY, CSTICK, YAXIS); getNotchAnglesSetting(notchAngles, CSTICK); cleanCalPoints(tempCalPointsX, tempCalPointsY, notchAngles, cleanedPointsX, cleanedPointsY, notchPointsX, notchPointsY, notchStatus); -#ifdef ARDUINO - Serial.println("calibration points cleaned"); -#endif //ARDUINO + debug_println("calibration points cleaned"); linearizeCal(cleanedPointsX, cleanedPointsY, cleanedPointsX, cleanedPointsY, cStickParams); -#ifdef ARDUINO - Serial.println("C stick linearized"); -#endif //ARDUINO + debug_println("C stick linearized"); notchCalibrate(cleanedPointsX, cleanedPointsY, notchPointsX, notchPointsY, _noOfNotches, cStickParams); //read in extras settings @@ -1245,40 +1193,106 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai } } + //get the A-stick cardinal snapping + controls.astickCardinalSnapping = getCardinalSnappingSetting(ASTICK); + if(controls.astickCardinalSnapping > controls.cardinalSnappingMax) { + controls.astickCardinalSnapping = controls.cardinalSnappingDefault; + numberOfNaN++; + } else if (controls.astickCardinalSnapping < controls.cardinalSnappingMin) { + controls.astickCardinalSnapping = controls.cardinalSnappingDefault; + numberOfNaN++; + } + + //get the C-stick cardinal snapping + controls.cstickCardinalSnapping = getCardinalSnappingSetting(CSTICK); + if(controls.cstickCardinalSnapping > controls.cardinalSnappingMax) { + controls.cstickCardinalSnapping = controls.cardinalSnappingDefault; + numberOfNaN++; + } else if (controls.cstickCardinalSnapping < controls.cardinalSnappingMin) { + controls.cstickCardinalSnapping = controls.cardinalSnappingDefault; + numberOfNaN++; + } + + //get the A-stick analog scaler + controls.astickAnalogScaler = getAnalogScalerSetting(ASTICK); + if(controls.astickAnalogScaler > controls.analogScalerMax) { + controls.astickAnalogScaler = controls.analogScalerDefault; + numberOfNaN++; + } else if (controls.astickAnalogScaler < controls.analogScalerMin) { + controls.astickAnalogScaler = controls.analogScalerDefault; + numberOfNaN++; + } + + //get the C-stick analog scaler + controls.cstickAnalogScaler = getAnalogScalerSetting(CSTICK); + if(controls.cstickAnalogScaler > controls.analogScalerMax) { + controls.cstickAnalogScaler = controls.analogScalerDefault; + numberOfNaN++; + } else if (controls.cstickAnalogScaler < controls.analogScalerMin) { + controls.cstickAnalogScaler = controls.analogScalerDefault; + numberOfNaN++; + } + + //get the tournament toggle setting + controls.tournamentToggle = getTournamentToggleSetting(); + if(controls.tournamentToggle > controls.tournamentToggleMax) { + controls.tournamentToggle = 0; + numberOfNaN++; + } else if(controls.tournamentToggle < controls.tournamentToggleMin) { + controls.tournamentToggle = 0; + numberOfNaN++; + } + +#ifdef PICO_RP2040 + _controls.interlaceOffset = getInterlaceOffsetSetting(); + if(controls.interlaceOffset < controls.interlaceOffsetMin) { + controls.interlaceOffset = 0; + numberOfNaN++; + } + if(controls.interlaceOffset > controls.interlaceOffsetMax) { + controls.interlaceOffset = 0; + numberOfNaN++; + } +#endif //PICO_RP2040 + //Migration const int schema = getSchemaSetting(); -#ifdef ARDUINO - Serial.print("Saved settings schema: "); - Serial.println(schema); -#endif //ARDUINO + debug_print("Saved settings schema: "); + debug_println(schema); bool migrating = false; switch(schema) { case -1: migrating = true; -#ifdef ARDUINO - Serial.println("Updating settings from unitialized"); -#endif //ARDUINO + debug_println("Updating settings from unitialized"); controls.rumble = controls.rumble!=0 ? controls.rumble + 4 : 0; _rumblePower = calcRumblePower(controls.rumble); setRumbleSetting(controls.rumble); -#ifdef ARDUINO - Serial.print("Rumble value changed to: "); - Serial.println(controls.rumble); - Serial.print("Rumble power now: "); - Serial.println(_rumblePower); -#endif //ARDUINO - //I'd like it to change smoothing, but it's way too complicated + debug_print("Rumble value changed to: "); + debug_println(controls.rumble); + debug_print("Rumble power now: "); + debug_println(_rumblePower); + //fallthrough case 28: - //migrating = true;//uncomment when we do have it migrate -#ifdef ARDUINO - Serial.println("Schema is now current"); -#endif //ARDUINO + //uncomment these when we do have it migrate + migrating = true; + debug_println("Updating settings from 0.28"); +#ifdef PICO_RP2040 + controls.interlaceOffset = 0; +#endif //PICO_RP2040 + controls.astickAnalogScaler = controls.analogScalerDefault; + controls.cstickAnalogScaler = controls.analogScalerDefault; + controls.astickCardinalSnapping = controls.cardinalSnappingDefault; + controls.cstickCardinalSnapping = controls.cardinalSnappingDefault; + controls.tournamentToggle = controls.tournamentToggleMin; + //fallthrough + case 29: + //uncomment these when we do have it migrate + //migrating = true; + //debug_println("Schema is now current"); //fallthrough default: if(migrating) { -#ifdef ARDUINO - Serial.println("Updating saved settings schema"); -#endif //ARDUINO + debug_println("Updating saved settings schema"); setSchemaSetting(SW_VERSION); #ifdef BATCHSETTINGS commitSettings(noLock); @@ -1289,9 +1303,7 @@ int readEEPROM(ControlConfig &controls, FilterGains &gains, FilterGains &normGai } void resetDefaults(HardReset reset, ControlConfig &controls, FilterGains &gains, FilterGains &normGains, StickParams &aStickParams, StickParams &cStickParams, const bool noLock = false){ -#ifdef ARDUINO - Serial.println("RESETTING ALL DEFAULTS"); -#endif //ARDUINO + debug_println("RESETTING ALL DEFAULTS"); controls.jumpConfig = DEFAULTJUMP; setJumpSetting(controls.jumpConfig); @@ -1314,9 +1326,7 @@ void resetDefaults(HardReset reset, ControlConfig &controls, FilterGains &gains, controls.ySnapback = controls.snapbackDefault; } setXSnapbackSetting(controls.xSnapback); - gains.xVelDamp = velDampFromSnapback(controls.xSnapback); setYSnapbackSetting(controls.ySnapback); - gains.yVelDamp = velDampFromSnapback(controls.ySnapback); if(reset == FACTORY){ controls.axSmoothing = controls.smoothingFactoryAX; @@ -1329,16 +1339,12 @@ void resetDefaults(HardReset reset, ControlConfig &controls, FilterGains &gains, controls.cxSmoothing = controls.smoothingMin; controls.cySmoothing = controls.smoothingMin; } - gains.xSmoothing = controls.axSmoothing / 10.0f; - gains.ySmoothing = controls.aySmoothing / 10.0f; - gains.cXSmoothing = controls.cxSmoothing / 10.0f; - gains.cYSmoothing = controls.cySmoothing / 10.0f; setXSmoothingSetting(controls.axSmoothing); setYSmoothingSetting(controls.aySmoothing); setCxSmoothingSetting(controls.cxSmoothing); setCySmoothingSetting(controls.cySmoothing); //recompute the intermediate gains used directly by the kalman filter - recomputeGains(gains, normGains); + recomputeGains(controls, gains, normGains); if(reset == FACTORY){ controls.axWaveshaping = controls.waveshapingFactoryAX; @@ -1373,6 +1379,23 @@ void resetDefaults(HardReset reset, ControlConfig &controls, FilterGains &gains, controls.autoInit = 0; setAutoInitSetting(controls.autoInit); + //Cardinal snapping + controls.astickCardinalSnapping = controls.cardinalSnappingDefault; + controls.cstickCardinalSnapping = controls.cardinalSnappingDefault; + setCardinalSnappingSetting(controls.astickCardinalSnapping, ASTICK); + setCardinalSnappingSetting(controls.cstickCardinalSnapping, CSTICK); + + //Analog scaling + controls.astickAnalogScaler = controls.analogScalerDefault; + controls.cstickAnalogScaler = controls.analogScalerDefault; + setAnalogScalerSetting(controls.astickAnalogScaler, ASTICK); + setAnalogScalerSetting(controls.cstickAnalogScaler, CSTICK); + +#ifdef PICO_RP2040 + _controls.interlaceOffset = 0; + setInterlaceOffsetSetting(0); +#endif //PICO_RP2040 + for(int extra=0; extra= _noOfCalibrationPoints) && (notchStatus[notchIndex] == TERT_INACTIVE) && (currentCalStep < _noOfCalibrationPoints + _noOfAdjNotches)){//this non-diagonal notch was not calibrated @@ -1526,9 +1538,7 @@ void calibrationAdvance(ControlConfig &controls, int ¤tCalStep, const Whic notchIndex = _notchAdjOrder[min(currentCalStep-_noOfCalibrationPoints, _noOfAdjNotches-1)];//limit this so it doesn't access outside the array bounds } if(currentCalStep >= _noOfCalibrationPoints + _noOfAdjNotches){//done adjusting notches -#ifdef ARDUINO - Serial.println("finished adjusting notches for the C stick"); -#endif //ARDUINO + debug_println("finished adjusting notches for the C stick"); setPointsSetting(tempCalPointsX, whichStick, XAXIS); setPointsSetting(tempCalPointsY, whichStick, YAXIS); setNotchAnglesSetting(notchAngles, whichStick); @@ -1537,30 +1547,22 @@ void calibrationAdvance(ControlConfig &controls, int ¤tCalStep, const Whic #ifdef BATCHSETTINGS commitSettings(); #endif //BATCHSETTINGS -#ifdef ARDUINO - Serial.println("calibration points stored in EEPROM"); -#endif //ARDUINO + debug_println("calibration points stored in EEPROM"); float cleanedPointsX[_noOfNotches+1]; float cleanedPointsY[_noOfNotches+1]; float notchPointsX[_noOfNotches+1]; float notchPointsY[_noOfNotches+1]; cleanCalPoints(tempCalPointsX, tempCalPointsY, notchAngles, cleanedPointsX, cleanedPointsY, notchPointsX, notchPointsY, notchStatus); -#ifdef ARDUINO - Serial.println("calibration points cleaned"); -#endif //ARDUINO + debug_println("calibration points cleaned"); linearizeCal(cleanedPointsX, cleanedPointsY, cleanedPointsX, cleanedPointsY, cStickParams); -#ifdef ARDUINO - Serial.println("C stick linearized"); -#endif //ARDUINO + debug_println("C stick linearized"); notchCalibrate(cleanedPointsX, cleanedPointsY, notchPointsX, notchPointsY, _noOfNotches, cStickParams); currentCalStep = -1; } } else if (whichStick == ASTICK){ -#ifdef ARDUINO - Serial.println("Current step:"); - Serial.println(currentCalStep); -#endif //ARDUINO + debug_println("Current step:"); + debug_println(currentCalStep); if(currentCalStep < _noOfCalibrationPoints){//still collecting points readADCScale(_ADCScale, _ADCScaleFactor); float X = 0; @@ -1582,7 +1584,7 @@ void calibrationAdvance(ControlConfig &controls, int ¤tCalStep, const Whic if(currentCalStep == _noOfCalibrationPoints){//done collecting points //bring all notches into a legal range; this helps recover from freakout situations legalizeNotches(currentCalStep, measuredNotchAngles, notchAngles, notchStatus); - applyCalFromPoints(whichStick, notchAngles, tempCalPointsX, tempCalPointsY, notchStatus, measuredNotchAngles, aStickParams); + applyCalFromPoints(whichStick, notchAngles, tempCalPointsX, tempCalPointsY, notchStatus, measuredNotchAngles, aStickParams, controls); } int notchIndex = _notchAdjOrder[min(currentCalStep-_noOfCalibrationPoints, _noOfAdjNotches-1)];//limit this so it doesn't access outside the array bounds while((currentCalStep >= _noOfCalibrationPoints) && (notchStatus[notchIndex] == TERT_INACTIVE) && (currentCalStep < _noOfCalibrationPoints + _noOfAdjNotches)){//this non-diagonal notch was not calibrated @@ -1592,9 +1594,7 @@ void calibrationAdvance(ControlConfig &controls, int ¤tCalStep, const Whic notchIndex = _notchAdjOrder[min(currentCalStep-_noOfCalibrationPoints, _noOfAdjNotches-1)];//limit this so it doesn't access outside the array bounds } if(currentCalStep >= _noOfCalibrationPoints + _noOfAdjNotches){//done adjusting notches -#ifdef ARDUINO - Serial.println("finished adjusting notches for the A stick"); -#endif //ARDUINO + debug_println("finished adjusting notches for the A stick"); setPointsSetting(tempCalPointsX, whichStick, XAXIS); setPointsSetting(tempCalPointsY, whichStick, YAXIS); setNotchAnglesSetting(notchAngles, whichStick); @@ -1603,21 +1603,15 @@ void calibrationAdvance(ControlConfig &controls, int ¤tCalStep, const Whic #ifdef BATCHSETTINGS commitSettings(); #endif //BATCHSETTINGS -#ifdef ARDUINO - Serial.println("calibration points stored in EEPROM"); -#endif //ARDUINO + debug_println("calibration points stored in EEPROM"); float cleanedPointsX[_noOfNotches+1]; float cleanedPointsY[_noOfNotches+1]; float notchPointsX[_noOfNotches+1]; float notchPointsY[_noOfNotches+1]; cleanCalPoints(tempCalPointsX, tempCalPointsY, notchAngles, cleanedPointsX, cleanedPointsY, notchPointsX, notchPointsY, notchStatus); -#ifdef ARDUINO - Serial.println("calibration points cleaned"); -#endif //ARDUINO + debug_println("calibration points cleaned"); linearizeCal(cleanedPointsX, cleanedPointsY, cleanedPointsX, cleanedPointsY, aStickParams); -#ifdef ARDUINO - Serial.println("A stick linearized"); -#endif //ARDUINO + debug_println("A stick linearized"); notchCalibrate(cleanedPointsX, cleanedPointsY, notchPointsX, notchPointsY, _noOfNotches, aStickParams); currentCalStep = -1; } @@ -1737,6 +1731,33 @@ void processButtons(Pins &pin, Buttons &btn, Buttons &hardware, ControlConfig &c //Apply any further button remapping to tempBtn here + //Tournament toggle + static int startLockout = 1000; + if(controls.tournamentToggle >= 3 && hardware.S) { + if(startLockout > 0) { + startLockout--; + tempBtn.S = (uint8_t) (0); + } else if(startLockout <= 0) { + tempBtn.S = (uint8_t) (1); + } + } else if(startLockout < 1000) { + startLockout++; + } + static int duLockout = 1000; + if((controls.tournamentToggle == 1 || controls.tournamentToggle == 4) && hardware.Du) { + if(duLockout > 0) { + duLockout--; + tempBtn.Du = (uint8_t) (0); + } else if(duLockout <= 0) { + tempBtn.Du = (uint8_t) (1); + } + } else if(duLockout < 1000) { + duLockout++; + } + if(controls.tournamentToggle == 2 || controls.tournamentToggle == 5) { + tempBtn.Du = (uint8_t) (0); + } + //Here we make sure LRAS actually operate. if(hardware.L && hardware.R && hardware.A && hardware.S) { tempBtn.L = (uint8_t) (1); @@ -1756,6 +1777,7 @@ void processButtons(Pins &pin, Buttons &btn, Buttons &hardware, ControlConfig &c * Soft Reset: ABZ+Start * Hard Reset: ABZ+Dd * Auto-Initialize: AXY+Z + * Tournament Toggle: Z+Start * * Increase/Decrease Rumble: AB+Du/Dd * Show Current Rumble Setting: AB+Start @@ -1777,6 +1799,8 @@ void processButtons(Pins &pin, Buttons &btn, Buttons &hardware, ControlConfig &c * Increase/Decrease X-Axis Smoothing: RX+Du/Dd * Increase/Decrease Y-Axis Smoothing: RY+Du/Dd * Show Analog Filtering Settings: L+Start + * Increase/Decrease Analog Scaler: LA+Du/Dd + * Increase/Decrease Cardinal Snapping: RA+Du/Dd * * C-Stick Configuration * Increase/Decrease X-Axis Snapback Filtering: AXZ+Du/Dd @@ -1786,6 +1810,8 @@ void processButtons(Pins &pin, Buttons &btn, Buttons &hardware, ControlConfig &c * Increase/Decrease X-Axis Offset: RXZ+Du/Dd * Increase/Decrease Y-Axis Offset: RYZ+Du/Dd * Show C-Stick Settings: R+Start + * Increase/Decrease Analog Scaler: LAZ+Du/Dd + * Increase/Decrease Cardinal Snapping: RAZ+Du/Dd * * Swap X with Z: XZ+Start * Swap Y with Z: YZ+Start @@ -1806,24 +1832,33 @@ void processButtons(Pins &pin, Buttons &btn, Buttons &hardware, ControlConfig &c static bool advanceCal = false; + //This will count up as we request settings changes continuously + //If we enter the following if else block with a nonzero counter but no commands are used, + // then that means we are done changing (for now) and can commit. + //Primarily meant for the trigger offset setting, which has a lot of changes. + static int settingChangeCount = 0; + //check the hardware buttons to change the controller settings if(!controls.safeMode && (currentCalStep == -1)) { - static float hardResetAccumulator = 0.0; - if (hardware.A && hardware.B && hardware.Z && hardware.Dd) { //Hard Reset pressed - hardResetAccumulator = 0.99*hardResetAccumulator + 0.01; - } else { - hardResetAccumulator = 0.99*hardResetAccumulator; - } - if(hardResetAccumulator > 0.99) { - hardResetAccumulator = 0; - resetDefaults(HARD, controls, gains, normGains, _aStickParams, _cStickParams);//do reset sticks - freezeSticks(2000, btn, hardware); + //it'll be unlocked after it hits zero + const int hardResetLockoutDuration = 800; + static int hardResetLockout = hardResetLockoutDuration; + if(hardware.A && hardware.B && hardware.Z && hardware.Dd) { //Hard Reset pressed + if(hardResetLockout > 0) { //Not held long enough + hardResetLockout--; + } else if(hardResetLockout == 0) { //Held long enough + hardResetLockout = hardResetLockoutDuration; + resetDefaults(HARD, controls, gains, normGains, _aStickParams, _cStickParams);//do reset sticks + freezeSticks(2000, btn, hardware); + } + } else if(hardResetLockout < hardResetLockoutDuration) { + hardResetLockout++; } if(hardware.A && hardware.X && hardware.Y && hardware.S && !hardware.L && !hardware.R) { //Safe Mode Toggle controls.safeMode = true; freezeSticks(4000, btn, hardware); - } else if (hardware.A && hardware.Z && hardware.Du && !hardware.X && !hardware.Y) { //display version number (ignore commands for c stick snapback) + } else if (hardware.A && hardware.Z && hardware.Du && !hardware.X && !hardware.Y && !hardware.L && !hardware.R) { //display version number (ignore commands for c stick snapback) const int versionHundreds = floor(SW_VERSION/100.0); const int versionOnes = SW_VERSION-versionHundreds; btn.Ax = (uint8_t) _floatOrigin; @@ -1835,10 +1870,15 @@ void processButtons(Pins &pin, Buttons &btn, Buttons &hardware, ControlConfig &c resetDefaults(SOFT, controls, gains, normGains, _aStickParams, _cStickParams);//don't reset sticks freezeSticks(2000, btn, hardware); } else if (hardware.A && hardware.B && hardware.Z && hardware.Dd) { //Hard Reset - //actually do nothing, this is just to prevent othing things from happening + //actually do nothing, this is just to prevent other things from happening } else if (hardware.A && hardware.X && hardware.Y && hardware.Z) { //Toggle Auto-Initialize + settingChangeCount++; changeAutoInit(btn, hardware, controls); + } else if(hardware.Z && hardware.S && !hardware.A && !hardware.B && !hardware.X && !hardware.Y) { + settingChangeCount++; + changeTournamentToggle(btn, hardware, controls); } else if (hardware.A && hardware.B && hardware.Du) { //Increase Rumble + settingChangeCount++; #ifdef RUMBLE changeRumble(INCREASE, btn, hardware, controls); #else // RUMBLE @@ -1846,6 +1886,7 @@ void processButtons(Pins &pin, Buttons &btn, Buttons &hardware, ControlConfig &c freezeSticks(2000, btn, hardware); #endif // RUMBLE } else if (hardware.A && hardware.B && hardware.Dd) { //Decrease Rumble + settingChangeCount++; #ifdef RUMBLE changeRumble(DECREASE, btn, hardware, controls); #else // RUMBLE @@ -1853,146 +1894,223 @@ void processButtons(Pins &pin, Buttons &btn, Buttons &hardware, ControlConfig &c freezeSticks(2000, btn, hardware); #endif // RUMBLE } else if (hardware.A && hardware.B && hardware.S) { //Show current rumble setting + settingChangeCount++; #ifdef RUMBLE showRumble(2000, btn, hardware, controls); #else // RUMBLE freezeSticks(2000, btn, hardware); #endif // RUMBLE } else if (hardware.A && hardware.X && hardware.Y && hardware.L) { //Analog Calibration -#ifdef ARDUINO - Serial.println("Calibrating the A stick"); -#endif //ARDUINO + debug_println("Calibrating the A stick"); whichStick = ASTICK; currentCalStep ++; advanceCal = true; freezeSticks(2000, btn, hardware); } else if (hardware.A && hardware.X && hardware.Y && hardware.R) { //C-stick Calibration -#ifdef ARDUINO - Serial.println("Calibrating the C stick"); -#endif //ARDUINO + debug_println("Calibrating the C stick"); whichStick = CSTICK; currentCalStep ++; advanceCal = true; freezeSticks(2000, btn, hardware); } else if(hardware.A && hardware.X && !hardware.Z && hardware.Du) { //Increase Analog X-Axis Snapback Filtering + settingChangeCount++; adjustSnapback(XAXIS, INCREASE, btn, hardware, controls, gains, normGains); } else if(hardware.A && hardware.X && !hardware.Z && hardware.Dd) { //Decrease Analog X-Axis Snapback Filtering + settingChangeCount++; adjustSnapback(XAXIS, DECREASE, btn, hardware, controls, gains, normGains); } else if(hardware.A && hardware.Y && !hardware.Z && hardware.Du) { //Increase Analog Y-Axis Snapback Filtering + settingChangeCount++; adjustSnapback(YAXIS, INCREASE, btn, hardware, controls, gains, normGains); } else if(hardware.A && hardware.Y && !hardware.Z && hardware.Dd) { //Decrease Analog Y-Axis Snapback Filtering + settingChangeCount++; adjustSnapback(YAXIS, DECREASE, btn, hardware, controls, gains, normGains); } else if(hardware.L && hardware.X && !hardware.Z && hardware.Du) { //Increase Analog X-Axis Waveshaping + settingChangeCount++; adjustWaveshaping(ASTICK, XAXIS, INCREASE, btn, hardware, controls); } else if(hardware.L && hardware.X && !hardware.Z && hardware.Dd) { //Decrease Analog X-Axis Waveshaping + settingChangeCount++; adjustWaveshaping(ASTICK, XAXIS, DECREASE, btn, hardware, controls); } else if(hardware.L && hardware.Y && !hardware.Z && hardware.Du) { //Increase Analog Y-Axis Waveshaping + settingChangeCount++; adjustWaveshaping(ASTICK, YAXIS, INCREASE, btn, hardware, controls); } else if(hardware.L && hardware.Y && !hardware.Z && hardware.Dd) { //Decrease Analog Y-Axis Waveshaping + settingChangeCount++; adjustWaveshaping(ASTICK, YAXIS, DECREASE, btn, hardware, controls); } else if(hardware.R && hardware.X && !hardware.Z && hardware.Du) { //Increase X-axis Delay + settingChangeCount++; adjustSmoothing(XAXIS, INCREASE, btn, hardware, controls, gains, normGains); } else if(hardware.R && hardware.X && !hardware.Z && hardware.Dd) { //Decrease X-axis Delay + settingChangeCount++; adjustSmoothing(XAXIS, DECREASE, btn, hardware, controls, gains, normGains); } else if(hardware.R && hardware.Y && !hardware.Z && hardware.Du) { //Increase Y-axis Delay + settingChangeCount++; adjustSmoothing(YAXIS, INCREASE, btn, hardware, controls, gains, normGains); } else if(hardware.R && hardware.Y && !hardware.Z && hardware.Dd) { //Decrease Y-axis Delay + settingChangeCount++; adjustSmoothing(YAXIS, DECREASE, btn, hardware, controls, gains, normGains); + } else if(hardware.R && hardware.A && hardware.Du && !hardware.Z) { //Increase Cardinal Snapping + settingChangeCount++; + adjustCardinalSnapping(ASTICK, INCREASE, btn, hardware, controls); + } else if(hardware.R && hardware.A && hardware.Dd && !hardware.Z) { //Decrease Cardinal Snapping + settingChangeCount++; + adjustCardinalSnapping(ASTICK, DECREASE, btn, hardware, controls); + } else if(hardware.L && hardware.A && hardware.Du && !hardware.Z) { //Increase Analog Scaler + settingChangeCount++; + adjustAnalogScaler(ASTICK, INCREASE, btn, hardware, controls); + } else if(hardware.L && hardware.A && hardware.Dd && !hardware.Z) { //Decrease Analog Scaler + settingChangeCount++; + adjustAnalogScaler(ASTICK, DECREASE, btn, hardware, controls); } else if(hardware.L && hardware.S && !hardware.A && !hardware.R && !hardware.X && !hardware.Y) { //Show Current Analog Settings (ignore L jump and L trigger toggle and LRAS) showAstickSettings(btn, hardware, controls, gains); } else if(hardware.A && hardware.X && hardware.Z && hardware.Du) { //Increase C-stick X-Axis Snapback Filtering + settingChangeCount++; adjustCstickSmoothing(XAXIS, INCREASE, btn, hardware, controls, gains, normGains); } else if(hardware.A && hardware.X && hardware.Z && hardware.Dd) { //Decrease C-stick X-Axis Snapback Filtering + settingChangeCount++; adjustCstickSmoothing(XAXIS, DECREASE, btn, hardware, controls, gains, normGains); } else if(hardware.A && hardware.Y && hardware.Z && hardware.Du) { //Increase C-stick Y-Axis Snapback Filtering + settingChangeCount++; adjustCstickSmoothing(YAXIS, INCREASE, btn, hardware, controls, gains, normGains); } else if(hardware.A && hardware.Y && hardware.Z && hardware.Dd) { //Decrease C-stick Y-Axis Snapback Filtering + settingChangeCount++; adjustCstickSmoothing(YAXIS, DECREASE, btn, hardware, controls, gains, normGains); } else if(hardware.L && hardware.X && hardware.Z && hardware.Du) { //Increase C-stick X-Axis Waveshaping + settingChangeCount++; adjustWaveshaping(CSTICK, XAXIS, INCREASE, btn, hardware, controls); } else if(hardware.L && hardware.X && hardware.Z && hardware.Dd) { //Decrease C-stick X-Axis Waveshaping + settingChangeCount++; adjustWaveshaping(CSTICK, XAXIS, DECREASE, btn, hardware, controls); } else if(hardware.L && hardware.Y && hardware.Z && hardware.Du) { //Increase C-stick Y-Axis Waveshaping + settingChangeCount++; adjustWaveshaping(CSTICK, YAXIS, INCREASE, btn, hardware, controls); } else if(hardware.L && hardware.Y && hardware.Z && hardware.Dd) { //Decrease C-stick Y-Axis Waveshaping adjustWaveshaping(CSTICK, YAXIS, DECREASE, btn, hardware, controls); } else if(hardware.R && hardware.X && hardware.Z && hardware.Du) { //Increase C-stick X Offset + settingChangeCount++; adjustCstickOffset(XAXIS, INCREASE, btn, hardware, controls); } else if(hardware.R && hardware.X && hardware.Z && hardware.Dd) { //Decrease C-stick X Offset + settingChangeCount++; adjustCstickOffset(XAXIS, DECREASE, btn, hardware, controls); } else if(hardware.R && hardware.Y && hardware.Z && hardware.Du) { //Increase C-stick Y Offset + settingChangeCount++; adjustCstickOffset(YAXIS, INCREASE, btn, hardware, controls); } else if(hardware.R && hardware.Y && hardware.Z && hardware.Dd) { //Decrease C-stick Y Offset + settingChangeCount++; adjustCstickOffset(YAXIS, DECREASE, btn, hardware, controls); + } else if(hardware.R && hardware.A && hardware.Z && hardware.Du) { //Increase C-stick Cardinal Snapping + settingChangeCount++; + adjustCardinalSnapping(CSTICK, INCREASE, btn, hardware, controls); + } else if(hardware.R && hardware.A && hardware.Z && hardware.Dd) { //Decrease C-stick Cardinal Snapping + settingChangeCount++; + adjustCardinalSnapping(CSTICK, DECREASE, btn, hardware, controls); + } else if(hardware.L && hardware.A && hardware.Z && hardware.Du) { //Increase C-stick Analog Scaler + settingChangeCount++; + adjustAnalogScaler(CSTICK, INCREASE, btn, hardware, controls); + } else if(hardware.L && hardware.A && hardware.Z && hardware.Dd) { //Decrease C-stick Analog Scaler + settingChangeCount++; + adjustAnalogScaler(CSTICK, DECREASE, btn, hardware, controls); } else if(hardware.R && hardware.S && !hardware.A && !hardware.L && !hardware.X && !hardware.Y) { //Show Current C-stick Settings (ignore R jump and R trigger toggle and LRAS) showCstickSettings(btn, hardware, controls, gains); } else if(hardware.A && hardware.B && hardware.L) { //Toggle Analog L + settingChangeCount++; nextTriggerState(LTRIGGER, btn, hardware, controls); } else if(hardware.A && hardware.B && hardware.R) { //Toggle Analog R + settingChangeCount++; nextTriggerState(RTRIGGER, btn, hardware, controls); } else if(hardware.L && hardware.B && hardware.Du) { //Increase L-Trigger Offset + settingChangeCount++; adjustTriggerOffset(LTRIGGER, INCREASE, btn, hardware, controls); } else if(hardware.L && hardware.B && hardware.Dd) { //Decrease L-trigger Offset + settingChangeCount++; adjustTriggerOffset(LTRIGGER, DECREASE, btn, hardware, controls); } else if(hardware.R && hardware.B && hardware.Du) { //Increase R-trigger Offset + settingChangeCount++; adjustTriggerOffset(RTRIGGER, INCREASE, btn, hardware, controls); } else if(hardware.R && hardware.B && hardware.Dd) { //Decrease R-trigger Offset + settingChangeCount++; adjustTriggerOffset(RTRIGGER, DECREASE, btn, hardware, controls); } else if(hardware.X && hardware.Z && hardware.S) { //Swap X and Z + settingChangeCount++; setJumpConfig(SWAP_XZ, controls); freezeSticks(2000, btn, hardware); } else if(hardware.Y && hardware.Z && hardware.S) { //Swap Y and Z + settingChangeCount++; setJumpConfig(SWAP_YZ, controls); freezeSticks(2000, btn, hardware); } else if(hardware.X && hardware.L && hardware.S) { //Swap X and L + settingChangeCount++; setJumpConfig(SWAP_XL, controls); freezeSticks(2000, btn, hardware); } else if(hardware.Y && hardware.L && hardware.S) { //Swap Y and L + settingChangeCount++; setJumpConfig(SWAP_YL, controls); freezeSticks(2000, btn, hardware); } else if(hardware.X && hardware.R && hardware.S) { //Swap X and R + settingChangeCount++; setJumpConfig(SWAP_XR, controls); freezeSticks(2000, btn, hardware); } else if(hardware.Y && hardware.R && hardware.S) { //Swap Y and R + settingChangeCount++; setJumpConfig(SWAP_YR, controls); freezeSticks(2000, btn, hardware); } else if(checkAdjustExtra(EXTRAS_UP, btn, false)) { // Toggle Extras + settingChangeCount++; toggleExtra(EXTRAS_UP, btn, hardware, controls); } else if(checkAdjustExtra(EXTRAS_DOWN, btn, false)) { + settingChangeCount++; toggleExtra(EXTRAS_DOWN, btn, hardware, controls); } else if(checkAdjustExtra(EXTRAS_LEFT, btn, false)) { + settingChangeCount++; toggleExtra(EXTRAS_LEFT, btn, hardware, controls); } else if(checkAdjustExtra(EXTRAS_RIGHT, btn, false)) { + settingChangeCount++; toggleExtra(EXTRAS_RIGHT, btn, hardware, controls); } else if(checkAdjustExtra(EXTRAS_UP, btn, true)) { // Configure Extras + settingChangeCount++; configExtra(EXTRAS_UP, btn, hardware, controls); } else if(checkAdjustExtra(EXTRAS_DOWN, btn, true)) { + settingChangeCount++; configExtra(EXTRAS_DOWN, btn, hardware, controls); } else if(checkAdjustExtra(EXTRAS_LEFT, btn, true)) { + settingChangeCount++; configExtra(EXTRAS_LEFT, btn, hardware, controls); } else if(checkAdjustExtra(EXTRAS_RIGHT, btn, true)) { + settingChangeCount++; configExtra(EXTRAS_RIGHT, btn, hardware, controls); - } - } else if (currentCalStep == -1) { //Safe Mode Enabled, Lock Settings, wait for safe mode command - static float safeModeAccumulator = 0.0; - if(hardware.A && hardware.X && hardware.Y && hardware.S && !hardware.L && !hardware.R) { //Safe Mode Toggle - safeModeAccumulator = 0.99*safeModeAccumulator + 0.01; } else { - safeModeAccumulator = 0.99*safeModeAccumulator; + //If the buttons were released after changing an applicable setting + if(settingChangeCount > 0) { + settingChangeCount = 0; + //request a commit only if we need to batch them. +#ifdef BATCHSETTINGS + commitSettings(); +#endif //BATCHSETTINGS + } } - if(safeModeAccumulator > 0.99){ - safeModeAccumulator = 0; - if (!running) {//wake it up if not already running - running = true; + } else if (currentCalStep == -1) { //Safe Mode Enabled, Lock Settings, wait for safe mode command + + //it'll be unlocked after it hits zero + const int safeModeLockoutDuration = 800; + static int safeModeLockout = safeModeLockoutDuration; + if(hardware.A && hardware.X && hardware.Y && hardware.S && !hardware.L && !hardware.R) { //Safe Mode toggle + if(safeModeLockout > 0) { //Not held long enough + safeModeLockout--; + } else if(safeModeLockout == 0) { //Held long enough + safeModeLockout = safeModeLockoutDuration; + if(!running) { //wake it up if not already running + running = true; + } + controls.safeMode = false; + freezeSticks(2000, btn, hardware); } - controls.safeMode = false; - freezeSticks(2000, btn, hardware); + } else if(safeModeLockout < safeModeLockoutDuration) { + safeModeLockout++; } } //Skip stick measurement and go to notch adjust using the start button while calibrating if(hardware.S && (currentCalStep >= 0 && currentCalStep < 32)){ - calibrationSkipMeasurement(currentCalStep, whichStick, tempCalPointsX, tempCalPointsY, notchStatus, notchAngles, measuredNotchAngles, aStickParams, cStickParams); + calibrationSkipMeasurement(currentCalStep, whichStick, tempCalPointsX, tempCalPointsY, notchStatus, notchAngles, measuredNotchAngles, aStickParams, cStickParams, controls); } //Undo Calibration using Z-button @@ -2005,31 +2123,29 @@ void processButtons(Pins &pin, Buttons &btn, Buttons &hardware, ControlConfig &c undoCalPressed = false; } - //Advance Calibration Using L or R triggers - static float advanceCalAccumulator = 0.0; - if((hardware.A || hardware.L || hardware.R) && advanceCal){ - advanceCalAccumulator = 0.96*advanceCalAccumulator + 0.04; - } else { - advanceCalAccumulator = 0.96*advanceCalAccumulator; - } - + //Advance Calibration Using L or R triggers or A button + static int calibLockout = 50; static bool advanceCalPressed = false; - if(advanceCalAccumulator > 0.75 && !advanceCalPressed){ - advanceCalPressed = true; - calibrationAdvance(controls, currentCalStep, whichStick, tempCalPointsX, tempCalPointsY, undoCal, notchAngles, notchStatus, measuredNotchAngles, aStickParams, cStickParams); - if(currentCalStep == -1) { - advanceCal = false; + if((hardware.A || hardware.L || hardware.R) && advanceCal){ + if(calibLockout > 0) { + calibLockout--; + } else if(calibLockout == 0 && !advanceCalPressed) { + calibLockout = 50; + advanceCalPressed = true; + calibrationAdvance(controls, currentCalStep, whichStick, tempCalPointsX, tempCalPointsY, undoCal, notchAngles, notchStatus, measuredNotchAngles, aStickParams, cStickParams); + if(currentCalStep == -1) { + advanceCal = false; + } } - } else if(advanceCalAccumulator <= 0.25) { + } else if(calibLockout < 50) { + calibLockout++; advanceCalPressed = false; } } -void readSticks(int readA, int readC, Buttons &btn, Pins &pin, RawStick &raw, const Buttons &hardware, const ControlConfig &controls, const FilterGains &normGains, const StickParams &aStickParams, const StickParams &cStickParams, float &dT, int ¤tCalStep, const bool runSynced){ +void readSticks(int readA, int readC, Buttons &btn, Pins &pin, RawStick &raw, const Buttons &hardware, const ControlConfig &controls, const FilterGains &normGains, const StickParams &aStickParams, const StickParams &cStickParams, float &dT, int ¤tCalStep){ readADCScale(_ADCScale, _ADCScaleFactor); - - //on Arduino (and therefore Teensy), micros() overflows after about 71.58 minutes //This is 2^32 microseconds static uint32_t lastMicros = micros(); @@ -2040,7 +2156,7 @@ void readSticks(int readA, int readC, Buttons &btn, Pins &pin, RawStick &raw, co //However, this may make it smaller than the most recently measured time. //So, we let the loop keep going if -#ifndef CLEANADC +//#ifndef CLEANADC //Read the sticks repeatedly until it's been 1 millisecond since the last iteration //This is for denoising and making sure the loop runs at 1000 Hz //We want to stop the ADC reading early enough that we don't overrun 1000 microseconds @@ -2068,11 +2184,12 @@ void readSticks(int readA, int readC, Buttons &btn, Pins &pin, RawStick &raw, co afterMicros = micros(); } - //Serial.println(adcCount); + //debug_println(adcCount); float aStickX = aXSum/(float)adcCount/4096.0*_ADCScale; float aStickY = aYSum/(float)adcCount/4096.0*_ADCScale; float cStickX = cXSum/(float)adcCount/4096.0*_ADCScale; float cStickY = cYSum/(float)adcCount/4096.0*_ADCScale; + /* #else //CLEANADC: read only once float aStickX = readAx(pin)/4096.0; float aStickY = readAy(pin)/4096.0; @@ -2080,26 +2197,21 @@ void readSticks(int readA, int readC, Buttons &btn, Pins &pin, RawStick &raw, co float cStickY = readCy(pin)/4096.0; //note: this actually results in about 0.5 ms delay for the analog sticks - if(!runSynced) { - uint32_t thisMicros = micros(); - while(thisMicros-lastMicros < 1000) { - thisMicros = micros(); - } + uint32_t thisMicros = micros(); + while(thisMicros-lastMicros < 1000) { + thisMicros = micros(); } #endif //CLEANADC + */ dT = (micros()-lastMicros)/1000; - if(!runSynced) { - lastMicros += 1000; - } else { - lastMicros = micros(); - } + lastMicros += 1000; if(micros() - lastMicros > 1500) { //handle the case that it was synced and now isn't lastMicros = micros(); } - _raw.axRaw = aStickX; - _raw.ayRaw = aStickY; - _raw.cxRaw = cStickX; - _raw.cyRaw = cStickY; + raw.axRaw = aStickX; + raw.ayRaw = aStickY; + raw.cxRaw = cStickX; + raw.cyRaw = cStickY; //create the measurement value to be used in the kalman filter float xZ; @@ -2115,10 +2227,10 @@ void readSticks(int readA, int readC, Buttons &btn, Pins &pin, RawStick &raw, co float posAx = xZ; float posAy = yZ; - _raw.axLinearized = posAx; - _raw.ayLinearized = posAy; - _raw.cxLinearized = posCx; - _raw.cyLinearized = posCy; + raw.axLinearized = posAx; + raw.ayLinearized = posAy; + raw.cxLinearized = posCx; + raw.cyLinearized = posCy; //Run the kalman filter to eliminate snapback static float xPosFilt = 0;//output of kalman filter @@ -2177,20 +2289,20 @@ void readSticks(int readA, int readC, Buttons &btn, Pins &pin, RawStick &raw, co float remappedAyUnfiltered; float remappedCxUnfiltered; float remappedCyUnfiltered; - notchRemap(posAx, posAy, &remappedAx, &remappedAy, _noOfNotches, aStickParams, currentCalStep); - notchRemap(posCx, posCy, &remappedCx, &remappedCy, _noOfNotches, cStickParams, currentCalStep); - notchRemap(_raw.axLinearized, _raw.ayLinearized, &remappedAxUnfiltered, &remappedAyUnfiltered, _noOfNotches, aStickParams, 1);//no snapping - notchRemap(_raw.cxLinearized, _raw.cyLinearized, &remappedCxUnfiltered, &remappedCyUnfiltered, _noOfNotches, cStickParams, 1);//no snapping + notchRemap(posAx, posAy, &remappedAx, &remappedAy, _noOfNotches, aStickParams, currentCalStep, controls, ASTICK); + notchRemap(posCx, posCy, &remappedCx, &remappedCy, _noOfNotches, cStickParams, currentCalStep, controls, CSTICK); + notchRemap(raw.axLinearized, raw.ayLinearized, &remappedAxUnfiltered, &remappedAyUnfiltered, _noOfNotches, aStickParams, 1, controls, ASTICK);//no snapping + notchRemap(raw.cxLinearized, raw.cyLinearized, &remappedCxUnfiltered, &remappedCyUnfiltered, _noOfNotches, cStickParams, 1, controls, CSTICK);//no snapping //Clamp values from -125 to +125 remappedAx = fmin(125, fmax(-125, remappedAx)); remappedAy = fmin(125, fmax(-125, remappedAy)); - remappedCx = fmin(125, fmax(-125, remappedCx+controls.cXOffset)); - remappedCy = fmin(125, fmax(-125, remappedCy+controls.cYOffset)); - _raw.axUnfiltered = fmin(125, fmax(-125, remappedAxUnfiltered)); - _raw.ayUnfiltered = fmin(125, fmax(-125, remappedAyUnfiltered)); - _raw.cxUnfiltered = fmin(125, fmax(-125, remappedCxUnfiltered+controls.cXOffset)); - _raw.cyUnfiltered = fmin(125, fmax(-125, remappedCyUnfiltered+controls.cYOffset)); + remappedCx = fmin(125, fmax(-125, remappedCx)); + remappedCy = fmin(125, fmax(-125, remappedCy)); + raw.axUnfiltered = fmin(125, fmax(-125, remappedAxUnfiltered)); + raw.ayUnfiltered = fmin(125, fmax(-125, remappedAyUnfiltered)); + raw.cxUnfiltered = fmin(125, fmax(-125, remappedCxUnfiltered)); + raw.cyUnfiltered = fmin(125, fmax(-125, remappedCyUnfiltered)); bool skipAHyst = false; #ifdef EXTRAS_ESS diff --git a/PhobGCC/common/stick.h b/PhobGCC/common/stick.h index 6cfe620..f801bfa 100644 --- a/PhobGCC/common/stick.h +++ b/PhobGCC/common/stick.h @@ -115,9 +115,7 @@ void stripCalPoints(const float calPointsX[], const float calPointsY[], float st * outputs need to be length _noOfNotches */ void computeStickAngles(float xInput[], float yInput[], float stickAngles[]){ -#ifdef ARDUINO - Serial.println("Computed stick angles:"); -#endif //ARDUINO + debug_println("Computed stick angles:"); for(int i=0; i < _noOfNotches; i++){ if(i%2 == 0){//cardinal or diagonal stickAngles[i] = _notchAngleDefaults[i]; @@ -139,7 +137,7 @@ void cleanNotches(float notchAngles[], float measuredNotchAngles[], NotchStatus notchRemap Remaps the stick position using affine transforms generated from the notch positions *******************/ -void notchRemap(const float xIn, const float yIn, float* xOut, float* yOut, const int regions, const StickParams &stickParams, int currentCalStep){ +void notchRemap(const float xIn, const float yIn, float* xOut, float* yOut, const int regions, const StickParams &stickParams, int currentCalStep, const ControlConfig &controls, const WhichStick whichStick){ //determine the angle between the x unit vector and the current position vector float angle = atan2f(yIn,xIn); @@ -164,12 +162,50 @@ void notchRemap(const float xIn, const float yIn, float* xOut, float* yOut, cons *xOut = stickParams.affineCoeffs[region][0]*xIn + stickParams.affineCoeffs[region][1]*yIn; *yOut = stickParams.affineCoeffs[region][2]*xIn + stickParams.affineCoeffs[region][3]*yIn; + float stickScale; + if(whichStick == ASTICK) { + stickScale = controls.astickAnalogScaler/100.0f; + } else { + stickScale = controls.cstickAnalogScaler/100.0f; + } + + *xOut *= stickScale; + *yOut *= stickScale; + if(currentCalStep == -1) { - if((abs(*xOut)<6) && (abs(*yOut)>80)){ - *xOut = 0; - } - if((abs(*yOut)<6) && (abs(*xOut)>80)){ - *yOut = 0; + + if(whichStick == ASTICK) { + if(controls.astickCardinalSnapping > 0) { + if((abs(*xOut)=79.5)){ + *xOut = 0; + } + if((abs(*yOut)=79.5)){ + *yOut = 0; + } + } else if(controls.astickCardinalSnapping == -1) { + if((abs(*xOut)<6.5) && (abs(*yOut)>=79.5)){ + *xOut = 7; + } + if((abs(*yOut)<6.5) && (abs(*xOut)>=79.5)){ + *yOut = 7; + } + } + } else { + if(controls.cstickCardinalSnapping > 0) { + if((abs(*xOut)=79.5)){ + *xOut = 0; + } + if((abs(*yOut)=79.5)){ + *yOut = 0; + } + } else if(controls.cstickCardinalSnapping == -1) { + if((abs(*xOut)<6.5) && (abs(*yOut)>=79.5)){ + *xOut = 7; + } + if((abs(*yOut)<6.5) && (abs(*xOut)>=79.5)){ + *yOut = 7; + } + } } if((abs(*xOut)<3) && (abs(*yOut)<3)) { @@ -184,13 +220,13 @@ void notchRemap(const float xIn, const float yIn, float* xOut, float* yOut, cons * remaps the cleaned calibration points from raw measurements to output coordinates * This seems redundant but we're feeding it coordinates without non-diagonal notches */ -void transformCalPoints(const float xInput[], const float yInput[], float xOutput[], float yOutput[], const StickParams &stickParams){ +void transformCalPoints(const float xInput[], const float yInput[], float xOutput[], float yOutput[], const StickParams &stickParams, const ControlConfig &controls, const WhichStick whichStick){ for(int i=0; i < _noOfNotches+1; i++){ float xValue = linearize(xInput[i], stickParams.fitCoeffsX); float yValue = linearize(yInput[i], stickParams.fitCoeffsY); float outX; float outY; - notchRemap(xValue, yValue, &outX, &outY, _noOfNotches, stickParams, 0); + notchRemap(xValue, yValue, &outX, &outY, _noOfNotches, stickParams, 0, controls, whichStick); xOutput[i] = outX; yOutput[i] = outY; } @@ -203,28 +239,24 @@ void transformCalPoints(const float xInput[], const float yInput[], float xOutpu *******************/ void cleanCalPoints(const float calPointsX[], const float calPointsY[], const float notchAngles[], float cleanedPointsX[], float cleanedPointsY[], float notchPointsX[], float notchPointsY[], NotchStatus notchStatus[]){ -#ifdef ARDUINO - Serial.println("The raw calibration points (x,y) are:"); + debug_println("The raw calibration points (x,y) are:"); for(int i = 0; i< _noOfCalibrationPoints; i++){ - Serial.print(calPointsX[i], 4); - Serial.print(","); - Serial.println(calPointsY[i], 4); + debug_print(calPointsX[i], 4); + debug_print(","); + debug_println(calPointsY[i], 4); } - Serial.println("The notch angles are:"); + debug_println("The notch angles are:"); for(int i = 0; i< _noOfNotches; i++){ - Serial.println(notchAngles[i], 4); + debug_println(notchAngles[i], 4); } -#endif //ARDUINO notchPointsX[0] = 0; notchPointsY[0] = 0; cleanedPointsX[0] = 0; cleanedPointsY[0] = 0; -#ifdef ARDUINO - Serial.println("The notch points are:"); -#endif //ARDUINO + debug_println("The notch points are:"); for(int i = 0; i < _noOfNotches; i++){ //add the origin values to the first x,y point cleanedPointsX[0] += calPointsX[i*2]; @@ -239,11 +271,9 @@ void cleanCalPoints(const float calPointsX[], const float calPointsY[], const fl notchPointsX[i+1] = round(notchPointsX[i+1]); notchPointsY[i+1] = round(notchPointsY[i+1]); -#ifdef ARDUINO - Serial.print(notchPointsX[i+1]); - Serial.print(","); - Serial.println(notchPointsY[i+1]); -#endif //ARDUINO + debug_print(notchPointsX[i+1]); + debug_print(","); + debug_println(notchPointsY[i+1]); } //remove the largest and smallest two origin values to remove outliers @@ -314,10 +344,8 @@ void cleanCalPoints(const float calPointsX[], const float calPointsY[], const fl notchPointsX[i+1] = (notchPointsX[prevIndex] + notchPointsX[nextIndex])/2.0; notchPointsY[i+1] = (notchPointsY[prevIndex] + notchPointsY[nextIndex])/2.0; -#ifdef ARDUINO - Serial.print("no input was found for notch: "); - Serial.println(i+1); -#endif //ARDUINO + debug_print("no input was found for notch: "); + debug_println(i+1); //Mark that notch adjustment should be skipped for this notchStatus[i] = TERT_INACTIVE; @@ -326,26 +354,24 @@ void cleanCalPoints(const float calPointsX[], const float calPointsY[], const fl } } -#ifdef ARDUINO - Serial.println("The cleaned calibration points are:"); + debug_println("The cleaned calibration points are:"); for(int i = 0; i< (_noOfNotches+1); i++){ - Serial.print(cleanedPointsX[i], 4); - Serial.print(","); - Serial.println(cleanedPointsY[i], 4); + debug_print(cleanedPointsX[i], 4); + debug_print(","); + debug_println(cleanedPointsY[i], 4); } - Serial.println("The corresponding notch points are:"); + debug_println("The corresponding notch points are:"); for(int i = 0; i< (_noOfNotches+1); i++){ - Serial.print(notchPointsX[i]); - Serial.print(","); - Serial.println(notchPointsY[i]); + debug_print(notchPointsX[i]); + debug_print(","); + debug_println(notchPointsY[i]); } - Serial.println("The notch statuses are:"); + debug_println("The notch statuses are:"); for(int i = 0; i< (_noOfNotches); i++){ - Serial.println(notchStatus[i]); + debug_println(notchStatus[i]); } -#endif //ARDUINO }; //The notch adjustment is limited in order to control @@ -388,23 +414,33 @@ void legalizeNotch(const int notchIndex, float measuredNotchAngles[], float notc nextMeasAngle += 2*M_PI; } - float lowerCompressLimit = prevAngle + 0.7*(thisMeasAngle-prevMeasAngle);//how far we can squish when reducing the angle - float lowerStretchLimit = nextAngle - 1.3*(nextMeasAngle-thisMeasAngle);//how far we can stretch when reducing the angle - float upperCompressLimit = nextAngle - 0.7*(nextMeasAngle-thisMeasAngle);//how far we can squish when increasing the angle - float upperStretchLimit = prevAngle + 1.3*(thisMeasAngle-prevMeasAngle);//how far we can stretch when increasing the angle + float cmpAmt; + float strAmt; + if(isDiagonal) {//tighter bounds for diagonals + cmpAmt = 0.769; + strAmt = 1.3; + } else {//wider bounds for modder notches + cmpAmt = 0.666; + strAmt = 1.5; + } + + float lowerCompressLimit = prevAngle + cmpAmt*(thisMeasAngle-prevMeasAngle);//how far we can squish when reducing the angle + float lowerStretchLimit = nextAngle - strAmt*(nextMeasAngle-thisMeasAngle);//how far we can stretch when reducing the angle + float upperCompressLimit = nextAngle - cmpAmt*(nextMeasAngle-thisMeasAngle);//how far we can squish when increasing the angle + float upperStretchLimit = prevAngle + strAmt*(thisMeasAngle-prevMeasAngle);//how far we can stretch when increasing the angle //Now, in order to apply stretch leniency to angles within the deadzone, // we need to figure out whether the previous angle or next angle was a cardinal. //If the previous one is a cardinal AND the angle is in the deadzone, we make the upperstretchlimit bigger, only if it can't reach 0.3000. const float minThreshold = 0.1500/0.9750;//radians; we don't want to fix things smaller than this const float deadzoneLimit = 0.2875/0.9500;//radians; or things larger than this - const float deadzonePlus = 0.3000/0.9500;//radians; we want to make sure the adjustment can make it here + const float deadzonePlus = 0.3250/0.9375;//radians; we want to make sure the adjustment can make it here if(prevIndex % 4 == 0 && !isDiagonal && (thisMeasAngle-prevMeasAngle) > minThreshold && (thisMeasAngle-prevMeasAngle) < deadzoneLimit){ - upperStretchLimit = prevAngle + fmax(1.3*(thisMeasAngle-prevMeasAngle), deadzonePlus); + upperStretchLimit = prevAngle + fmax(strAmt*(thisMeasAngle-prevMeasAngle), deadzonePlus); } //If the next one is a cardinal AND the angle is in the deadzone, we make the lowerstretchlimit smaller. if(nextIndex % 4 == 0 && !isDiagonal && (nextMeasAngle-thisMeasAngle) > minThreshold && (nextMeasAngle-thisMeasAngle) < deadzoneLimit){ - lowerStretchLimit = nextAngle - fmax(1.3*(nextMeasAngle-thisMeasAngle), deadzonePlus); + lowerStretchLimit = nextAngle - fmax(strAmt*(nextMeasAngle-thisMeasAngle), deadzonePlus); } float lowerDistortLimit = fmax(lowerCompressLimit, lowerStretchLimit); @@ -498,25 +534,19 @@ void displayNotch(const int currentStepIn, const bool calibratingAStick, const f }; void insertCalPoints(const WhichStick whichStick, const int currentStepIn, float calPointsX[], float calPointsY[], Pins &pin, float X, float Y){ -#ifdef ARDUINO - Serial.print("Inserting cal point for step: "); - Serial.println(currentStepIn); -#endif //ARDUINO + debug_print("Inserting cal point for step: "); + debug_println(currentStepIn); const int currentStep = _calOrder[currentStepIn]; -#ifdef ARDUINO - Serial.print("Cal point number: "); - Serial.println(currentStep); -#endif //ARDUINO + debug_print("Cal point number: "); + debug_println(currentStep); calPointsX[currentStep] = X; calPointsY[currentStep] = Y; -#ifdef ARDUINO - Serial.println("The collected coordinates are: "); - Serial.println(calPointsX[currentStep],8); - Serial.println(calPointsY[currentStep],8); -#endif //ARDUINO + debug_println("The collected coordinates are: "); + debug_println(calPointsX[currentStep],8); + debug_println(calPointsY[currentStep],8); }; /******************* @@ -528,9 +558,7 @@ void insertCalPoints(const WhichStick whichStick, const int currentStepIn, float linearization fit coefficients for X and Y *******************/ void linearizeCal(const float inX[], const float inY[], float outX[], float outY[], StickParams &stickParams){ -#ifdef ARDUINO - Serial.println("beginning linearization"); -#endif //ARDUINO + debug_println("beginning linearization"); //do the curve fit first //generate all the notched/not notched specific cstick values we will need @@ -559,21 +587,19 @@ void linearizeCal(const float inX[], const float inY[], float outX[], float outY double x_output[5] = {27.5,53.2537879754,127.5,201.7462120246,227.5}; double y_output[5] = {27.5,53.2537879754,127.5,201.7462120246,227.5}; -#ifdef ARDUINO - Serial.println("The fit input points are (x,y):"); + debug_println("The fit input points are (x,y):"); for(int i = 0; i < 5; i++){ - Serial.print(fitPointsX[i],8); - Serial.print(","); - Serial.println(fitPointsY[i],8); + debug_print(fitPointsX[i],8); + debug_print(","); + debug_println(fitPointsY[i],8); } - Serial.println("The corresponding fit output points are (x,y):"); + debug_println("The corresponding fit output points are (x,y):"); for(int i = 0; i < 5; i++){ - Serial.print(x_output[i]); - Serial.print(","); - Serial.println(y_output[i]); + debug_print(x_output[i]); + debug_print(","); + debug_println(y_output[i]); } -#endif //ARDUINO //perform the curve fit, order is 3 double tempCoeffsX[_fitOrder+1]; @@ -597,24 +623,20 @@ void linearizeCal(const float inX[], const float inY[], float outX[], float outY stickParams.fitCoeffsX[3] = stickParams.fitCoeffsX[3] - xZeroError; stickParams.fitCoeffsY[3] = stickParams.fitCoeffsY[3] - yZeroError; -#ifdef ARDUINO - Serial.println("The fit coefficients are are (x,y):"); + debug_println("The fit coefficients are are (x,y):"); for(int i = 0; i < 4; i++){ - Serial.print(stickParams.fitCoeffsX[i]); - Serial.print(","); - Serial.println(stickParams.fitCoeffsY[i]); + debug_print(stickParams.fitCoeffsX[i]); + debug_print(","); + debug_println(stickParams.fitCoeffsY[i]); } - Serial.println("The linearized points are:"); -#endif //ARDUINO + debug_println("The linearized points are:"); for(int i = 0; i <= _noOfNotches; i++){ outX[i] = linearize(inX[i], stickParams.fitCoeffsX); outY[i] = linearize(inY[i], stickParams.fitCoeffsY); -#ifdef ARDUINO - Serial.print(outX[i],8); - Serial.print(","); - Serial.println(outY[i],8); -#endif //ARDUINO + debug_print(outX[i],8); + debug_print(","); + debug_println(outY[i],8); } }; @@ -654,39 +676,33 @@ void matrixMatrixMult(const float left[3][3], const float right[3][3], float (&o } void print_mtx(const float matrix[3][3]){ -#ifdef ARDUINO int i, j, nrow, ncol; nrow = 3; ncol = 3; - Serial.println(); + debug_println(); for (i=0; i>1)); - memset(vsync_ssb, BLANK2, HORIZ_bytes + (HORIZ_bytes>>1)); // vertical equalizing/blanking + vsync_ssb = (unsigned char *)malloc(HORIZ_bytes+HORIZ_bytes); + memset(vsync_ssb, BLANK2, HORIZ_bytes + HORIZ_bytes); // vertical equalizing/blanking memset(vsync_ssb, SYNC, HORIZ_EP_bytes); memset(vsync_ssb + (HORIZ_bytes>>1), SYNC, HORIZ_EP_bytes); @@ -208,57 +213,18 @@ int videoOut(const uint8_t pin_base, pleaseCommit = 0; } - gpio_put(0, !gpio_get_out_level(0)); - handleMenuButtons(_bitmap, menuIndex, itemIndex, redraw, changeMade, currentCalStep, pleaseCommit, hardware, config); - gpio_put(0, !gpio_get_out_level(0)); + handleMenuButtons(_bitmap, menuIndex, itemIndex, redraw, changeMade, currentCalStep, pleaseCommit, btn, hardware, config, capture); if(redraw == 2) { //fast redraw redraw = 0; - gpio_put(0, !gpio_get_out_level(0)); drawMenuFast(_bitmap, menuIndex, itemIndex, changeMade, currentCalStep, btn, hardware, raw, config, aStick, cStick); - gpio_put(0, !gpio_get_out_level(0)); } else if(redraw == 1) { //slow redraw redraw = 0; - gpio_put(0, !gpio_get_out_level(0)); + //write interlace offset + _interlaceOffset = config.interlaceOffset; memset(_bitmap, BLACK2, BUFFERLEN); - drawMenu(_bitmap, menuIndex, itemIndex, changeMade, currentCalStep, version, btn, raw, config, aStick, cStick); - gpio_put(0, !gpio_get_out_level(0)); + drawMenu(_bitmap, menuIndex, itemIndex, changeMade, currentCalStep, version, btn, raw, config, aStick, cStick, capture); } - - /* - //drawImage(_bitmap, Quadrants, Quadrants_Index, center-80, center-80); - drawLine(_bitmap, center+ 0, center-100, center+ 74, center- 74, 7); - drawLine(_bitmap, center+100, center+ 0, center+ 74, center- 74, 7); - drawLine(_bitmap, center+100, center+ 0, center+ 74, center+ 74, 7); - drawLine(_bitmap, center+ 0, center+100, center+ 74, center+ 74, 7); - drawLine(_bitmap, center+ 0, center+100, center- 74, center+ 74, 7); - drawLine(_bitmap, center-100, center+ 0, center- 74, center+ 74, 7); - drawLine(_bitmap, center-100, center+ 0, center- 74, center- 74, 7); - drawLine(_bitmap, center+ 0, center-100, center- 74, center- 74, 7); - - drawLine(_bitmap, btn.Cx+1, 256-btn.Cy, btn.Cx+1, 256-btn.Cy, 11); - drawLine(_bitmap, btn.Ax+1, 256-btn.Ay, btn.Ax+1, 256-btn.Ay, WHITE); - //int xList[6] = {0, 5, 23, 45, 60, 74}; - //int yList[6] = {0, -6, -30, -55, -65, -74}; - //graphStickmap(_bitmap, 1, 1, xList, yList, 6, WHITE, POINTGRAPH); - - //char ax[6] = {0, 0, 0, 0, 0, 0}; - //char ay[6] = {0, 0, 0, 0, 0, 0}; - //char cx[6] = {0, 0, 0, 0, 0, 0}; - //char cy[6] = {0, 0, 0, 0, 0, 0}; - //std::to_chars(ax, ax + 5, btn.Ax-127); - //std::to_chars(ay, ay + 5, btn.Ay-127); - //std::to_chars(cx, cx + 5, btn.Cx-127); - //std::to_chars(cy, cy + 5, btn.Cy-127); - drawFloat(_bitmap, 0, 20, 15, 0, raw.axRaw); - drawFloat(_bitmap, 0, 40, 15, 0, raw.ayRaw); - drawFloat(_bitmap, 140, 20, 15, 2, raw.axLinearized); - drawFloat(_bitmap, 140, 40, 15, 2, raw.ayLinearized); - drawInt(_bitmap, 280, 20, 15, 2, int(raw.axUnfiltered)); - drawInt(_bitmap, 280, 40, 15, 2, int(raw.ayUnfiltered)); - - drawFloat(_bitmap, 0, 60, 15, 2, raw.axLinearized*180/M_PI); - */ } } @@ -291,7 +257,7 @@ void __no_inline_not_in_flash_func(cvideo_dma_handler)(void) { dma_channel_set_read_addr(dma_channel, vsync_bb, true); } else { // even field - blank, half line - dma_channel_set_trans_count(dma_channel, HORIZ_bytes/2, false); + dma_channel_set_trans_count(dma_channel, HORIZ_bytes/2 + _interlaceOffset, false); dma_channel_set_read_addr(dma_channel, vsync_bb, true); } break; @@ -315,7 +281,7 @@ void __no_inline_not_in_flash_func(cvideo_dma_handler)(void) { dma_channel_set_read_addr(dma_channel, vsync_ss, true); } else { //even field - equalizing pulse, line and a half - dma_channel_set_trans_count(dma_channel, HORIZ_bytes + HORIZ_bytes/2, false); + dma_channel_set_trans_count(dma_channel, HORIZ_bytes + HORIZ_bytes/2 - _interlaceOffset, false); dma_channel_set_read_addr(dma_channel, vsync_ssb, true); } break; diff --git a/PhobGCC/rp2040/src/drawMenu.cpp b/PhobGCC/rp2040/src/drawMenu.cpp index 281c7d7..5a58992 100644 --- a/PhobGCC/rp2040/src/drawMenu.cpp +++ b/PhobGCC/rp2040/src/drawMenu.cpp @@ -8,6 +8,9 @@ #include "structsAndEnums.h" #include "menuStrings.h" #include "images/cuteGhost.h" +#include "images/stickmaps.h" + +#define ORG 127 void meleeCoordClamp(const int xIn, const int yIn, float &xOut, float &yOut) { const float magnitude = sqrt((float) xIn*xIn + yIn*yIn); @@ -100,9 +103,9 @@ void drawStickCalFast(unsigned char bitmap[], //where to point the stick if(whichStick == ASTICK && itemIndex > -1) { - drawLine(bitmap, xCenter, yCenter, xCenter+btn.Cx-127, yCenter-btn.Cy+127, 12); + drawLine(bitmap, xCenter, yCenter, xCenter+btn.Cx-ORG, yCenter-btn.Cy+ORG, 12); } else if(whichStick == CSTICK && itemIndex > -1) { - drawLine(bitmap, xCenter, yCenter, xCenter+btn.Ax-127, yCenter-btn.Ay+127, 12); + drawLine(bitmap, xCenter, yCenter, xCenter+btn.Ax-ORG, yCenter-btn.Ay+ORG, 12); } else { drawLine(bitmap, xCenter, yCenter, xCenter, yCenter, 15); } @@ -110,15 +113,15 @@ void drawStickCalFast(unsigned char bitmap[], //current stick position, only if currently in notch adj if(itemIndex >= 32 || itemIndex == -1) { if(whichStick == ASTICK) { - drawLine(bitmap, xCenter+btn.Ax-127+1, yCenter-btn.Ay+127+1, xCenter+btn.Ax-127+1, yCenter-btn.Ay+127+0, 15); - drawLine(bitmap, xCenter+btn.Ax-127+1, yCenter-btn.Ay+127-1, xCenter+btn.Ax-127+0, yCenter-btn.Ay+127-1, 15); - drawLine(bitmap, xCenter+btn.Ax-127-1, yCenter-btn.Ay+127-1, xCenter+btn.Ax-127-1, yCenter-btn.Ay+127+0, 15); - drawLine(bitmap, xCenter+btn.Ax-127-1, yCenter-btn.Ay+127+1, xCenter+btn.Ax-127+0, yCenter-btn.Ay+127+1, 15); + drawLine(bitmap, xCenter+btn.Ax-ORG+1, yCenter-btn.Ay+ORG+1, xCenter+btn.Ax-ORG+1, yCenter-btn.Ay+ORG+0, 15); + drawLine(bitmap, xCenter+btn.Ax-ORG+1, yCenter-btn.Ay+ORG-1, xCenter+btn.Ax-ORG+0, yCenter-btn.Ay+ORG-1, 15); + drawLine(bitmap, xCenter+btn.Ax-ORG-1, yCenter-btn.Ay+ORG-1, xCenter+btn.Ax-ORG-1, yCenter-btn.Ay+ORG+0, 15); + drawLine(bitmap, xCenter+btn.Ax-ORG-1, yCenter-btn.Ay+ORG+1, xCenter+btn.Ax-ORG+0, yCenter-btn.Ay+ORG+1, 15); } else { - drawLine(bitmap, xCenter+btn.Cx-127+1, yCenter-btn.Cy+127+1, xCenter+btn.Cx-127+1, yCenter-btn.Cy+127+0, 15); - drawLine(bitmap, xCenter+btn.Cx-127+1, yCenter-btn.Cy+127-1, xCenter+btn.Cx-127+0, yCenter-btn.Cy+127-1, 15); - drawLine(bitmap, xCenter+btn.Cx-127-1, yCenter-btn.Cy+127-1, xCenter+btn.Cx-127-1, yCenter-btn.Cy+127+0, 15); - drawLine(bitmap, xCenter+btn.Cx-127-1, yCenter-btn.Cy+127+1, xCenter+btn.Cx-127+0, yCenter-btn.Cy+127+1, 15); + drawLine(bitmap, xCenter+btn.Cx-ORG+1, yCenter-btn.Cy+ORG+1, xCenter+btn.Cx-ORG+1, yCenter-btn.Cy+ORG+0, 15); + drawLine(bitmap, xCenter+btn.Cx-ORG+1, yCenter-btn.Cy+ORG-1, xCenter+btn.Cx-ORG+0, yCenter-btn.Cy+ORG-1, 15); + drawLine(bitmap, xCenter+btn.Cx-ORG-1, yCenter-btn.Cy+ORG-1, xCenter+btn.Cx-ORG-1, yCenter-btn.Cy+ORG+0, 15); + drawLine(bitmap, xCenter+btn.Cx-ORG-1, yCenter-btn.Cy+ORG+1, xCenter+btn.Cx-ORG+0, yCenter-btn.Cy+ORG+1, 15); } } @@ -129,8 +132,8 @@ void drawStickCalFast(unsigned char bitmap[], drawFloat(bitmap, 30, 360, 15, 0, 6, raw.ayRaw); drawFloat(bitmap, 200, 340, 15, 2, 6, raw.axUnfiltered); drawFloat(bitmap, 200, 360, 15, 2, 6, raw.ayUnfiltered); - const int xCoord = btn.Ax - 127; - const int yCoord = btn.Ay - 127; + const int xCoord = btn.Ax - ORG; + const int yCoord = btn.Ay - ORG; float xMelee; float yMelee; meleeCoordClamp(xCoord, yCoord, xMelee, yMelee); @@ -141,8 +144,8 @@ void drawStickCalFast(unsigned char bitmap[], drawFloat(bitmap, 30, 360, 15, 0, 6, raw.cyRaw); drawFloat(bitmap, 200, 340, 15, 2, 6, raw.cxUnfiltered); drawFloat(bitmap, 200, 360, 15, 2, 6, raw.cyUnfiltered); - const int xCoord = btn.Cx - 127; - const int yCoord = btn.Cy - 127; + const int xCoord = btn.Cx - ORG; + const int yCoord = btn.Cy - ORG; float xMelee; float yMelee; meleeCoordClamp(xCoord, yCoord, xMelee, yMelee); @@ -206,6 +209,12 @@ void drawStickdbg(unsigned char bitmap[], drawFloat(bitmap, 280, 210, 15, 2, 6, raw.cxUnfiltered); drawFloat(bitmap, 30, 230, 15, 2, 6, raw.ayUnfiltered); drawFloat(bitmap, 280, 230, 15, 2, 6, raw.cyUnfiltered); + drawString(bitmap, 30, 260, 15, stickdbgARnd); + drawString(bitmap, 280, 260, 15, stickdbgCRnd); + drawInt(bitmap, 30, 280, 15, 2, btn.Ax - ORG); + drawInt(bitmap, 280, 280, 15, 2, btn.Cx - ORG); + drawInt(bitmap, 30, 300, 15, 2, btn.Ay - ORG); + drawInt(bitmap, 280, 300, 15, 2, btn.Cy - ORG); } else if(itemIndex == 1) { //fit coefficients drawString(bitmap, 30, 50, 15, stickdbgAXfit); @@ -283,87 +292,12 @@ void drawStickdbgFast(unsigned char bitmap[], eraseCharLine(bitmap, 230); drawFloat(bitmap, 30, 230, 15, 2, 6, raw.ayUnfiltered); drawFloat(bitmap, 280, 230, 15, 2, 6, raw.cyUnfiltered); - } -} - -void drawSet_over(unsigned char bitmap[], - const unsigned int menu, - const int itemIndex, - const bool changeMade, - const Buttons btn, - const RawStick raw, - const ControlConfig &controls, - const StickParams &aStick, - const StickParams &cStick) { - drawString(bitmap, 20, 20, 15, MenuNames[menu]); - drawString(bitmap, 30, 50, 15, "AX SB:"); - drawString(bitmap, 30, 70, 15, "AY SB:"); - drawString(bitmap, 30, 90, 15, "AX WS:"); - drawString(bitmap, 30, 110, 15, "AY WS:"); - drawString(bitmap, 30, 130, 15, "AX SM:"); - drawString(bitmap, 30, 150, 15, "AY SM:"); - drawInt(bitmap, 90, 50, 15, 2, controls.xSnapback); - drawInt(bitmap, 90, 70, 15, 2, controls.ySnapback); - drawInt(bitmap, 90, 90, 15, 2, controls.axWaveshaping); - drawInt(bitmap, 90, 110, 15, 2, controls.ayWaveshaping); - drawInt(bitmap, 90, 130, 15, 2, controls.axSmoothing); - drawInt(bitmap, 90, 150, 15, 2, controls.aySmoothing); - drawString(bitmap, 150, 50, 15, "CX SB:"); - drawString(bitmap, 150, 70, 15, "CY SB:"); - drawString(bitmap, 150, 90, 15, "CX WS:"); - drawString(bitmap, 150, 110, 15, "CY WS:"); - drawString(bitmap, 150, 130, 15, "CX OF:"); - drawString(bitmap, 150, 150, 15, "CY OF:"); - drawInt(bitmap, 210, 50, 15, 2, controls.cxSmoothing); - drawInt(bitmap, 210, 70, 15, 2, controls.cySmoothing); - drawInt(bitmap, 210, 90, 15, 2, controls.cxWaveshaping); - drawInt(bitmap, 210, 110, 15, 2, controls.cyWaveshaping); - drawInt(bitmap, 210, 130, 15, 2, controls.cXOffset); - drawInt(bitmap, 210, 150, 15, 2, controls.cYOffset); - drawString(bitmap, 280, 50, 15, "L Mode:"); - drawString(bitmap, 280, 70, 15, "R Mode:"); - drawString(bitmap, 280, 90, 15, "L Val:"); - drawString(bitmap, 280, 110, 15, "R Val:"); - drawString(bitmap, 280, 130, 15, "L WS:"); - drawString(bitmap, 280, 150, 15, "L WS:"); - drawInt(bitmap, 350, 50, 15, 2, controls.lConfig+1); - drawInt(bitmap, 350, 70, 15, 2, controls.rConfig+1); - drawInt(bitmap, 350, 90, 15, 2, controls.lTriggerOffset); - drawInt(bitmap, 350, 110, 15, 2, controls.rTriggerOffset); - drawInt(bitmap, 350, 130, 15, 2, -1);//controls.rTriggerWaveshaping); - drawInt(bitmap, 350, 150, 15, 2, -1);//controls.rTriggerWaveshaping); - drawString(bitmap, 30, 170, 15, "Rumble:"); - drawInt(bitmap, 110, 170, 15, 1, controls.rumble); - if(controls.autoInit) { - drawString(bitmap, 30, 190, 15, set_overAutoOn); - } else { - drawString(bitmap, 30, 190, 15, set_overAutoOff); - } - switch(controls.jumpConfig) { - case DEFAULTJUMP: - drawString(bitmap, 30, 210, 15, set_overJumpDf); - break; - case SWAP_XZ: - drawString(bitmap, 30, 210, 15, set_overJumpXZ); - break; - case SWAP_YZ: - drawString(bitmap, 30, 210, 15, set_overJumpYZ); - break; - case SWAP_XL: - drawString(bitmap, 30, 210, 15, set_overJumpXL); - break; - case SWAP_XR: - drawString(bitmap, 30, 210, 15, set_overJumpXR); - break; - case SWAP_YL: - drawString(bitmap, 30, 210, 15, set_overJumpYL); - break; - case SWAP_YR: - drawString(bitmap, 30, 210, 15, set_overJumpYR); - break; - default: - drawString(bitmap, 30, 210, 15, set_overJumpBr); - break; + eraseCharLine(bitmap, 280); + drawInt(bitmap, 30, 280, 15, 2, btn.Ax - ORG); + drawInt(bitmap, 280, 280, 15, 2, btn.Cx - ORG); + eraseCharLine(bitmap, 300); + drawInt(bitmap, 30, 300, 15, 2, btn.Ay - ORG); + drawInt(bitmap, 280, 300, 15, 2, btn.Cy - ORG); } } @@ -385,14 +319,15 @@ void drawAsnapback(unsigned char bitmap[], drawString(bitmap, 30, 90, 15, asnapback2); drawString(bitmap, 30, 110, 15, asnapback3); drawString(bitmap, 30, 130, 15, asnapback4); - drawString(bitmap, 30, 160, 15, leftStickX); - drawInt( bitmap, 160, 160, 15, 1, controls.xSnapback); - drawString(bitmap, 280, 160, 15, leftStickY); - drawInt( bitmap, 410, 160, 15, 1, controls.ySnapback); + drawString(bitmap, 30, 150, 15, asnapback5); + drawString(bitmap, 30, 180, 15, leftStickX); + drawInt( bitmap, 160, 180, 15, 1, controls.xSnapback); + drawString(bitmap, 280, 180, 15, leftStickY); + drawInt( bitmap, 410, 180, 15, 1, controls.ySnapback); if(itemIndex == 0) { - drawString(bitmap, 10, 160, 15, arrowPointer); + drawString(bitmap, 10, 180, 15, arrowRight); } else { - drawString(bitmap, 260, 160, 15, arrowPointer); + drawString(bitmap, 260, 180, 15, arrowRight); } //graph? } @@ -420,9 +355,9 @@ void drawAwave(unsigned char bitmap[], drawString(bitmap, 280, 160, 15, leftStickY); drawInt( bitmap, 410, 160, 15, 1, controls.ayWaveshaping); if(itemIndex == 0) { - drawString(bitmap, 10, 160, 15, arrowPointer); + drawString(bitmap, 10, 160, 15, arrowRight); } else { - drawString(bitmap, 260, 160, 15, arrowPointer); + drawString(bitmap, 260, 160, 15, arrowRight); } //graph? } @@ -450,9 +385,9 @@ void drawAsmooth(unsigned char bitmap[], drawString(bitmap, 280, 160, 15, leftStickY); drawInt( bitmap, 410, 160, 15, 0, controls.aySmoothing); if(itemIndex == 0) { - drawString(bitmap, 10, 160, 15, arrowPointer); + drawString(bitmap, 10, 160, 15, arrowRight); } else { - drawString(bitmap, 260, 160, 15, arrowPointer); + drawString(bitmap, 260, 160, 15, arrowRight); } //graph? } @@ -480,9 +415,9 @@ void drawCsnapback(unsigned char bitmap[], drawString(bitmap, 280, 160, 15, rightStickY); drawInt( bitmap, 420, 160, 15, 0, controls.cySmoothing); if(itemIndex == 0) { - drawString(bitmap, 10, 160, 15, arrowPointer); + drawString(bitmap, 10, 160, 15, arrowRight); } else { - drawString(bitmap, 260, 160, 15, arrowPointer); + drawString(bitmap, 260, 160, 15, arrowRight); } //graph? } @@ -510,13 +445,14 @@ void drawCwave(unsigned char bitmap[], drawString(bitmap, 280, 160, 15, rightStickY); drawInt( bitmap, 420, 160, 15, 1, controls.cyWaveshaping); if(itemIndex == 0) { - drawString(bitmap, 10, 160, 15, arrowPointer); + drawString(bitmap, 10, 160, 15, arrowRight); } else { - drawString(bitmap, 260, 160, 15, arrowPointer); + drawString(bitmap, 260, 160, 15, arrowRight); } //graph? } +/* void drawCoffset(unsigned char bitmap[], const unsigned int menu, const int itemIndex, @@ -540,12 +476,167 @@ void drawCoffset(unsigned char bitmap[], drawString(bitmap, 280, 160, 15, rightStickY); drawInt( bitmap, 420, 160, 15, 2, controls.cYOffset); if(itemIndex == 0) { - drawString(bitmap, 10, 160, 15, arrowPointer); + drawString(bitmap, 10, 160, 15, arrowRight); } else { - drawString(bitmap, 260, 160, 15, arrowPointer); + drawString(bitmap, 260, 160, 15, arrowRight); } //graph? } +*/ + +void drawCardinals(unsigned char bitmap[], + const unsigned int menu, + const int itemIndex, + const bool changeMade, + const ControlConfig &controls) { + drawString(bitmap, 20, 20, 15, MenuNames[menu]); + if(changeMade) { + drawString(bitmap, 300, 20, 15, bToSave); + } + drawString(bitmap, 30, 50, 15, lr_ud); + drawString(bitmap, 30, 70, 15, cardinals1); + drawString(bitmap, 30, 90, 15, cardinals2); + drawString(bitmap, 30, 110, 15, cardinals3); + drawString(bitmap, 30, 130, 15, cardinals4); + drawString(bitmap, 30, 160, 15, leftStick); + drawInt( bitmap, 150, 160, 15, 0, controls.astickCardinalSnapping); + drawString(bitmap, 280, 160, 15, rightStick); + drawInt( bitmap, 410, 160, 15, 0, controls.cstickCardinalSnapping); + if(itemIndex == 0) { + drawString(bitmap, 10, 160, 15, arrowRight); + } else { + drawString(bitmap, 260, 160, 15, arrowRight); + } +} + +void drawRadius(unsigned char bitmap[], + const unsigned int menu, + const int itemIndex, + const bool changeMade, + const ControlConfig &controls) { + drawString(bitmap, 20, 20, 15, MenuNames[menu]); + if(changeMade) { + drawString(bitmap, 300, 20, 15, bToSave); + } + drawString(bitmap, 30, 50, 15, lr_ud); + drawString(bitmap, 30, 70, 15, radius1); + drawString(bitmap, 30, 90, 15, radius2); + drawString(bitmap, 30, 110, 15, radius3); + drawString(bitmap, 30, 130, 15, radius4); + drawString(bitmap, 30, 160, 15, leftStick); + drawInt( bitmap, 140, 160, 15, 2, controls.astickAnalogScaler); + drawString(bitmap, 280, 160, 15, rightStick); + drawInt( bitmap, 400, 160, 15, 2, controls.cstickAnalogScaler); + if(itemIndex == 0) { + drawString(bitmap, 10, 160, 15, arrowRight); + } else { + drawString(bitmap, 260, 160, 15, arrowRight); + } +} + +void drawSet_over(unsigned char bitmap[], + const unsigned int menu, + const int itemIndex, + const bool changeMade, + const Buttons btn, + const RawStick raw, + const ControlConfig &controls, + const StickParams &aStick, + const StickParams &cStick) { + drawString(bitmap, 20, 20, 15, MenuNames[menu]); + drawString(bitmap, 30, 50, 15, "AX SB:"); + drawString(bitmap, 30, 70, 15, "AY SB:"); + drawString(bitmap, 30, 90, 15, "AX WS:"); + drawString(bitmap, 30, 110, 15, "AY WS:"); + drawString(bitmap, 30, 130, 15, "AX SM:"); + drawString(bitmap, 30, 150, 15, "AY SM:"); + drawInt(bitmap, 90, 50, 15, 2, controls.xSnapback); + drawInt(bitmap, 90, 70, 15, 2, controls.ySnapback); + drawInt(bitmap, 90, 90, 15, 2, controls.axWaveshaping); + drawInt(bitmap, 90, 110, 15, 2, controls.ayWaveshaping); + drawInt(bitmap, 90, 130, 15, 2, controls.axSmoothing); + drawInt(bitmap, 90, 150, 15, 2, controls.aySmoothing); + drawString(bitmap, 150, 50, 15, "CX SB:"); + drawString(bitmap, 150, 70, 15, "CY SB:"); + drawString(bitmap, 150, 90, 15, "CX WS:"); + drawString(bitmap, 150, 110, 15, "CY WS:"); + drawString(bitmap, 150, 130, 15, "A SNP:"); + drawString(bitmap, 150, 150, 15, "A SCA:"); + drawInt(bitmap, 210, 50, 15, 2, controls.cxSmoothing); + drawInt(bitmap, 210, 70, 15, 2, controls.cySmoothing); + drawInt(bitmap, 210, 90, 15, 2, controls.cxWaveshaping); + drawInt(bitmap, 210, 110, 15, 2, controls.cyWaveshaping); + drawInt(bitmap, 210, 130, 15, 2, controls.astickCardinalSnapping); + drawInt(bitmap, 210, 150, 15, 2, controls.astickAnalogScaler); + drawString(bitmap, 280, 50, 15, "L Mode:"); + drawString(bitmap, 280, 70, 15, "R Mode:"); + drawString(bitmap, 280, 90, 15, "L Val:"); + drawString(bitmap, 280, 110, 15, "R Val:"); + drawString(bitmap, 280, 130, 15, "C SNP:"); + drawString(bitmap, 280, 150, 15, "C SCA:"); + drawInt(bitmap, 350, 50, 15, 2, controls.lConfig+1); + drawInt(bitmap, 350, 70, 15, 2, controls.rConfig+1); + drawInt(bitmap, 350, 90, 15, 2, controls.lTriggerOffset); + drawInt(bitmap, 350, 110, 15, 2, controls.rTriggerOffset); + drawInt(bitmap, 350, 130, 15, 2, controls.cstickCardinalSnapping); + drawInt(bitmap, 350, 150, 15, 2, controls.cstickAnalogScaler); + drawString(bitmap, 30, 210, 15, "Rumble:"); + drawInt(bitmap, 110, 210, 15, 1, controls.rumble); + if(controls.autoInit) { + drawString(bitmap, 30, 230, 15, set_overAutoOn); + } else { + drawString(bitmap, 30, 230, 15, set_overAutoOff); + } + switch(controls.jumpConfig) { + case DEFAULTJUMP: + drawString(bitmap, 30, 250, 15, set_overJumpDf); + break; + case SWAP_XZ: + drawString(bitmap, 30, 250, 15, set_overJumpXZ); + break; + case SWAP_YZ: + drawString(bitmap, 30, 250, 15, set_overJumpYZ); + break; + case SWAP_XL: + drawString(bitmap, 30, 250, 15, set_overJumpXL); + break; + case SWAP_XR: + drawString(bitmap, 30, 250, 15, set_overJumpXR); + break; + case SWAP_YL: + drawString(bitmap, 30, 250, 15, set_overJumpYL); + break; + case SWAP_YR: + drawString(bitmap, 30, 250, 15, set_overJumpYR); + break; + default: + drawString(bitmap, 30, 250, 15, set_overJumpBr); + break; + } + switch(controls.tournamentToggle) { + case 0: + drawString(bitmap, 30, 270, 15, tourn0); + break; + case 1: + drawString(bitmap, 30, 270, 15, tourn1); + break; + case 2: + drawString(bitmap, 30, 270, 15, tourn2); + break; + case 3: + drawString(bitmap, 30, 270, 15, tourn3); + break; + case 4: + drawString(bitmap, 30, 270, 15, tourn4); + break; + case 5: + drawString(bitmap, 30, 270, 15, tourn5); + break; + default: + drawString(bitmap, 30, 270, 15, tournBr); + break; + } +} void drawRemap(unsigned char bitmap[], const unsigned int menu, @@ -612,8 +703,9 @@ void drawRumble(unsigned char bitmap[], drawString(bitmap, 30, 90, 15, rumble2); drawString(bitmap, 30, 110, 15, rumble3); drawString(bitmap, 30, 130, 15, rumble4); - drawString(bitmap, 30, 160, 15, currentSetting); - drawInt( bitmap, 190, 160, 15, 0, controls.rumble); + drawString(bitmap, 30, 150, 15, rumble5); + drawString(bitmap, 30, 180, 15, currentSetting); + drawInt( bitmap, 190, 180, 15, 0, controls.rumble); } void drawTrigger(unsigned char bitmap[], @@ -712,9 +804,9 @@ void drawLtrigger(unsigned char bitmap[], drawString(bitmap, 30, 250, 15, lrtrigger23); drawString(bitmap, 30, 310, 15, lrtrigger24); if(itemIndex == 0) { - drawString(bitmap, 10, 100, 15, arrowPointer); + drawString(bitmap, 10, 100, 15, arrowRight); } else { - drawString(bitmap, 260, 100, 15, arrowPointer); + drawString(bitmap, 260, 100, 15, arrowRight); } switch(controls.lConfig) { case 0: @@ -789,9 +881,9 @@ void drawRtrigger(unsigned char bitmap[], drawString(bitmap, 30, 250, 15, lrtrigger23); drawString(bitmap, 30, 310, 15, lrtrigger24); if(itemIndex == 0) { - drawString(bitmap, 10, 100, 15, arrowPointer); + drawString(bitmap, 10, 100, 15, arrowRight); } else { - drawString(bitmap, 260, 100, 15, arrowPointer); + drawString(bitmap, 260, 100, 15, arrowRight); } switch(controls.rConfig) { case 0: @@ -844,6 +936,45 @@ void drawRtrigger(unsigned char bitmap[], //graph? } +void drawTourney(unsigned char bitmap[], + const unsigned int menu, + const bool changeMade, + const ControlConfig &controls) { + drawString(bitmap, 20, 20, 15, MenuNames[menu]); + if(changeMade) { + drawString(bitmap, 300, 20, 15, bToSave); + } + drawString(bitmap, 30, 50, 15, ud_only); + drawString(bitmap, 30, 70, 15, tourney1); + drawString(bitmap, 30, 90, 15, tourney2); + drawString(bitmap, 30, 110, 15, tourney3); + drawString(bitmap, 30, 130, 15, tourney4); + drawString(bitmap, 30, 160, 15, currentSetting); + switch(controls.tournamentToggle) { + case 0: + drawString(bitmap, 200, 160, 15, tourn0); + break; + case 1: + drawString(bitmap, 200, 160, 15, tourn1); + break; + case 2: + drawString(bitmap, 200, 160, 15, tourn2); + break; + case 3: + drawString(bitmap, 200, 160, 15, tourn3); + break; + case 4: + drawString(bitmap, 200, 160, 15, tourn4); + break; + case 5: + drawString(bitmap, 200, 160, 15, tourn5); + break; + default: + drawString(bitmap, 200, 160, 15, tournBr); + break; + } +} + void drawReset(unsigned char bitmap[], const unsigned int menu, const int itemIndex, @@ -860,11 +991,11 @@ void drawReset(unsigned char bitmap[], if(itemIndex == 0 || itemIndex == 2) {//soft reset drawString(bitmap, 30, 70, 15, reset2); drawString(bitmap, 30, 90, 15, reset3); - drawString(bitmap, 10, 120, 15, arrowPointer); + drawString(bitmap, 10, 120, 15, arrowRight); } else { drawString(bitmap, 30, 70, 15, reset4); drawString(bitmap, 30, 90, 15, reset5); - drawString(bitmap, 10, 150, 15, arrowPointer); + drawString(bitmap, 10, 150, 15, arrowRight); } if(itemIndex >= 2) {//confirm drawString(bitmap, 30, 180, 15, reset6); @@ -881,8 +1012,10 @@ void drawInputview(unsigned char bitmap[], const StickParams &aStick, const StickParams &cStick) { drawString(bitmap, 20, 20, 15, MenuNames[menu]); - drawString(bitmap, 280, 50, 15, "Hardware Inputs:"); - drawString(bitmap, 280, 160, 15, "Controller Outputs:"); + drawString(bitmap, 280, 50, 15, inputview1); + drawString(bitmap, 280, 160, 15, inputview2); + drawString(bitmap, 30, 300, 15, inputview3); + drawString(bitmap, 30, 320, 15, inputview4); } void drawInputviewFast(unsigned char bitmap[], @@ -935,8 +1068,8 @@ void drawInputviewFast(unsigned char bitmap[], memset(bitmap + y*VWIDTHBYTE, BLACK2, 128+1/*256 pixels = 128 bytes*/); } - int xCenter = 128;//starts at 1 - int yCenter = 168;//starts at 40 + const int xCenter = 128;//starts at 1 + const int yCenter = 168;//starts at 40 //octagon drawLine(bitmap, xCenter+ 0, yCenter-100, xCenter+74, yCenter-74, 10); @@ -949,16 +1082,771 @@ void drawInputviewFast(unsigned char bitmap[], drawLine(bitmap, xCenter+ 0, yCenter-100, xCenter-74, yCenter-74, 10); //current left stick position - drawLine(bitmap, xCenter+btn.Ax-127+3, yCenter-btn.Ay+127+3, xCenter+btn.Ax-127+3, yCenter-btn.Ay+127-2, 15); - drawLine(bitmap, xCenter+btn.Ax-127+3, yCenter-btn.Ay+127-3, xCenter+btn.Ax-127-2, yCenter-btn.Ay+127-3, 15); - drawLine(bitmap, xCenter+btn.Ax-127-3, yCenter-btn.Ay+127-3, xCenter+btn.Ax-127-3, yCenter-btn.Ay+127+2, 15); - drawLine(bitmap, xCenter+btn.Ax-127-3, yCenter-btn.Ay+127+3, xCenter+btn.Ax-127+2, yCenter-btn.Ay+127+3, 15); + drawLine(bitmap, xCenter+btn.Ax-ORG+3, yCenter-btn.Ay+ORG+3, xCenter+btn.Ax-ORG+3, yCenter-btn.Ay+ORG-2, 15); + drawLine(bitmap, xCenter+btn.Ax-ORG+3, yCenter-btn.Ay+ORG-3, xCenter+btn.Ax-ORG-2, yCenter-btn.Ay+ORG-3, 15); + drawLine(bitmap, xCenter+btn.Ax-ORG-3, yCenter-btn.Ay+ORG-3, xCenter+btn.Ax-ORG-3, yCenter-btn.Ay+ORG+2, 15); + drawLine(bitmap, xCenter+btn.Ax-ORG-3, yCenter-btn.Ay+ORG+3, xCenter+btn.Ax-ORG+2, yCenter-btn.Ay+ORG+3, 15); //current c-stick position - drawLine(bitmap, xCenter+btn.Cx-127+1, yCenter-btn.Cy+127+1, xCenter+btn.Cx-127+1, yCenter-btn.Cy+127+0, 15); - drawLine(bitmap, xCenter+btn.Cx-127+1, yCenter-btn.Cy+127-1, xCenter+btn.Cx-127+0, yCenter-btn.Cy+127-1, 15); - drawLine(bitmap, xCenter+btn.Cx-127-1, yCenter-btn.Cy+127-1, xCenter+btn.Cx-127-1, yCenter-btn.Cy+127+0, 15); - drawLine(bitmap, xCenter+btn.Cx-127-1, yCenter-btn.Cy+127+1, xCenter+btn.Cx-127+0, yCenter-btn.Cy+127+1, 15); + drawLine(bitmap, xCenter+btn.Cx-ORG+1, yCenter-btn.Cy+ORG+1, xCenter+btn.Cx-ORG+1, yCenter-btn.Cy+ORG+0, 15); + drawLine(bitmap, xCenter+btn.Cx-ORG+1, yCenter-btn.Cy+ORG-1, xCenter+btn.Cx-ORG+0, yCenter-btn.Cy+ORG-1, 15); + drawLine(bitmap, xCenter+btn.Cx-ORG-1, yCenter-btn.Cy+ORG-1, xCenter+btn.Cx-ORG-1, yCenter-btn.Cy+ORG+0, 15); + drawLine(bitmap, xCenter+btn.Cx-ORG-1, yCenter-btn.Cy+ORG+1, xCenter+btn.Cx-ORG+0, yCenter-btn.Cy+ORG+1, 15); + + //stick coordinates + eraseCharLine(bitmap, 340); + eraseCharLine(bitmap, 360); + //left stick + drawInt(bitmap, 20, 340, 15, 2, btn.Ax-ORG); + drawInt(bitmap, 20, 360, 15, 2, btn.Ay-ORG); + const int axCoord = btn.Ax - ORG; + const int ayCoord = btn.Ay - ORG; + float axMelee; + float ayMelee; + meleeCoordClamp(axCoord, ayCoord, axMelee, ayMelee); + drawFloat(bitmap, 120, 340, 15, 0, 7, axMelee); + drawFloat(bitmap, 120, 360, 15, 0, 7, ayMelee); + //c-stick + drawInt(bitmap, 280, 340, 15, 2, btn.Cx-ORG); + drawInt(bitmap, 280, 360, 15, 2, btn.Cy-ORG); + const int cxCoord = btn.Cx - ORG; + const int cyCoord = btn.Cy - ORG; + float cxMelee; + float cyMelee; + meleeCoordClamp(cxCoord, cyCoord, cxMelee, cyMelee); + drawFloat(bitmap, 380, 340, 15, 0, 7, cxMelee); + drawFloat(bitmap, 380, 360, 15, 0, 7, cyMelee); +} + +void drawXYScope(unsigned char bitmap[], + const unsigned int menu, + const int itemIndex, + DataCapture &capture) { + drawString(bitmap, 20, 20, 15, MenuNames[menu]); + drawString(bitmap, 240, 20, 15, xyscope5); + + const int xCenter = 128;//starts at 1 + const int yCenter = 168;//starts at 40 + drawString(bitmap, 280, 50, 15, xyscope1); + if(itemIndex == 0) { + if(capture.stickmap != 0) { + drawString(bitmap, 280, 70, 15, arrowLeft); + } + if(capture.stickmap < 6) { + drawString(bitmap, 470, 70, 15, arrowRight); + } + } + switch(capture.stickmap) { + case 0: + drawString(bitmap, 300, 70, 15, stickmap0); + break; + case 1: + drawString(bitmap, 300, 70, 15, stickmap1); + drawImage(bitmap, deadzone_image, deadzone_indexes, 1, 40); + break; + case 2: + drawString(bitmap, 300, 70, 15, stickmap2); + drawImage(bitmap, await_image, await_indexes, 1, 40); + break; + case 3: + drawString(bitmap, 300, 70, 15, stickmap3); + drawImage(bitmap, movewait_image, movewait_indexes, 1, 40); + break; + case 4: + drawString(bitmap, 300, 70, 15, stickmap4); + drawImage(bitmap, crouch_image, crouch_indexes, 1, 40); + break; + case 5: + drawString(bitmap, 300, 70, 15, stickmap5); + drawImage(bitmap, ledgeL_image, ledgeL_indexes, 1, 40); + break; + case 6: + drawString(bitmap, 300, 70, 15, stickmap6); + drawImage(bitmap, ledgeR_image, ledgeR_indexes, 1, 40); + break; + default: + break; + } + + drawString(bitmap, 280, 100, 15, xyscope2); + if(itemIndex == 1) { + if(capture.captureStick == CSTICK) { + drawString(bitmap, 280, 120, 15, arrowLeft); + } else { + drawString(bitmap, 410, 120, 15, arrowRight); + } + } + if(capture.captureStick == ASTICK) { + drawString(bitmap, 300, 120, 15, leftright0); + } else { + drawString(bitmap, 300, 120, 15, leftright1); + } + + drawString(bitmap, 280, 150, 15, xyscope3); + drawInt(bitmap, 290, 170, 15, 1, capture.viewIndex); + if(itemIndex == 2) { + if(capture.viewIndex != 0) { + drawString(bitmap, 280, 170, 15, arrowLeft); + } + if(capture.viewIndex < 99) { + drawString(bitmap, 330, 170, 15, arrowRight); + } + } + + if(capture.done) { + drawString(bitmap, 280, 200, 15, xyscope4); + if(capture.abxyszrl[capture.viewIndex] & 0b0000'0001) { + drawString(bitmap, 280, 220, 15, "A"); + } + if(capture.abxyszrl[capture.viewIndex] & 0b0000'0010) { + drawString(bitmap, 300, 220, 15, "B"); + } + if(capture.abxyszrl[capture.viewIndex] & 0b0000'0100) { + drawString(bitmap, 320, 220, 15, "X"); + } + if(capture.abxyszrl[capture.viewIndex] & 0b0000'1000) { + drawString(bitmap, 340, 220, 15, "Y"); + } + if(capture.abxyszrl[capture.viewIndex] & 0b0001'0000) { + drawString(bitmap, 420, 220, 15, "S"); + } + if(capture.abxyszrl[capture.viewIndex] & 0b0010'0000) { + drawString(bitmap, 400, 220, 15, "Z"); + } + if(capture.abxyszrl[capture.viewIndex] & 0b0100'0000) { + drawString(bitmap, 380, 220, 15, "R"); + } + if(capture.abxyszrl[capture.viewIndex] & 0b1000'0000) { + drawString(bitmap, 360, 220, 15, "L"); + } + + for (int i=0; i < 100; i++) { + const int index = (i + capture.startIndex) % 100; + const int x = capture.a1[index]-ORG; + const int y = capture.a2[index]-ORG; + const int ux = capture.a1Unfilt[index]-ORG; + const int uy = capture.a2Unfilt[index]-ORG; + if(i != capture.viewIndex) { + //unfiltered + drawLine(bitmap, xCenter+ux+0, yCenter-uy+0, xCenter+ux+0, yCenter-uy-0, 13); + //filtered + drawLine(bitmap, xCenter+x+0, yCenter-y+0, xCenter+x+0, yCenter-y-0, 15); + } else { + //unfiltered + drawLine(bitmap, xCenter+ux+1, yCenter-uy+1, xCenter+ux+1, yCenter-uy-(1-1), 13); + drawLine(bitmap, xCenter+ux+1, yCenter-uy-1, xCenter+ux-(1-1), yCenter-uy-1, 13); + drawLine(bitmap, xCenter+ux-1, yCenter-uy-1, xCenter+ux-1, yCenter-uy+(1-1), 13); + drawLine(bitmap, xCenter+ux-1, yCenter-uy+1, xCenter+ux+(1-1), yCenter-uy+1, 13); + //filtered + drawLine(bitmap, xCenter+x+2, yCenter-y+2, xCenter+x+2, yCenter-y-(2-1), 15); + drawLine(bitmap, xCenter+x+2, yCenter-y-2, xCenter+x-(2-1), yCenter-y-2, 15); + drawLine(bitmap, xCenter+x-2, yCenter-y-2, xCenter+x-2, yCenter-y+(2-1), 15); + drawLine(bitmap, xCenter+x-2, yCenter-y+2, xCenter+x+(2-1), yCenter-y+2, 15); + } + } + + //coordinate view + drawString(bitmap, 30, 300, 15, xyscope6); + drawString(bitmap, 30, 320, 15, inputview4);//reused + + //get values at the view index + const int index = (capture.viewIndex + capture.startIndex) % 100; + const int x = capture.a1[index]-ORG; + const int y = capture.a2[index]-ORG; + const int ux = capture.a1Unfilt[index]-ORG; + const int uy = capture.a2Unfilt[index]-ORG; + //unfiltered + drawInt(bitmap, 20, 340, 15, 2, ux); + drawInt(bitmap, 20, 360, 15, 2, uy); + float uxMelee; + float uyMelee; + meleeCoordClamp(ux, uy, uxMelee, uyMelee); + drawFloat(bitmap, 120, 340, 15, 0, 7, uxMelee); + drawFloat(bitmap, 120, 360, 15, 0, 7, uyMelee); + //filtered + drawInt(bitmap, 280, 340, 15, 2, x); + drawInt(bitmap, 280, 360, 15, 2, y); + float xMelee; + float yMelee; + meleeCoordClamp(x, y, xMelee, yMelee); + drawFloat(bitmap, 380, 340, 15, 0, 7, xMelee); + drawFloat(bitmap, 380, 360, 15, 0, 7, yMelee); + } +} + +void drawTimeScope(unsigned char bitmap[], + const unsigned int menu, + const int itemIndex, + DataCapture &capture) { + drawString(bitmap, 20, 20, 15, MenuNames[menu]); + if(itemIndex != 2) { + drawString(bitmap, 240, 20, 15, timescope0); + } else { + drawString(bitmap, 240, 20, 15, xyscope5); + } + + //which input to graph + drawString(bitmap, 30, 300, 15, timescope1); + if(itemIndex == 0) { + drawString(bitmap, 20, 320, 15, arrowRight); + } + if(capture.mode != CM_TRIG) { + if(capture.captureStick == ASTICK) { + drawString(bitmap, 50, 320, 15, "A"); + } else { + drawString(bitmap, 50, 320, 15, "C"); + } + if(capture.whichAxis == XAXIS) { + drawString(bitmap, 60, 320, 15, "X"); + } else { + drawString(bitmap, 60, 320, 15, "Y"); + } + } else {//if(capture.mode == CM_TRIG) + if(capture.captureStick == ASTICK) { + drawString(bitmap, 50, 320, 15, "L"); + } else { + drawString(bitmap, 50, 320, 15, "R"); + } + } + + //what to trigger upon + drawString(bitmap, 140, 300, 15, timescope2); + if(itemIndex == 1) { + drawString(bitmap, 130, 320, 8+7*(capture.mode != CM_TRIG), arrowRight); + } + switch(capture.mode) { + case CM_STICK_FALL: + drawString(bitmap, 160, 320, 15, timescope3); + break; + case CM_STICK_RISE: + drawString(bitmap, 160, 320, 15, timescope4); + break; + case CM_STICK_PIVOT: + drawString(bitmap, 160, 320, 15, timescope5); + break; + case CM_TRIG: + drawString(bitmap, 160, 320, 15, timescope6); + break; + default: + break; + } + + //which sample point to view info of + drawString(bitmap, 290, 300, 15, xyscope3); + drawInt(bitmap, 300, 320, 15, 2, capture.viewIndex); + if(itemIndex == 2) { + drawString(bitmap, 280, 320, 15, arrowRight); + } + + //% chance of success readout (TODO) + + const int xCenter = 5; + const int yCenter = 168;//starts at 40 + + //draw axes for the graph + drawLine(bitmap, xCenter-1, yCenter+ORG, xCenter-1, yCenter-ORG, 9);//y-axis + switch(capture.mode) { + case CM_STICK_FALL: + drawLine(bitmap, xCenter, yCenter, xCenter+399, yCenter, 9);//x-axis + drawLine(bitmap, xCenter, yCenter+23, xCenter+399, yCenter+23, 8);//deadzone - + drawLine(bitmap, xCenter, yCenter-23, xCenter+399, yCenter-23, 8);//deadzone + + break; + case CM_STICK_RISE: + drawLine(bitmap, xCenter, yCenter, xCenter+399, yCenter, 9);//x-axis + drawLine(bitmap, xCenter, yCenter+23, xCenter+399, yCenter+23, 8);//deadzone - + drawLine(bitmap, xCenter, yCenter-23, xCenter+399, yCenter-23, 8);//deadzone + + drawLine(bitmap, xCenter, yCenter+64, xCenter+399, yCenter+64, 8);//dash - + drawLine(bitmap, xCenter, yCenter-64, xCenter+399, yCenter-64, 8);//dash + + break; + case CM_STICK_PIVOT: + drawLine(bitmap, xCenter, yCenter, xCenter+399, yCenter, 9);//x-axis + drawLine(bitmap, xCenter, yCenter+64, xCenter+399, yCenter+64, 8);//dash - + drawLine(bitmap, xCenter, yCenter-64, xCenter+399, yCenter-64, 8);//dash + + break; + case CM_TRIG: + drawLine(bitmap, xCenter, yCenter+ORG, xCenter+399, yCenter+ORG, 9);//x-axis + drawLine(bitmap, xCenter, yCenter+ORG-43, xCenter+399, yCenter+ORG-43, 8);//lightshield + break; + default: + break; + } + + int oldY = capture.a1[capture.startIndex+1 % 200] - ORG; + + //draw the actual graph + for (int i=0; i < 200; i++) { + const int index = (i + capture.startIndex+1) % 200; + const int zeroY = capture.a1[index]; + const int y = zeroY-ORG; + const int uy = capture.a1Unfilt[index]-ORG; + + //highlight trigger + if(capture.mode == CM_TRIG) { + drawLine(bitmap, xCenter+i*2-1, yCenter+10, xCenter+i*2, yCenter+10, 5+10*capture.abxyszrl[index]); + } + if(capture.mode == CM_TRIG && (zeroY >= 43)) { + drawLine(bitmap, xCenter+i*2-1, yCenter+ORG-43, xCenter+i*2, yCenter+ORG-43, 15); + } + + //unfiltered + drawLine(bitmap, xCenter+i*2+0, yCenter-uy+0, xCenter+i*2+0, yCenter-uy-0, 11); + //filtered + drawLine(bitmap, xCenter+i*2-1+0, yCenter-oldY+0, xCenter+i*2+0, yCenter-y-0, 15); + + //highlight + if(i == capture.viewIndex) { + //unfiltered + drawLine(bitmap, xCenter+i*2+1, yCenter-uy+1, xCenter+i*2+1, yCenter-uy-(1-1), 11); + drawLine(bitmap, xCenter+i*2+1, yCenter-uy-1, xCenter+i*2-(1-1), yCenter-uy-1, 11); + drawLine(bitmap, xCenter+i*2-1, yCenter-uy-1, xCenter+i*2-1, yCenter-uy+(1-1), 11); + drawLine(bitmap, xCenter+i*2-1, yCenter-uy+1, xCenter+i*2+(1-1), yCenter-uy+1, 11); + //filtered + drawLine(bitmap, xCenter+i*2+2, yCenter-y+2, xCenter+i*2+2, yCenter-y-(2-1), 15); + drawLine(bitmap, xCenter+i*2+2, yCenter-y-2, xCenter+i*2-(2-1), yCenter-y-2, 15); + drawLine(bitmap, xCenter+i*2-2, yCenter-y-2, xCenter+i*2-2, yCenter-y+(2-1), 15); + drawLine(bitmap, xCenter+i*2-2, yCenter-y+2, xCenter+i*2+(2-1), yCenter-y+2, 15); + } + + oldY = y; + } + + //draw percent success rates + switch(capture.mode) { + case CM_STICK_FALL: + drawString(bitmap, 410, 80, 15, timescope9); + drawFloat(bitmap, 410, 110, 15, 2, 6, capture.percents[0]); + drawString(bitmap, 470, 110, 15, "%"); + drawString(bitmap, 410, 210, 15, timescope10); + drawFloat(bitmap, 410, 240, 15, 2, 6, fmax(0, 100-capture.percents[0])); + drawString(bitmap, 470, 240, 15, "%"); + break; + case CM_STICK_RISE: + drawString(bitmap, 410, 80, 15, timescope11); + drawFloat(bitmap, 410, 110, 15, 2, 4, capture.percents[0]); + drawString(bitmap, 450, 110, 15, "%"); + break; + case CM_STICK_PIVOT: + drawString(bitmap, 410, 80, 15, timescope14); + drawFloat(bitmap, 410, 110, 15, 2, 4, round(capture.percents[0])); + drawString(bitmap, 450, 110, 15, "%"); + drawString(bitmap, 410, 140, 15, timescope12); + drawString(bitmap, 410, 160, 15, timescope13); + drawFloat(bitmap, 410, 190, 15, 2, 4, round(capture.percents[1])); + drawString(bitmap, 450, 190, 15, "%"); + drawString(bitmap, 410, 220, 15, timescope11); + drawFloat(bitmap, 410, 250, 15, 2, 4, round(capture.percents[2])); + drawString(bitmap, 450, 250, 15, "%"); + break; + case CM_TRIG: + drawString(bitmap, 410, 80, 15, timescope15); + drawFloat(bitmap, 410, 110, 15, 2, 4, round(capture.percents[0])); + drawString(bitmap, 450, 110, 15, "%"); + drawString(bitmap, 410, 150, 15, timescope16); + drawFloat(bitmap, 410, 180, 15, 2, 4, round(capture.percents[1])); + drawString(bitmap, 450, 180, 15, "%"); + drawString(bitmap, 410, 220, 15, timescope17); + drawFloat(bitmap, 410, 250, 15, 2, 4, round(capture.percents[2])); + drawString(bitmap, 450, 250, 15, "%"); + break; + default: + break; + } + + //coordinate view + drawString(bitmap, 30, 350, 15, timescope7); + drawString(bitmap, 280, 350, 15, timescope8); + + //get values at the view index + const int index = (capture.viewIndex + capture.startIndex+1) % 200; + const int origin = (capture.mode == CM_TRIG) ? 0 : ORG; + const int y = capture.a1[index]-origin; + const int uy = capture.a1Unfilt[index]-origin; + //filtered + drawInt(bitmap, 140, 350, 15, 2, y); + //unfiltered + drawInt(bitmap, 410, 350, 15, 2, uy); +} + +void drawPressSlice(unsigned char bitmap[], + const uint8_t frame, + DataCapture &capture) { + const int x0 = 40 + 2*frame; + const int x1 = x0 + 1; + + //frame boundary lines + if(fmod(frame, 16.666667f) < 1) { + drawLine(bitmap, x0, 145, x0, 350, 9); + drawLine(bitmap, x1, 145, x1, 350, 9); + } + + //button presses + if(capture.abxyszrl[frame] & 0b0000'0001) {//A + drawLine(bitmap, x0, 150 + 0*15, x0, 162 + 0*15, 15); + drawLine(bitmap, x1, 150 + 0*15, x1, 162 + 0*15, 15); + } + if(capture.abxyszrl[frame] & 0b0000'0010) {//B + drawLine(bitmap, x0, 150 + 1*15, x0, 162 + 1*15, 15); + drawLine(bitmap, x1, 150 + 1*15, x1, 162 + 1*15, 15); + } + if(capture.abxyszrl[frame] & 0b0000'0100) {//X + drawLine(bitmap, x0, 150 + 2*15, x0, 162 + 2*15, 15); + drawLine(bitmap, x1, 150 + 2*15, x1, 162 + 2*15, 15); + } + if(capture.abxyszrl[frame] & 0b0000'1000) {//Y + drawLine(bitmap, x0, 150 + 3*15, x0, 162 + 3*15, 15); + drawLine(bitmap, x1, 150 + 3*15, x1, 162 + 3*15, 15); + } + if(capture.abxyszrl[frame] & 0b1000'0000) {//L + drawLine(bitmap, x0, 150 + 4*15, x0, 162 + 4*15, 15); + drawLine(bitmap, x1, 150 + 4*15, x1, 162 + 4*15, 15); + } + if(capture.axaycxcyrl[frame] & 0b0010'0000) {//La + drawLine(bitmap, x0, 150 + 5*15, x0, 162 + 5*15, 15); + drawLine(bitmap, x1, 150 + 5*15, x1, 162 + 5*15, 15); + } + if(capture.abxyszrl[frame] & 0b0100'0000) {//R + drawLine(bitmap, x0, 150 + 6*15, x0, 162 + 6*15, 15); + drawLine(bitmap, x1, 150 + 6*15, x1, 162 + 6*15, 15); + } + if(capture.axaycxcyrl[frame] & 0b0001'0000) {//Ra + drawLine(bitmap, x0, 150 + 7*15, x0, 162 + 7*15, 15); + drawLine(bitmap, x1, 150 + 7*15, x1, 162 + 7*15, 15); + } + if(capture.abxyszrl[frame] & 0b0010'0000) {//Z + drawLine(bitmap, x0, 150 + 8*15, x0, 162 + 8*15, 15); + drawLine(bitmap, x1, 150 + 8*15, x1, 162 + 8*15, 15); + } + if(capture.axaycxcyrl[frame] & 0b0000'0001) {//Ax + drawLine(bitmap, x0, 150 + 9*15, x0, 162 + 9*15, 15); + drawLine(bitmap, x1, 150 + 9*15, x1, 162 + 9*15, 15); + } + if(capture.axaycxcyrl[frame] & 0b0000'0010) {//Ay + drawLine(bitmap, x0, 150 + 10*15, x0, 162 + 10*15, 15); + drawLine(bitmap, x1, 150 + 10*15, x1, 162 + 10*15, 15); + } + if(capture.axaycxcyrl[frame] & 0b0000'0100) {//Cx + drawLine(bitmap, x0, 150 + 11*15, x0, 162 + 11*15, 15); + drawLine(bitmap, x1, 150 + 11*15, x1, 162 + 11*15, 15); + } + if(capture.axaycxcyrl[frame] & 0b0000'1000) {//Cy + drawLine(bitmap, x0, 150 + 12*15, x0, 162 + 12*15, 15); + drawLine(bitmap, x1, 150 + 12*15, x1, 162 + 12*15, 15); + } +} + +void drawPressFrames(unsigned char bitmap[], + DataCapture &capture) { + int8_t a = 0; + int8_t b = 0; + int8_t x = 0; + int8_t y = 0; + int8_t l = 0; + int8_t la = 0; + int8_t r = 0; + int8_t ra = 0; + int8_t z = 0; + int8_t ax = 0; + int8_t ay = 0; + int8_t cx = 0; + int8_t cy = 0; + + int frame = 16; + + //was it pressed initially? + if(capture.abxyszrl[0] & 0b0000'0001) {//A + a = -1; + } + if(capture.abxyszrl[0] & 0b0000'0010) {//B + b = -1; + } + if(capture.abxyszrl[0] & 0b0000'0100) {//X + x = -1; + } + if(capture.abxyszrl[0] & 0b0000'1000) {//Y + y = -1; + } + if(capture.abxyszrl[0] & 0b1000'0000) {//L + l = -1; + } + if(capture.axaycxcyrl[0] & 0b0010'0000) {//La + la = -1; + } + if(capture.abxyszrl[0] & 0b0100'0000) {//R + r = -1; + } + if(capture.axaycxcyrl[0] & 0b0001'0000) {//Ra + ra = -1; + } + if(capture.abxyszrl[0] & 0b0010'0000) {//Z + z = -1; + } + if(capture.axaycxcyrl[0] & 0b0000'0001) {//Ax + ax = -1; + } + if(capture.axaycxcyrl[0] & 0b0000'0010) {//Ay + ay = -1; + } + if(capture.axaycxcyrl[0] & 0b0000'0100) {//Cx + cx = -1; + } + if(capture.axaycxcyrl[0] & 0b0000'1000) {//Cy + cy = -1; + } + + for(int frame = 1; frame < 200; frame++) { + if(capture.abxyszrl[frame] & 0b0000'0001) {//A + if(a == 0) { + a = 1; + drawFloat(bitmap, 440, 150 + 0*15, 15, 1, 6, frame/16.666667); + } + } else { + if(a == -1) { + a = 1; + drawFloat(bitmap, 440, 150 + 0*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.abxyszrl[frame] & 0b0000'0010) {//B + if(b == 0) { + b = 1; + drawFloat(bitmap, 440, 150 + 1*15, 15, 1, 6, frame/16.666667); + } + } else { + if(b == -1) { + b = 1; + drawFloat(bitmap, 440, 150 + 1*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.abxyszrl[frame] & 0b0000'0100) {//X + if(x == 0) { + x = 1; + drawFloat(bitmap, 440, 150 + 2*15, 15, 1, 6, frame/16.666667); + } + } else { + if(x == -1) { + x = 1; + drawFloat(bitmap, 440, 150 + 2*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.abxyszrl[frame] & 0b0000'1000) {//Y + if(y == 0) { + y = 1; + drawFloat(bitmap, 440, 150 + 3*15, 15, 1, 6, frame/16.666667); + } + } else { + if(y == -1) { + y = 1; + drawFloat(bitmap, 440, 150 + 3*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.abxyszrl[frame] & 0b1000'0000) {//L + if(l == 0) { + l = 1; + drawFloat(bitmap, 440, 150 + 4*15, 15, 1, 6, frame/16.666667); + } + } else { + if(l == -1) { + l = 1; + drawFloat(bitmap, 440, 150 + 4*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.axaycxcyrl[frame] & 0b0010'0000) {//La + if(la == 0) { + la = 1; + drawFloat(bitmap, 440, 150 + 5*15, 15, 1, 6, frame/16.666667); + } + } else { + if(la == -1) { + la = 1; + drawFloat(bitmap, 440, 150 + 5*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.abxyszrl[frame] & 0b0100'0000) {//R + if(r == 0) { + r = 1; + drawFloat(bitmap, 440, 150 + 6*15, 15, 1, 6, frame/16.666667); + } + } else { + if(r == -1) { + r = 1; + drawFloat(bitmap, 440, 150 + 6*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.axaycxcyrl[frame] & 0b0001'0000) {//Ra + if(ra == 0) { + ra = 1; + drawFloat(bitmap, 440, 150 + 7*15, 15, 1, 6, frame/16.666667); + } + } else { + if(ra == -1) { + ra = 1; + drawFloat(bitmap, 440, 150 + 7*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.abxyszrl[frame] & 0b0010'0000) {//Z + if(z == 0) { + z = 1; + drawFloat(bitmap, 440, 150 + 8*15, 15, 1, 6, frame/16.666667); + } + } else { + if(z == -1) { + z = 1; + drawFloat(bitmap, 440, 150 + 8*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.axaycxcyrl[frame] & 0b0000'0001) {//Ax + if(ax == 0) { + ax = 1; + drawFloat(bitmap, 440, 150 + 9*15, 15, 1, 6, frame/16.666667); + } + } else { + if(ax == -1) { + ax = 1; + drawFloat(bitmap, 440, 150 + 9*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.axaycxcyrl[frame] & 0b0000'0010) {//Ay + if(ay == 0) { + ay = 1; + drawFloat(bitmap, 440, 150 + 10*15, 15, 1, 6, frame/16.666667); + } + } else { + if(ay == -1) { + ay = 1; + drawFloat(bitmap, 440, 150 + 10*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.axaycxcyrl[frame] & 0b0000'0100) {//Cx + if(cx == 0) { + cx = 1; + drawFloat(bitmap, 440, 150 + 11*15, 15, 1, 6, frame/16.666667); + } + } else { + if(cx == -1) { + cx = 1; + drawFloat(bitmap, 440, 150 + 11*15, 15, 1, 6, frame/16.666667); + } + } + if(capture.axaycxcyrl[frame] & 0b0000'1000) {//Cy + if(cy == 0) { + cy = 1; + drawFloat(bitmap, 440, 150 + 12*15, 15, 1, 6, frame/16.666667); + } + } else { + if(cy == -1) { + cy = 1; + drawFloat(bitmap, 440, 150 + 12*15, 15, 1, 6, frame/16.666667); + } + } + } +} + +void drawPresstime(unsigned char bitmap[], + const unsigned int menu, + const int itemIndex, + DataCapture &capture) { + drawString(bitmap, 20, 20, 15, MenuNames[menu]); + drawString(bitmap, 30, 50, 15, presstime1); + drawString(bitmap, 30, 70, 15, presstime2); + drawString(bitmap, 30, 90, 15, reaction3); + drawString(bitmap, 30, 120, 15, reaction4); + drawInt( bitmap, 90, 120, 15, 2, capture.stickThresh); + drawString(bitmap, 170, 120, 15, reaction5); + drawInt( bitmap, 250, 120, 15, 2, capture.triggerThresh); + drawString(bitmap, 330, 120, 15, presstime4); + if(capture.autoRepeat) { + drawString(bitmap, 460, 120, 15, presstime5); + } else { + drawString(bitmap, 460, 120, 15, presstime6); + } + if(itemIndex == 0) { + drawString(bitmap, 10, 120, 15, arrowRight); + } else if (itemIndex == 1) { + drawString(bitmap, 150, 120, 15, arrowRight); + } else { + drawString(bitmap, 310, 120, 15, arrowRight); + } + + drawString(bitmap, 10, 150 + 0*15, 15, "A"); + drawString(bitmap, 10, 150 + 1*15, 15, "B"); + drawString(bitmap, 10, 150 + 2*15, 15, "X"); + drawString(bitmap, 10, 150 + 3*15, 15, "Y"); + drawString(bitmap, 10, 150 + 4*15, 15, "L"); + drawString(bitmap, 10, 150 + 5*15, 15, "La"); + drawString(bitmap, 10, 150 + 6*15, 15, "R"); + drawString(bitmap, 10, 150 + 7*15, 15, "Ra"); + drawString(bitmap, 10, 150 + 8*15, 15, "Z"); + drawString(bitmap, 10, 150 + 9*15, 15, "AX"); + drawString(bitmap, 10, 150 + 10*15, 15, "AY"); + drawString(bitmap, 10, 150 + 11*15, 15, "CX"); + drawString(bitmap, 10, 150 + 12*15, 15, "CY"); + + for(int frame = 0; frame < 200; frame++) { + drawPressSlice(bitmap, frame, capture); + } + + drawPressFrames(bitmap, capture); + + if(capture.begin == false && capture.done == false) { + drawString(bitmap, 30, 360, 15, presstime3); + } +} + +//You wait a random amount of time before actually calling this draw function +//Then the draw function, as soon as it is done, initiates recording +void drawReaction(unsigned char bitmap[], + const unsigned int menu, + const int itemIndex, + DataCapture &capture) { + drawString(bitmap, 20, 20, 15, MenuNames[menu]); + drawString(bitmap, 30, 50, 15, reaction1); + drawString(bitmap, 30, 70, 15, reaction2); + drawString(bitmap, 30, 90, 15, reaction3); + drawString(bitmap, 30, 120, 15, reaction4); + drawInt( bitmap, 160, 120, 15, 0, capture.stickThresh); + drawString(bitmap, 280, 120, 15, reaction5); + drawInt( bitmap, 410, 120, 15, 0, capture.triggerThresh); + if(itemIndex == 0) { + drawString(bitmap, 10, 120, 15, arrowRight); + } else { + drawString(bitmap, 260, 120, 15, arrowRight); + } + if(!capture.done) { + //draw white square + for(int i = 0; i < 50; i++) { + memset(bitmap + (180+i)*VWIDTHBYTE + 128 - 12, WHITE2, 25/*50 pixels wide*/); + } + //start capture + capture.mode = CM_REACTION; + } else { + //write the reaction time to the screen + drawString(bitmap, 30, 300, 15, reaction6); + drawInt( bitmap, 60, 300, 15, 0, capture.delay); + drawString(bitmap, 280, 300, 15, reaction7); + drawFloat( bitmap, 350, 300, 15, 1, 5, capture.delay/16.667f); + } +} + +void drawVision(unsigned char bitmap[], + const unsigned int menu, + const int itemIndex, + const bool changeMade, + const Buttons btn, + const RawStick raw, + const ControlConfig &controls, + const StickParams &aStick, + const StickParams &cStick) { + drawString(bitmap, 20, 20, 15, MenuNames[menu]); + if(changeMade) { + drawString(bitmap, 300, 20, 15, bToSave); + } + drawString(bitmap, 30, 50, 15, vision1); + drawString(bitmap, 30, 70, 15, vision2); + drawString(bitmap, 30, 100, 15, vision3); + drawInt(bitmap, 220, 100, 15, 2, controls.interlaceOffset); + drawLine(bitmap, 500, 1, 1, 101, 15); + drawLine(bitmap, 500, 101, 1, 201, 15); + drawLine(bitmap, 500, 201, 1, 301, 15); + drawLine(bitmap, 500, 301, 1, 380, 15); } void drawMenuFast(unsigned char bitmap[], @@ -977,7 +1865,7 @@ void drawMenuFast(unsigned char bitmap[], for(int i = 0; i < MenuIndex[menu][1]; i++) { drawString(bitmap, 50, 80 + 30*i, 15, MenuNames[MenuIndex[menu][i+2]]); } - drawString(bitmap, 20, 80 + 30*itemIndex, 15, arrowPointer); + drawString(bitmap, 20, 80 + 30*itemIndex, 15, arrowRight); } switch(menu) { case MENU_ASTICKCAL: @@ -1012,7 +1900,8 @@ void drawMenu(unsigned char bitmap[], const RawStick raw, const ControlConfig &controls, const StickParams &aStick, - const StickParams &cStick) { + const StickParams &cStick, + DataCapture &capture) { //Basic menus if(MenuIndex[menu][1] == 0) { drawImage(bitmap, Cute_Ghost, Cute_Ghost_Index, VWIDTH/2-112, 0);//224x300 @@ -1032,7 +1921,7 @@ void drawMenu(unsigned char bitmap[], for(int i = 0; i < MenuIndex[menu][1]; i++) { drawString(bitmap, 50, 80 + 30*i, 15, MenuNames[MenuIndex[menu][i+2]]); } - drawString(bitmap, 20, 80 + 30*itemIndex, 15, arrowPointer); + drawString(bitmap, 20, 80 + 30*itemIndex, 15, arrowRight); } else { //placeholder for other screens that don't need menu graphics drawn } @@ -1052,9 +1941,6 @@ void drawMenu(unsigned char bitmap[], case MENU_STICKDBG: drawStickdbg(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); break; - case MENU_SET_OVER: - drawSet_over(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); - break; case MENU_ASNAPBACK: drawAsnapback(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); break; @@ -1070,9 +1956,20 @@ void drawMenu(unsigned char bitmap[], case MENU_CWAVE: drawCwave(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); break; + /* case MENU_COFFSET: drawCoffset(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); break; + */ + case MENU_CARDINALS: + drawCardinals(bitmap, menu, itemIndex, changeMade, controls); + break; + case MENU_RADIUS: + drawRadius(bitmap, menu, itemIndex, changeMade, controls); + break; + case MENU_SET_OVER: + drawSet_over(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); + break; case MENU_REMAP: drawRemap(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); break; @@ -1088,12 +1985,30 @@ void drawMenu(unsigned char bitmap[], case MENU_RTRIGGER: drawRtrigger(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); break; + case MENU_TOURNEY: + drawTourney(bitmap, menu, changeMade, controls); + break; case MENU_RESET: drawReset(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); break; case MENU_INPUTVIEW: drawInputview(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); break; + case MENU_XYSCOPE: + drawXYScope(bitmap, menu, itemIndex, capture); + break; + case MENU_TIMESCOPE: + drawTimeScope(bitmap, menu, itemIndex, capture); + break; + case MENU_PRESSTIME: + drawPresstime(bitmap, menu, itemIndex, capture); + break; + case MENU_REACTION: + drawReaction(bitmap, menu, itemIndex, capture); + break; + case MENU_VISION: + drawVision(bitmap, menu, itemIndex, changeMade, btn, raw, controls, aStick, cStick); + break; default: //placeholder for screens that don't have anything defined if(MenuIndex[menu][1] > 6) { diff --git a/PhobGCC/rp2040/src/joybus.cpp b/PhobGCC/rp2040/src/joybus.cpp index a385fd1..3deecb2 100644 --- a/PhobGCC/rp2040/src/joybus.cpp +++ b/PhobGCC/rp2040/src/joybus.cpp @@ -6,6 +6,7 @@ #include "hardware/pio.h" #include "joybus.pio.h" +#define ORG 127 /* PIOs are separate state machines for handling IOs with high timing precision. You load a program into them and they do their stuff on their own with deterministic timing, communicating with the main cores via FIFOs (and interrupts, if you want). @@ -64,21 +65,6 @@ void __time_critical_func(enterMode)(const int dataPin, gpio_set_dir(dataPin, GPIO_IN); gpio_pull_up(dataPin); - gpio_init(rumblePin); - gpio_init(brakePin); - gpio_set_dir(rumblePin, GPIO_OUT); - gpio_set_dir(brakePin, GPIO_OUT); - gpio_set_function(rumblePin, GPIO_FUNC_PWM); - gpio_set_function(brakePin, GPIO_FUNC_PWM); - const uint rumbleSlice_num = pwm_gpio_to_slice_num(rumblePin); - const uint brakeSlice_num = pwm_gpio_to_slice_num(brakePin); - pwm_set_wrap(rumbleSlice_num, 255); - pwm_set_wrap(brakeSlice_num, 255); - pwm_set_chan_level(rumbleSlice_num, PWM_CHAN_B, 0);//B for odd pins - pwm_set_chan_level(brakeSlice_num, PWM_CHAN_B, 255);//B for odd pins - pwm_set_enabled(rumbleSlice_num, true); - pwm_set_enabled(brakeSlice_num, true); - sleep_us(100); // Stabilize voltages PIO pio = pio0; @@ -115,7 +101,7 @@ void __time_critical_func(enterMode)(const int dataPin, } else if (buffer[0] == 0x41) { // Origin (NOT 0x81) gpio_put(25, 1); - uint8_t originResponse[10] = { 0x00, 0x80, 127, 127, 127, 127, 0, 0, 0, 0 }; + uint8_t originResponse[10] = { 0x00, 0x80, ORG, ORG, ORG, ORG, 0, 0, 0, 0 }; // TODO The origin response sends centered values in this code excerpt. Consider whether that makes sense for your project (digital controllers -> yes) uint32_t result[6]; int resultLen; diff --git a/PhobGCC/rp2040/src/main.cpp b/PhobGCC/rp2040/src/main.cpp index 286eea8..53db076 100644 --- a/PhobGCC/rp2040/src/main.cpp +++ b/PhobGCC/rp2040/src/main.cpp @@ -11,10 +11,10 @@ volatile bool _videoOut = false; //Variables used by PhobVision to communicate with the event loop core -volatile bool _vsyncSensors = false; volatile bool _sync = false; volatile uint8_t _pleaseCommit = 0;//255 = redraw please int _currentCalStep = -1;//-1 means not calibrating +DataCapture _dataCapture; //This gets called by the comms library GCReport __no_inline_not_in_flash_func(buttonsToGCReport)() { @@ -70,6 +70,7 @@ void second_core() { if(_pleaseCommit != 0) { if(_pleaseCommit == 1) { _pleaseCommit = 0; + recomputeGains(_controls, _gains, _normGains); commitSettings(); } else if(_pleaseCommit == 2) { _pleaseCommit = 0; @@ -98,24 +99,560 @@ void second_core() { _pleaseCommit = 255; calibrationUndo(_currentCalStep, whichStick, notchStatus); } else if(_pleaseCommit == 7) { - //skip cal (might not actually get used?) + //skip cal (might not actually get used?) (it's available but not shown) _pleaseCommit = 255; - calibrationSkipMeasurement(_currentCalStep, whichStick, tempCalPointsX, tempCalPointsY, notchStatus, notchAngles, measuredNotchAngles, _aStickParams, _cStickParams); + calibrationSkipMeasurement(_currentCalStep, whichStick, tempCalPointsX, tempCalPointsY, notchStatus, notchAngles, measuredNotchAngles, _aStickParams, _cStickParams, _controls); + } else if(_pleaseCommit == 8) { + _pleaseCommit = 0; + _rumblePower = calcRumblePower(_controls.rumble); + //rumble for 0.3 seconds + pwm_set_gpio_level(_pinBrake, 0); + pwm_set_gpio_level(_pinRumble, _rumblePower); + int startTime = millis(); + int delta = 0; + while(delta < 300) { + delta = millis() - startTime; + } + pwm_set_gpio_level(_pinRumble, 0); + pwm_set_gpio_level(_pinBrake, 255); + } else if(_pleaseCommit == 9) { + switch(_dataCapture.mode) { + //make sure that we can write 200 things in a1 (clobbering a2) for longer recording + //this is used for single-axis recording + static_assert(&_dataCapture.a1[100] == &_dataCapture.a2[0]); + static_assert(&_dataCapture.a1Unfilt[100] == &_dataCapture.a2Unfilt[0]); + + case CM_REACTION: + //this expects that you initialize data capture by setting delay to 0 + _dataCapture.delay++; + if( + //_btn.arr[0] & 0b11110000 ||//abxy + //_btn.arr[1] & 0b11111110 ||//dpad, lrz + _btn.arr[0] & 0b00001111 ||//abxy + _btn.arr[1] & 0b01111111 ||//dpad, lrz + max(max(abs(int(_btn.Ax)-127), abs(int(_btn.Ay)-127)), + max(abs(int(_btn.Cx)-127), abs(int(_btn.Cy)-127))) >= _dataCapture.stickThresh || + max(_btn.La, _btn.Ra) >= _dataCapture.triggerThresh) { + _dataCapture.done = true; + _pleaseCommit = 255;//end capture and display + } + break; + case CM_STICK_RISE2: + //100 points of 2-axis data + //this begins capturing data immediately in a rolling buffer, + //and on detecting a rising edge it begins recording + //this records the starting point only the first time, then it sets begin + static int x0; + static int y0; + + if(!_dataCapture.begin && !_dataCapture.done) { + _dataCapture.begin = true; + _dataCapture.done = false; + _dataCapture.startIndex = 0; + _dataCapture.endIndex = 255;//when it triggers, we freeze startIndex and start counting up here + if(_dataCapture.captureStick == ASTICK) { + x0 = _raw.axUnfiltered; + y0 = _raw.ayUnfiltered; + _dataCapture.a1[_dataCapture.startIndex] = _btn.Ax; + _dataCapture.a2[_dataCapture.startIndex] = _btn.Ay; + _dataCapture.a1Unfilt[_dataCapture.startIndex] = (uint8_t) (_raw.axUnfiltered+_floatOrigin); + _dataCapture.a2Unfilt[_dataCapture.startIndex] = (uint8_t) (_raw.ayUnfiltered+_floatOrigin); + } else { + x0 = _raw.cxUnfiltered; + y0 = _raw.cyUnfiltered; + _dataCapture.a1[_dataCapture.startIndex] = _btn.Cx; + _dataCapture.a2[_dataCapture.startIndex] = _btn.Cy; + _dataCapture.a1Unfilt[_dataCapture.startIndex] = (uint8_t) (_raw.cxUnfiltered+_floatOrigin); + _dataCapture.a2Unfilt[_dataCapture.startIndex] = (uint8_t) (_raw.cyUnfiltered+_floatOrigin); + } + // syxba lrz + _dataCapture.abxyszrl[_dataCapture.startIndex] = (_btn.arr[0] & 0b00011111) | ((_btn.arr[1] & 0b01110000) << 1); + } else { + if(_dataCapture.endIndex == 255) { + //not triggered yet + //increment startIndex + _dataCapture.startIndex = (_dataCapture.startIndex+1) % 100; + //record + if(_dataCapture.captureStick == ASTICK) { + _dataCapture.a1[_dataCapture.startIndex] = _btn.Ax; + _dataCapture.a2[_dataCapture.startIndex] = _btn.Ay; + _dataCapture.a1Unfilt[_dataCapture.startIndex] = (uint8_t) (_raw.axUnfiltered+_floatOrigin); + _dataCapture.a2Unfilt[_dataCapture.startIndex] = (uint8_t) (_raw.ayUnfiltered+_floatOrigin); + //if it's not triggered, do nothing further + //if it's triggered, set endIndex to startIndex+1 + int diffX = abs(int(_raw.axUnfiltered) - x0); + int diffY = abs(int(_raw.ayUnfiltered) - y0); + if(diffX > _dataCapture.stickThresh || diffY > _dataCapture.stickThresh) { + _dataCapture.endIndex = (_dataCapture.startIndex+1) % 100; + } + } else { + _dataCapture.a1[_dataCapture.startIndex] = _btn.Cx; + _dataCapture.a2[_dataCapture.startIndex] = _btn.Cy; + _dataCapture.a1Unfilt[_dataCapture.startIndex] = (uint8_t) (_raw.cxUnfiltered+_floatOrigin); + _dataCapture.a2Unfilt[_dataCapture.startIndex] = (uint8_t) (_raw.cyUnfiltered+_floatOrigin); + //if it's not triggered, do nothing further + //if it's triggered, set endIndex to startIndex+1 + int diffX = abs(int(_raw.cxUnfiltered) - x0); + int diffY = abs(int(_raw.cyUnfiltered) - y0); + if(diffX > _dataCapture.stickThresh || diffY > _dataCapture.stickThresh) { + _dataCapture.endIndex = (_dataCapture.startIndex+1) % 100; + } + } + // syxba lrz + _dataCapture.abxyszrl[_dataCapture.startIndex] = (_btn.arr[0] & 0b00011111) | ((_btn.arr[1] & 0b01110000) << 1); + } else if(_dataCapture.endIndex != _dataCapture.startIndex) { + //triggered + //record + if(_dataCapture.captureStick == ASTICK) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Ax; + _dataCapture.a2[_dataCapture.endIndex] = _btn.Ay; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.axUnfiltered+_floatOrigin); + _dataCapture.a2Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.ayUnfiltered+_floatOrigin); + } else { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Cx; + _dataCapture.a2[_dataCapture.endIndex] = _btn.Cy; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.cxUnfiltered+_floatOrigin); + _dataCapture.a2Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.cyUnfiltered+_floatOrigin); + } + // syxba lrz + _dataCapture.abxyszrl[_dataCapture.endIndex] = (_btn.arr[0] & 0b00011111) | ((_btn.arr[1] & 0b01110000) << 1); + //increment endIndex + _dataCapture.endIndex = (_dataCapture.endIndex+1) % 100; + } else { + //done + _dataCapture.done = true; + _pleaseCommit = 255;//end capture and display + } + } + break; + case CM_STICK_RISE: + //200 points of single-axis data + //based on the raw unfiltered values hitting >= 23 + //it should record for 150 ms after detection (saving 50 from before detection) + + //prep + //expect data to be prepped already + //begin = false + //triggered = false + //done = false + //startIndex = 0 + //endIndex = 0 + + //record data continuously if not done + //actually, if it's done, it should never reach this + if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == XAXIS) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Ax; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.axUnfiltered+_floatOrigin); + } else if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == YAXIS) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Ay; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.ayUnfiltered+_floatOrigin); + } else if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == XAXIS) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Cx; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.cxUnfiltered+_floatOrigin); + } else {//if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == YAXIS) + _dataCapture.a1[_dataCapture.endIndex] = _btn.Cy; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.cyUnfiltered+_floatOrigin); + } + + //check for initial waiting state + //in this case, we want the stick's raw value to be out of the deadzone + if(!_dataCapture.begin && !_dataCapture.done) { + if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == XAXIS) { + if(fabs(_raw.axUnfiltered) >= 23) { + _dataCapture.begin = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } else if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == YAXIS) { + if(fabs(_raw.ayUnfiltered) >= 23) { + _dataCapture.begin = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } else if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == XAXIS) { + if(fabs(_raw.cxUnfiltered) >= 23) { + _dataCapture.begin = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } else {//if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == YAXIS) + if(fabs(_raw.cyUnfiltered) >= 23) { + _dataCapture.begin = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } + } + + + //stop if done + if(_dataCapture.begin && _dataCapture.startIndex == _dataCapture.endIndex) { + //calculate the dashback chance + int counter = 0; + for(int i = 0; i < 200; i++) { + if(fabs(_dataCapture.a1[(i+_dataCapture.startIndex+1) % 200]-_intOrigin) >= 23) { + if(fabs(_dataCapture.a1[(i+_dataCapture.startIndex+1) % 200]-_intOrigin) >= 64) { + break; + } + counter++; + } + } + _dataCapture.percents[0] = fmax(0, (1 - (counter/16.666667f))*100); + + //clean up + _dataCapture.done = true; + _pleaseCommit = 255;//end capture and display + } + + //advance to next index to record + _dataCapture.endIndex = (_dataCapture.endIndex+1) % 200; + break; + case CM_STICK_FALL: + //single-axis + //based on the raw unfiltered values falling from >70 to 0 in <30 ms + //it should record for 150 ms after detection (saving 50 from before detection) + + //prep + //expect data to be prepped already + //begin = false + //triggered = false + //done = false + //startIndex = 0 + //endIndex = 0 + + //record data continuously if not done + //actually, if it's done, it should never reach this + if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == XAXIS) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Ax; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.axUnfiltered+_floatOrigin); + } else if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == YAXIS) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Ay; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.ayUnfiltered+_floatOrigin); + } else if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == XAXIS) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Cx; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.cxUnfiltered+_floatOrigin); + } else {//if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == YAXIS) + _dataCapture.a1[_dataCapture.endIndex] = _btn.Cy; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.cyUnfiltered+_floatOrigin); + } + + //check for initial waiting state + //in this case, we want the stick's raw value to be >=80 + if(!_dataCapture.begin && !_dataCapture.triggered && !_dataCapture.done) { + if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == XAXIS) { + if(fabs(_raw.axUnfiltered) >= 80) { + _dataCapture.begin = true; + } + } else if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == YAXIS) { + if(fabs(_raw.ayUnfiltered) >= 80) { + _dataCapture.begin = true; + } + } else if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == XAXIS) { + if(fabs(_raw.cxUnfiltered) >= 80) { + _dataCapture.begin = true; + } + } else {//if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == YAXIS) + if(fabs(_raw.cyUnfiltered) >= 80) { + _dataCapture.begin = true; + } + } + } + + //check for secondary trigger state + //if the trigger has now dropped to less than 23 (in the deadzone) + if(_dataCapture.begin && !_dataCapture.triggered && !_dataCapture.done) { + if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == XAXIS) { + if(fabs(_raw.axUnfiltered) < 23) { + _dataCapture.triggered = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } else if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == YAXIS) { + if(fabs(_raw.ayUnfiltered) < 23) { + _dataCapture.triggered = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } else if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == XAXIS) { + if(fabs(_raw.cxUnfiltered) < 23) { + _dataCapture.triggered = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } else {//if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == YAXIS) + if(fabs(_raw.cyUnfiltered) < 23) { + _dataCapture.triggered = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } + } + + //stop if done + if(_dataCapture.triggered && _dataCapture.startIndex == _dataCapture.endIndex) { + //calculate the percent chance the last input was + + _dataCapture.percents[0] = 0.0f; + //try each poll offset + for(int offset = 0; offset < 17; offset++) { + bool positive = false; + //poll at roughly 60 hz + for(int i = offset; i < 200; i += 17) { + const int index = (i + _dataCapture.startIndex+1) % 200; + const int data = _dataCapture.a1[index] - _intOrigin; + //see if the data would exceed the deadzone in either direction + //the last excursion out counts as having turned that way + if(data >= 23) { + positive = true; + } else if(data <= -23) { + positive = false; + } + } + if(positive) { + _dataCapture.percents[0] += 100/17.0f; + } + } + + //clean up + _dataCapture.done = true; + _pleaseCommit = 255;//end capture and display + } + + //advance to next index to record + _dataCapture.endIndex = (_dataCapture.endIndex+1) % 200; + break; + case CM_STICK_PIVOT: + //single-axis + //Begins waiting when you input >=64 in one direction. + //Starts recording when it detects >=64 in the other direction. + //it should record for 150 ms after detection (saving 50 from before detection) + + //prep + //expect data to be prepped already + //begin = false + //triggered = false + //done = false + //startIndex = 0 + //endIndex = 0 + static bool negativePivot = false; + + //record data continuously if not done + //actually, if it's done, it should never reach this + if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == XAXIS) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Ax; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.axUnfiltered+_floatOrigin); + } else if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == YAXIS) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Ay; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.ayUnfiltered+_floatOrigin); + } else if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == XAXIS) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Cx; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.cxUnfiltered+_floatOrigin); + } else {//if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == YAXIS) + _dataCapture.a1[_dataCapture.endIndex] = _btn.Cy; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = (uint8_t) (_raw.cyUnfiltered+_floatOrigin); + } + + //check for initial waiting state + //in this case, we want the stick's raw value to be >=80 (dash threshold) + //also record which side + if(!_dataCapture.begin && !_dataCapture.triggered && !_dataCapture.done) { + if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == XAXIS) { + if(_btn.Ax - _intOrigin >= 80) { + _dataCapture.begin = true; + negativePivot = true; + } else if(_btn.Ax - _intOrigin <= -80) { + _dataCapture.begin = true; + negativePivot = false; + } + } else if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == YAXIS) { + if(_btn.Ay - _intOrigin >= 80) { + _dataCapture.begin = true; + negativePivot = true; + } else if(_btn.Ay - _intOrigin <= -80) { + _dataCapture.begin = true; + negativePivot = false; + } + } else if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == XAXIS) { + if(_btn.Cx - _intOrigin >= 80) { + _dataCapture.begin = true; + negativePivot = true; + } else if(_btn.Cx - _intOrigin <= -80) { + _dataCapture.begin = true; + negativePivot = false; + } + } else {//if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == YAXIS) + if(_btn.Cy - _intOrigin >= 80) { + _dataCapture.begin = true; + negativePivot = true; + } else if(_btn.Cy - _intOrigin <= -80) { + _dataCapture.begin = true; + negativePivot = false; + } + } + } + + //check for secondary trigger state + //if the trigger has now crossed to the opposite dash threshold + if(_dataCapture.begin && !_dataCapture.triggered && !_dataCapture.done) { + if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == XAXIS) { + if((_btn.Ax - _intOrigin) * (negativePivot ? -1 : 1) >= 80) { + _dataCapture.triggered = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } else if(_dataCapture.captureStick == ASTICK && _dataCapture.whichAxis == YAXIS) { + if((_btn.Ay - _intOrigin) * (negativePivot ? -1 : 1) >= 80) { + _dataCapture.triggered = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } else if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == XAXIS) { + if((_btn.Cx - _intOrigin) * (negativePivot ? -1 : 1) >= 80) { + _dataCapture.triggered = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } else {//if(_dataCapture.captureStick == CSTICK && _dataCapture.whichAxis == YAXIS) + if((_btn.Cy - _intOrigin) * (negativePivot ? -1 : 1) >= 80) { + _dataCapture.triggered = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } + } + + //stop if done + if(_dataCapture.triggered && _dataCapture.startIndex == _dataCapture.endIndex) { + //calculate pivot success rate + int counter = 0; + for(int i = 0; i < 200; i++) { + const int index = (i + _dataCapture.startIndex+1) % 200; + const int data = (_dataCapture.a1[index] - _intOrigin) * (negativePivot ? -1 : 1); + if(data > 80) { + counter++; + } + if(counter > 0 && data < 80) { + break; + } + } + const float frames = counter/16.6666666667f; + //no turn + _dataCapture.percents[0] = 100*fmax(0, 1-frames); + //empty pivot + _dataCapture.percents[1] = 100*fmax(0, fmin(2-frames, frames)); + //turn + _dataCapture.percents[2] = 100*fmax(0, fmin(1, frames-1)); + + //clean up + _dataCapture.done = true; + _pleaseCommit = 255;//end capture and display + } + + //advance to next index to record + _dataCapture.endIndex = (_dataCapture.endIndex+1) % 200; + break; + case CM_TRIG: + //single trigger + //based on the filtered values >=43, or digital being pressed + //it should record for 150 ms after detection (saving 50 from before detection) + + //prep + //expect data to be prepped already + //begin = false + //done = false + //startIndex = 0 + //endIndex = 0 + + //record data continuously if not done + //actually, if it's done, it should never reach this + if(_dataCapture.captureStick == ASTICK) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.La; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = _hardware.La; + _dataCapture.abxyszrl[_dataCapture.endIndex] = _btn.L; + } else {//if(_dataCapture.captureStick == CSTICK) { + _dataCapture.a1[_dataCapture.endIndex] = _btn.Ra; + _dataCapture.a1Unfilt[_dataCapture.endIndex] = _hardware.Ra; + _dataCapture.abxyszrl[_dataCapture.endIndex] = _btn.R; + } + + //check for trigger condition + if(!_dataCapture.begin && !_dataCapture.done) { + if(_dataCapture.captureStick == ASTICK) { + if(_btn.La >= 43 || _btn.L) { + _dataCapture.begin = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } else { //if(_dataCapture.captureStick == CSTICK) + if(_btn.Ra >= 43 || _btn.R) { + _dataCapture.begin = true; + _dataCapture.startIndex = (_dataCapture.endIndex+150) % 200; + } + } + } + + //stop if done + if(_dataCapture.begin && _dataCapture.startIndex == _dataCapture.endIndex) { + //calculate pivot success rate + int counter = 0; + for(int i = 0; i < 200; i++) { + const int index = (i + _dataCapture.startIndex+1) % 200; + const int analog = _dataCapture.a1[index]; + const int digital = _dataCapture.abxyszrl[index]; + if(digital) { + break;//if digital is active on the same ms as analog or before, we're good + } + if(analog >= 43) { + counter++; + } + } + const float frames = counter/16.6666666667f; + //digital only powershield + _dataCapture.percents[0] = 100*fmax(0, 1-frames); + //adt powershield + _dataCapture.percents[1] = 100*fmax(0, fmin(2-frames, frames)); + //no powershield + _dataCapture.percents[2] = 100*fmax(0, fmin(1, frames-1)); + _dataCapture.done = true; + _pleaseCommit = 255;//end capture and display + } + + //advance to next index to record + _dataCapture.endIndex = (_dataCapture.endIndex+1) % 200; + break; + case CM_JUMP: + //not really needed? + //button timing (CM_PRESS) takes care of it really + break; + case CM_PRESS: + if(!_dataCapture.begin && !_dataCapture.done) { + // syxba lrz + if((_btn.arr[0] & 0b00001111) || (_btn.arr[1] & 0b01110000)) { + _dataCapture.begin = true; + } + //stick thresholds + if(abs(int(_btn.Ax)-127) >= _dataCapture.stickThresh || + abs(int(_btn.Ay)-127) >= _dataCapture.stickThresh || + abs(int(_btn.Cx)-127) >= _dataCapture.stickThresh || + abs(int(_btn.Cy)-127) >= _dataCapture.stickThresh || + abs(int(_btn.Ra)) >= _dataCapture.triggerThresh || + abs(int(_btn.La)) >= _dataCapture.triggerThresh) { + _dataCapture.begin = true; + } + } + if(_dataCapture.begin && !_dataCapture.done) { + // syxba lrz + _dataCapture.abxyszrl[_dataCapture.endIndex] = (_btn.arr[0] & 0b00001111) | ((_btn.arr[1] & 0b01110000) << 1); + _dataCapture.axaycxcyrl[_dataCapture.endIndex] = + (0b0000'0001 * (abs(int(_btn.Ax)-127) >= _dataCapture.stickThresh)) | + (0b0000'0010 * (abs(int(_btn.Ay)-127) >= _dataCapture.stickThresh)) | + (0b0000'0100 * (abs(int(_btn.Cx)-127) >= _dataCapture.stickThresh)) | + (0b0000'1000 * (abs(int(_btn.Cy)-127) >= _dataCapture.stickThresh)) | + (0b0001'0000 * (abs(int(_btn.Ra)) >= _dataCapture.triggerThresh)) | + (0b0010'0000 * (abs(int(_btn.La)) >= _dataCapture.triggerThresh)); + _dataCapture.endIndex++; + if(_dataCapture.endIndex >= 200) { + _dataCapture.done = true; + _pleaseCommit = 255;//end capture and display + } + } + break; + default: + //nothing + break; + } } } //gpio_put(_pinSpare0, !gpio_get_out_level(_pinSpare0)); //pwm_set_gpio_level(_pinLED, 255*gpio_get_out_level(_pinSpare0)); - //limit speed if video is running - if(_vsyncSensors) { - while(!_sync) { - tight_loop_contents(); - } - _sync = false; - } - - static bool running = false; //gpio_put(_pinSpare0, !gpio_get_out_level(_pinSpare0)); @@ -148,7 +685,7 @@ void second_core() { }else{//just show desired stick position displayNotch(_currentCalStep, true, _notchAngleDefaults, _btn); } - readSticks(true,false, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, _currentCalStep, _vsyncSensors); + readSticks(true,false, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, _currentCalStep); } else{//WHICHSTICK == CSTICK if(_currentCalStep >= _noOfCalibrationPoints){//adjust notch angles @@ -168,12 +705,12 @@ void second_core() { }else{//just show desired stick position displayNotch(_currentCalStep, false, _notchAngleDefaults, _btn); } - readSticks(false,true, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, _currentCalStep, _vsyncSensors); + readSticks(false,true, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, _currentCalStep); } } else if(running){ //if not calibrating read the sticks normally - readSticks(true,true, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, _currentCalStep, _vsyncSensors); + readSticks(true,true, _btn, _pinList, _raw, _hardware, _controls, _normGains, _aStickParams, _cStickParams, _dT, _currentCalStep); } //read the controller's buttons @@ -254,6 +791,18 @@ int main() { _raw.cxUnfiltered = 0; _raw.cyUnfiltered = 0; + _dataCapture.mode = CM_NULL; + _dataCapture.triggerStick = ASTICK; + _dataCapture.captureStick = ASTICK; + _dataCapture.begin = false; + _dataCapture.done = true; + _dataCapture.delay = 0; + _dataCapture.stickThresh = 23; + _dataCapture.triggerThresh = 49; + _dataCapture.startIndex = 0; + _dataCapture.endIndex = 0; + _dataCapture.viewIndex = 0; + //measure the trigger values for trigger tricking initializeButtons(_pinList, _btn, _controls.lTrigInitial, _controls.rTrigInitial); @@ -275,14 +824,12 @@ int main() { //Run comms unless Z is held while plugging in if(_hardware.Z) { - //Don't - //_vsyncSensors = true; #ifdef BUILD_DEV const int version = -SW_VERSION; #else //BUILD_DEV const int version = SW_VERSION; #endif //BUILD_DEV - videoOut(_pinDac0, _btn, _hardware, _raw, _controls, _aStickParams, _cStickParams, _sync, _pleaseCommit, _currentCalStep, version); + videoOut(_pinDac0, _btn, _hardware, _raw, _controls, _aStickParams, _cStickParams, _dataCapture, _sync, _pleaseCommit, _currentCalStep, version); } else { enterMode(_pinTX, _pinRumble, diff --git a/PhobGCC/rp2040/src/navigateMenu.cpp b/PhobGCC/rp2040/src/navigateMenu.cpp index fdb5df3..02a1580 100644 --- a/PhobGCC/rp2040/src/navigateMenu.cpp +++ b/PhobGCC/rp2040/src/navigateMenu.cpp @@ -1,7 +1,9 @@ #include #include "pico/platform.h" +#include "hardware/timer.h" #include "cvideo.h" #include "menu.h" +#include "menuStrings.h" #include "storage/pages/storage.h" #define APRESS 0b0000'0000'0000'0001 @@ -24,9 +26,10 @@ void navigateMenu(unsigned char bitmap[], bool &changeMade, const int currentCalStep, volatile uint8_t &pleaseCommit, + const Buttons &btn, uint16_t presses, - const uint8_t increment, - ControlConfig &controls); + ControlConfig &controls, + DataCapture &capture); void __time_critical_func(handleMenuButtons)(unsigned char bitmap[], unsigned int &menu, @@ -35,16 +38,18 @@ void __time_critical_func(handleMenuButtons)(unsigned char bitmap[], bool &changeMade, const int currentCalStep, volatile uint8_t &pleaseCommit, + const Buttons &btn, const Buttons &hardware, - ControlConfig &controls) { + ControlConfig &controls, + DataCapture &capture) { uint16_t presses = 0; - uint8_t changeIncrement = 1; //b button needs to accumulate before acting static uint8_t backAccumulator = 0; //a and dpad are locked out after acting - const uint8_t buttonLockout = 10;// 1/6 of a second of ignoring button bounce + const uint8_t buttonLockout = 6;// 1/10 of a second of ignoring button bounce const uint8_t dpadLockout = 15;// 1/4 of a second of ignoring button bounce + const uint8_t dpadLockoutShort = 3;// 1/20 of a second of ignoring button bounce static uint8_t aLockout = 0; static uint8_t zLockout = 0; static uint8_t sLockout = 0; @@ -75,6 +80,8 @@ void __time_critical_func(handleMenuButtons)(unsigned char bitmap[], static uint8_t duCounter = 0;//for controls that go faster when you hold them static uint8_t ddCounter = 0;//for controls that go faster when you hold them + static uint8_t dlCounter = 0;//for controls that go faster when you hold them + static uint8_t drCounter = 0;//for controls that go faster when you hold them if(hardware.B) { backAccumulator++; @@ -85,6 +92,11 @@ void __time_critical_func(handleMenuButtons)(unsigned char bitmap[], backAccumulator = 0; aLockout = 0;//make A available immediately after backing out presses = presses | BPRESS; + capture.autoRepeat = false;//cancel auto repeating if you back out + capture.begin = false; + capture.triggered = false; + capture.done = true; + pleaseCommit = 0; } } else { if(backAccumulator > 0) { @@ -104,50 +116,63 @@ void __time_critical_func(handleMenuButtons)(unsigned char bitmap[], lrLockout = buttonLockout; } else if(hardware.Dl && dlLockout == 0) { presses = presses | DLPRESS; - dlLockout = dpadLockout; + //Go faster after 10 steps + if(dlCounter <= 10) { + dlCounter++; + } + drCounter = 0; + dlLockout = dlCounter > 10 ? dpadLockoutShort : dpadLockout; drLockout = 0; //also lock out perpendicular directions to prevent misinputs ddLockout = dpadLockout; duLockout = dpadLockout; - //clear the repetition counters + //clear the perpendicular repetition counters duCounter = 0; ddCounter = 0; } else if(hardware.Dr && drLockout == 0) { presses = presses | DRPRESS; - drLockout = dpadLockout; + //Go faster after 10 steps + if(drCounter <= 10) { + drCounter++; + } + drLockout = drCounter > 10 ? dpadLockoutShort : dpadLockout; dlLockout = 0; //also lock out perpendicular directions to prevent misinputs ddLockout = dpadLockout; duLockout = dpadLockout; - //clear the repetition counters + //clear the perpendicular repetition counters duCounter = 0; ddCounter = 0; } else if(hardware.Du && duLockout == 0) { presses = presses | DUPRESS; - duLockout = dpadLockout; - ddLockout = 0; - //also lock out perpendicular directions to prevent misinputs - dlLockout = dpadLockout; - drLockout = dpadLockout; - //Go by 10 after 10 steps + //Go faster after 10 steps if(duCounter <= 10) { duCounter++; } ddCounter = 0; - changeIncrement = duCounter > 10 ? 10 : 1; - } else if(hardware.Dd && ddLockout == 0) { - presses = presses | DDPRESS; - ddLockout = dpadLockout; - duLockout = 0; + duLockout = duCounter > 10 ? dpadLockoutShort : dpadLockout; + ddLockout = 0; //also lock out perpendicular directions to prevent misinputs dlLockout = dpadLockout; drLockout = dpadLockout; - //Go by 10 after 10 steps + //clear the perpendicular repetition counters + dlCounter = 0; + drCounter = 0; + } else if(hardware.Dd && ddLockout == 0) { + presses = presses | DDPRESS; + //Go faster after 10 steps if(ddCounter <= 10) { ddCounter++; } duCounter = 0; - changeIncrement = ddCounter > 10 ? 10 : 1; + ddLockout = ddCounter > 10 ? dpadLockoutShort : dpadLockout; + duLockout = 0; + //also lock out perpendicular directions to prevent misinputs + dlLockout = dpadLockout; + drLockout = dpadLockout; + //clear the perpendicular repetition counters + dlCounter = 0; + drCounter = 0; } else { //clear the repetition counters if(duLockout == 0) { @@ -156,6 +181,12 @@ void __time_critical_func(handleMenuButtons)(unsigned char bitmap[], if(ddLockout == 0) { ddCounter = 0; } + if(dlLockout == 0) { + dlCounter = 0; + } + if(drLockout == 0) { + drCounter = 0; + } } //Other presses that don't get locked out, not for navigation if(hardware.X) { @@ -165,6 +196,19 @@ void __time_critical_func(handleMenuButtons)(unsigned char bitmap[], presses = presses | YPRESS; } } + + //handle autorepeat + if(capture.autoRepeat && capture.done) { + const uint8_t repeatTimerDuration = 15; + static uint8_t repeatTimer = repeatTimerDuration; + if(repeatTimer == 0) { + presses = SPRESS;//ignore other things, just make it press start + repeatTimer = repeatTimerDuration; + } else { + repeatTimer--; + } + } + //handle actual navigation and settings changes if(presses) { navigateMenu(bitmap, @@ -174,9 +218,10 @@ void __time_critical_func(handleMenuButtons)(unsigned char bitmap[], changeMade, currentCalStep, pleaseCommit, + btn, presses, - changeIncrement, - controls); + controls, + capture); } //handle always-redrawing screens since we don't always call navigation //redraw = 2 asks for a fast-path @@ -200,9 +245,10 @@ void navigateMenu(unsigned char bitmap[], bool &changeMade, const int currentCalStep, volatile uint8_t &pleaseCommit, + const Buttons &btn, uint16_t presses, - const uint8_t increment, - ControlConfig &controls) { + ControlConfig &controls, + DataCapture &capture) { if(MenuIndex[menu][1] == 0) { if(presses & APRESS) { presses = 0; @@ -246,6 +292,7 @@ void navigateMenu(unsigned char bitmap[], //Big switch case for controls for all the bottom level items static int tempInt1 = 0; static int tempInt2 = 0; + static int tempInt3 = 0; switch(menu) { case MENU_ASTICKCAL: if(presses & (APRESS | LRPRESS)) { @@ -480,6 +527,7 @@ void navigateMenu(unsigned char bitmap[], pleaseCommit = 1;//ask the other thread to commit settings to flash } return; + /* case MENU_COFFSET: if(!changeMade) { tempInt1 = controls.cXOffset; @@ -493,17 +541,17 @@ void navigateMenu(unsigned char bitmap[], redraw = 1; } else if(presses & DUPRESS) { if(itemIndex == 0) { - controls.cXOffset = fmin(controls.cMax, controls.cXOffset+increment); + controls.cXOffset = fmin(controls.cMax, controls.cXOffset+1); } else {//itemIndex == 1 - controls.cYOffset = fmin(controls.cMax, controls.cYOffset+increment); + controls.cYOffset = fmin(controls.cMax, controls.cYOffset+1); } changeMade = (controls.cXOffset != tempInt1) || (controls.cYOffset != tempInt2); redraw = 1; } else if(presses & DDPRESS) { if(itemIndex == 0) { - controls.cXOffset = fmax(controls.cMin, controls.cXOffset-increment); + controls.cXOffset = fmax(controls.cMin, controls.cXOffset-1); } else {//itemIndex == 1 - controls.cYOffset = fmax(controls.cMin, controls.cYOffset-increment); + controls.cYOffset = fmax(controls.cMin, controls.cYOffset-1); } changeMade = (controls.cXOffset != tempInt1) || (controls.cYOffset != tempInt2); redraw = 1; @@ -517,6 +565,81 @@ void navigateMenu(unsigned char bitmap[], pleaseCommit = 1;//ask the other thread to commit settings to flash } return; + */ + case MENU_CARDINALS: + if(!changeMade) { + tempInt1 = controls.astickCardinalSnapping; + tempInt2 = controls.cstickCardinalSnapping; + } + if(presses & DLPRESS) { + itemIndex = 0; + redraw = 1; + } else if(presses & DRPRESS) { + itemIndex = 1; + redraw = 1; + } else if(presses & DUPRESS) { + if(itemIndex == 0) { + controls.astickCardinalSnapping = fmin(controls.cardinalSnappingMax, controls.astickCardinalSnapping+1); + } else {//itemIndex == 1 + controls.cstickCardinalSnapping = fmin(controls.cardinalSnappingMax, controls.cstickCardinalSnapping+1); + } + changeMade = (controls.astickCardinalSnapping != tempInt1) || (controls.cstickCardinalSnapping != tempInt2); + redraw = 1; + } else if(presses & DDPRESS) { + if(itemIndex == 0) { + controls.astickCardinalSnapping = fmax(controls.cardinalSnappingMin, controls.astickCardinalSnapping-1); + } else {//itemIndex == 1 + controls.cstickCardinalSnapping = fmax(controls.cardinalSnappingMin, controls.cstickCardinalSnapping-1); + } + changeMade = (controls.astickCardinalSnapping != tempInt1) || (controls.cstickCardinalSnapping != tempInt2); + redraw = 1; + } else if((presses & BSAVE) && changeMade) { + setCardinalSnappingSetting(controls.astickCardinalSnapping, ASTICK); + setCardinalSnappingSetting(controls.cstickCardinalSnapping, CSTICK); + tempInt1 = controls.astickCardinalSnapping; + tempInt2 = controls.cstickCardinalSnapping; + changeMade = false; + redraw = 1; + pleaseCommit = 1;//ask the other thread to commit settings to flash + } + return; + case MENU_RADIUS: + if(!changeMade) { + tempInt1 = controls.astickAnalogScaler; + tempInt2 = controls.cstickAnalogScaler; + } + if(presses & DLPRESS) { + itemIndex = 0; + redraw = 1; + } else if(presses & DRPRESS) { + itemIndex = 1; + redraw = 1; + } else if(presses & DUPRESS) { + if(itemIndex == 0) { + controls.astickAnalogScaler = fmin(controls.analogScalerMax, controls.astickAnalogScaler+1); + } else {//itemIndex == 1 + controls.cstickAnalogScaler = fmin(controls.analogScalerMax, controls.cstickAnalogScaler+1); + } + changeMade = (controls.astickAnalogScaler != tempInt1) || (controls.cstickAnalogScaler != tempInt2); + redraw = 1; + } else if(presses & DDPRESS) { + if(itemIndex == 0) { + controls.astickAnalogScaler = fmax(controls.analogScalerMin, controls.astickAnalogScaler-1); + } else {//itemIndex == 1 + controls.cstickAnalogScaler = fmax(controls.analogScalerMin, controls.cstickAnalogScaler-1); + } + changeMade = (controls.astickAnalogScaler != tempInt1) || (controls.cstickAnalogScaler != tempInt2); + redraw = 1; + } else if((presses & BSAVE) && changeMade) { + setAnalogScalerSetting(controls.astickAnalogScaler, ASTICK); + setAnalogScalerSetting(controls.cstickAnalogScaler, CSTICK); + tempInt1 = controls.astickAnalogScaler; + tempInt2 = controls.cstickAnalogScaler; + changeMade = false; + redraw = 1; + pleaseCommit = 1;//ask the other thread to commit settings to flash + } + return; case MENU_REMAP: if(!changeMade) { tempInt1 = controls.jumpConfig; @@ -549,6 +672,8 @@ void navigateMenu(unsigned char bitmap[], controls.rumble = fmax(controls.rumbleMin, controls.rumble-1); changeMade = controls.rumble != tempInt1; redraw = 1; + } else if(presses & ZPRESS) { + pleaseCommit = 8;//request rumble } else if((presses & BSAVE) && changeMade) { setRumbleSetting(controls.rumble); tempInt1 = controls.rumble; @@ -572,7 +697,7 @@ void navigateMenu(unsigned char bitmap[], if(itemIndex == 0) { controls.lConfig = fmin(controls.triggerConfigMax, controls.lConfig+1); } else {//itemIndex == 1 - controls.lTriggerOffset = fmin(controls.triggerMax, controls.lTriggerOffset+increment); + controls.lTriggerOffset = fmin(controls.triggerMax, controls.lTriggerOffset+1); } changeMade = (controls.lConfig != tempInt1) || (controls.lTriggerOffset != tempInt2); redraw = 1; @@ -580,7 +705,7 @@ void navigateMenu(unsigned char bitmap[], if(itemIndex == 0) { controls.lConfig = fmax(controls.triggerConfigMin, controls.lConfig-1); } else {//itemIndex == 1 - controls.lTriggerOffset = fmax(controls.triggerMin, controls.lTriggerOffset-increment); + controls.lTriggerOffset = fmax(controls.triggerMin, controls.lTriggerOffset-1); } changeMade = (controls.lConfig != tempInt1) || (controls.lTriggerOffset != tempInt2); redraw = 1; @@ -609,7 +734,7 @@ void navigateMenu(unsigned char bitmap[], if(itemIndex == 0) { controls.rConfig = fmin(controls.triggerConfigMax, controls.rConfig+1); } else {//itemIndex == 1 - controls.rTriggerOffset = fmin(controls.triggerMax, controls.rTriggerOffset+increment); + controls.rTriggerOffset = fmin(controls.triggerMax, controls.rTriggerOffset+1); } changeMade = (controls.rConfig != tempInt1) || (controls.rTriggerOffset != tempInt2); redraw = 1; @@ -617,7 +742,7 @@ void navigateMenu(unsigned char bitmap[], if(itemIndex == 0) { controls.rConfig = fmax(controls.triggerConfigMin, controls.rConfig-1); } else {//itemIndex == 1 - controls.rTriggerOffset = fmax(controls.triggerMin, controls.rTriggerOffset-increment); + controls.rTriggerOffset = fmax(controls.triggerMin, controls.rTriggerOffset-1); } changeMade = (controls.rConfig != tempInt1) || (controls.rTriggerOffset != tempInt2); redraw = 1; @@ -631,6 +756,26 @@ void navigateMenu(unsigned char bitmap[], pleaseCommit = 1;//ask the other thread to commit settings to flash } return; + case MENU_TOURNEY: + if(!changeMade) { + tempInt1 = controls.tournamentToggle; + } + if(presses & DUPRESS) { + controls.tournamentToggle = fmin(controls.tournamentToggleMax, controls.tournamentToggle+1); + changeMade = controls.tournamentToggle != tempInt1; + redraw = 1; + } else if(presses & DDPRESS) { + controls.tournamentToggle = fmax(controls.tournamentToggleMin, controls.tournamentToggle-1); + changeMade = controls.tournamentToggle != tempInt1; + redraw = 1; + } else if((presses & BSAVE) && changeMade) { + setTournamentToggleSetting(controls.tournamentToggle); + tempInt1 = controls.tournamentToggle; + changeMade = false; + redraw = 1; + pleaseCommit = 1;//ask the other thread to commit settings to flash + } + return; case MENU_RESET: if(presses & DUPRESS) { itemIndex = 0; @@ -657,6 +802,339 @@ void navigateMenu(unsigned char bitmap[], pleaseCommit = 3; } } + return; + case MENU_XYSCOPE://stickmap plot + if(!changeMade) { + capture.stickThresh = 10;//fixed threshold for triggering + tempInt1 = 0;//which stickmap to display + capture.stickmap = 0; + tempInt2 = 0;//left stick 0, c-stick 1 + capture.captureStick = ASTICK; + tempInt3 = 0;//0 through 99 + capture.viewIndex = 0; + changeMade = true; + } + if(presses & DUPRESS) { + if(itemIndex != 0) { + itemIndex--; + redraw = 1; + } + } else if(presses & DDPRESS) { + if(itemIndex < 2) { + itemIndex++; + redraw = 1; + } + } else if(presses & DLPRESS) { + if(itemIndex == 0) { + capture.stickmap = (capture.stickmap == 0) ? 0 : capture.stickmap-1; + } else if(itemIndex == 1) { + capture.captureStick = ASTICK; + } else { + capture.viewIndex = (capture.viewIndex == 0) ? 0 : capture.viewIndex-1; + } + redraw = 1; + } else if(presses & DRPRESS) { + if(itemIndex == 0) { + capture.stickmap = fmin(6, capture.stickmap+1); + } else if(itemIndex == 1) { + capture.captureStick = CSTICK; + } else { + capture.viewIndex = fmin(99, capture.viewIndex+1); + } + redraw = 1; + } else if(presses & SPRESS && capture.done == true) { + //tell the user it's recording + drawString(bitmap, 280, 250, 15, xyscope0); + //set up recording + capture.begin = false; + capture.done = false; + capture.mode = CM_STICK_RISE2; + //then trigger the recording + pleaseCommit = 9; + } + return; + case MENU_TIMESCOPE://value vs time plot + if(!changeMade) { + capture.captureStick = ASTICK;//if triggers, then ASTICK is L, CSTICK is R + capture.whichAxis = XAXIS; + tempInt1 = 0;//capture stick + axis together, or triggers + capture.mode = CM_STICK_FALL;//snapback (default) + tempInt2 = 0;//snapback/dashback/pivot (only available for sticks) + capture.viewIndex = 0; + capture.autoRepeat = 1;//trigger automatically (except when itemIndex == 2) + //clear data + for(int i = 0; i<99; i++) { + capture.a1[i] = (uint8_t) 0; + capture.a2[i] = (uint8_t) 0; + capture.a1Unfilt[i] = (uint8_t) 0; + capture.a2Unfilt[i] = (uint8_t) 0; + capture.abxyszrl[i] = (uint8_t) 0; + capture.abxyszrl[i+100] = (uint8_t) 0; + } + changeMade = true; + } + if(presses & DLPRESS) { + if(itemIndex != 0) { + itemIndex--; + capture.autoRepeat = 1; + redraw = 1; + } + } else if(presses & DRPRESS) { + if(itemIndex < 2) { + itemIndex++; + if(itemIndex == 2) { + capture.autoRepeat = 0; + } else { + capture.autoRepeat = 1; + } + redraw = 1; + } + } else if(presses & DDPRESS) { + if(itemIndex == 0) { + tempInt1 = (tempInt1 == 0) ? 0 : tempInt1-1; + switch(tempInt1) { + case 0: + capture.captureStick = ASTICK; + capture.whichAxis = XAXIS; + capture.mode = (tempInt2 == 0) ? CM_STICK_FALL : (tempInt2 == 1) ? CM_STICK_RISE : CM_STICK_PIVOT; + break; + case 1: + capture.captureStick = ASTICK; + capture.whichAxis = YAXIS; + capture.mode = (tempInt2 == 0) ? CM_STICK_FALL : (tempInt2 == 1) ? CM_STICK_RISE : CM_STICK_PIVOT; + break; + case 2: + capture.captureStick = CSTICK; + capture.whichAxis = XAXIS; + capture.mode = (tempInt2 == 0) ? CM_STICK_FALL : (tempInt2 == 1) ? CM_STICK_RISE : CM_STICK_PIVOT; + break; + case 3: + capture.captureStick = CSTICK; + capture.whichAxis = YAXIS; + capture.mode = (tempInt2 == 0) ? CM_STICK_FALL : (tempInt2 == 1) ? CM_STICK_RISE : CM_STICK_PIVOT; + break; + case 4: + capture.captureStick = ASTICK; + capture.mode = CM_TRIG; + break; + case 5: + capture.captureStick = CSTICK; + capture.mode = CM_TRIG; + break; + } + //every time we change capture params, we need to re-set-up recording just to be sure. + //set up recording + capture.begin = false; + capture.triggered = false; + capture.done = false; + capture.startIndex = 0; + capture.endIndex = 0; + //then trigger the recording + pleaseCommit = 9; + } else if(itemIndex == 1) { + if(tempInt1 < 4 && tempInt2 > 0) {//only applies when the sticks are selected + tempInt2--; + capture.mode = (tempInt2 == 0) ? CM_STICK_FALL : (tempInt2 == 1) ? CM_STICK_RISE : CM_STICK_PIVOT; + } + //every time we change capture params, we need to re-set-up recording just to be sure. + //set up recording + capture.begin = false; + capture.triggered = false; + capture.done = false; + capture.startIndex = 0; + capture.endIndex = 0; + //then trigger the recording + pleaseCommit = 9; + } else { + capture.viewIndex = (capture.viewIndex == 0) ? 0 : capture.viewIndex-1; + } + redraw = 1; + } else if(presses & DUPRESS) { + if(itemIndex == 0) { + tempInt1 = fmin(5, tempInt1+1); + switch(tempInt1) { + case 0: + capture.captureStick = ASTICK; + capture.whichAxis = XAXIS; + capture.mode = (tempInt2 == 0) ? CM_STICK_FALL : (tempInt2 == 1) ? CM_STICK_RISE : CM_STICK_PIVOT; + break; + case 1: + capture.captureStick = ASTICK; + capture.whichAxis = YAXIS; + capture.mode = (tempInt2 == 0) ? CM_STICK_FALL : (tempInt2 == 1) ? CM_STICK_RISE : CM_STICK_PIVOT; + break; + case 2: + capture.captureStick = CSTICK; + capture.whichAxis = XAXIS; + capture.mode = (tempInt2 == 0) ? CM_STICK_FALL : (tempInt2 == 1) ? CM_STICK_RISE : CM_STICK_PIVOT; + break; + case 3: + capture.captureStick = CSTICK; + capture.whichAxis = YAXIS; + capture.mode = (tempInt2 == 0) ? CM_STICK_FALL : (tempInt2 == 1) ? CM_STICK_RISE : CM_STICK_PIVOT; + break; + case 4: + capture.captureStick = ASTICK; + capture.mode = CM_TRIG; + break; + case 5: + capture.captureStick = CSTICK; + capture.mode = CM_TRIG; + break; + } + //every time we change capture params, we need to re-set-up recording just to be sure. + //set up recording + capture.begin = false; + capture.triggered = false; + capture.done = false; + capture.startIndex = 0; + capture.endIndex = 0; + //then trigger the recording + pleaseCommit = 9; + } else if(itemIndex == 1) { + if(tempInt1 < 4 && tempInt2 < 2) {//only applies when the sticks are selected + tempInt2++; + capture.mode = (tempInt2 == 0) ? CM_STICK_FALL : (tempInt2 == 1) ? CM_STICK_RISE : CM_STICK_PIVOT; + } + //every time we change capture params, we need to re-set-up recording just to be sure. + //set up recording + capture.begin = false; + capture.triggered = false; + capture.done = false; + capture.startIndex = 0; + capture.endIndex = 0; + //then trigger the recording + pleaseCommit = 9; + } else { + capture.viewIndex = fmin(199, capture.viewIndex+1); + } + redraw = 1; + } else if(presses & SPRESS) {//this will be triggered by autorepeat + //if we're framestepping, redraw the title + if(itemIndex == 2) { + eraseCharLine(bitmap, 20); + drawString(bitmap, 20, 20, 15, MenuNames[menu]); + drawString(bitmap, 240, 20, 15, xyscope0); + } + //set up recording + capture.begin = false; + capture.triggered = false; + capture.done = false; + capture.startIndex = 0; + capture.endIndex = 0; + //then trigger the recording + pleaseCommit = 9; + } + return; + case MENU_PRESSTIME: + if(!changeMade) { + capture.stickThresh = 23;//dash + capture.triggerThresh = 255;//no lightshield threshold by default + capture.autoRepeat = 0;//don't auto repeat by default + changeMade = true; + } + if(presses & DLPRESS) { + itemIndex = fmax(0, itemIndex-1); + redraw = 1; + } else if(presses & DRPRESS) { + itemIndex = fmin(2, itemIndex+1); + redraw = 1; + } else if(presses & DUPRESS) { + if(itemIndex == 0) { + capture.stickThresh = fmin(100, capture.stickThresh+1); + } else if(itemIndex == 1) { + capture.triggerThresh = fmin(255, capture.triggerThresh+1); + } else {//itemIndex == 2 + capture.autoRepeat = 1; + } + redraw = 1; + } else if(presses & DDPRESS) { + if(itemIndex == 0) { + capture.stickThresh = fmax(10, capture.stickThresh-1); + } else if(itemIndex == 1) { + capture.triggerThresh = fmax(10, capture.triggerThresh-1); + } else {//itemIndex == 2 + capture.autoRepeat = 0; + } + redraw = 1; + } else if(presses & SPRESS) {//this will be triggered by autorepeat + //tell the user to press ABXYLRZ or move a stick to begin + drawString(bitmap, 30, 360, 15, presstime3); + //set up recording + capture.begin = false; + capture.done = false; + capture.endIndex = 0; + capture.mode = CM_PRESS; + //then trigger the recording + pleaseCommit = 9; + } + return; + case MENU_REACTION: + if(!changeMade) { + capture.stickThresh = 23;//dash + capture.triggerThresh = 49;//lightshield + changeMade = true; + } + if(presses & DLPRESS) { + itemIndex = 0; + redraw = 1; + } else if(presses & DRPRESS) { + itemIndex = 1; + redraw = 1; + } else if(presses & DUPRESS) { + if(itemIndex == 0) { + capture.stickThresh = fmin(100, capture.stickThresh+1); + } else {//itemIndex == 1 + capture.triggerThresh = fmin(200, capture.triggerThresh+1); + } + redraw = 1; + } else if(presses & DDPRESS) { + if(itemIndex == 0) { + capture.stickThresh = fmax(10, capture.stickThresh-1); + } else {//itemIndex == 1 + capture.triggerThresh = fmax(10, capture.triggerThresh-1); + } + redraw = 1; + } else if(presses & SPRESS) { + //tell the user to get ready + drawString(bitmap, 30, 150, 15, reaction8); + //set up for recording the delay + capture.delay = 0; + capture.done = false; + capture.mode = CM_NULL; + //wait a random amount of time + const uint32_t delay = rand() % 5'000'000 + 3'000'000; //3 to 8 seconds + const uint32_t lastMicros = time_us_64(); + uint32_t thisMicros = lastMicros; + while((thisMicros-lastMicros) < delay) { + thisMicros = time_us_64(); + } + //then trigger a redraw (which actually starts the recording) + //(we want the recording to be synced to the redraw) + pleaseCommit = 9; + redraw = 1; + } + return; + case MENU_VISION: + if(!changeMade) { + tempInt1 = controls.interlaceOffset; + } + if(presses & DUPRESS) { + controls.interlaceOffset = fmin(controls.interlaceOffsetMax, controls.interlaceOffset+1); + changeMade = controls.interlaceOffset != tempInt1; + redraw = 1; + } else if(presses & DDPRESS) { + controls.interlaceOffset = fmax(controls.interlaceOffsetMin, controls.interlaceOffset-1); + changeMade = controls.interlaceOffset != tempInt1; + redraw = 1; + } else if((presses & BSAVE) && changeMade) { + setInterlaceOffsetSetting(controls.interlaceOffset); + tempInt1 = controls.interlaceOffset; + changeMade = false; + redraw = 1; + pleaseCommit = 1;//ask the other thread to commit settings to flash + } + return; default: //do nothing return; diff --git a/PhobGCC/rp2040/src/storage.cpp b/PhobGCC/rp2040/src/storage.cpp index 7325693..10962f6 100644 --- a/PhobGCC/rp2040/src/storage.cpp +++ b/PhobGCC/rp2040/src/storage.cpp @@ -44,6 +44,12 @@ void getStoragePage() { _storage.settings.rExtras[i].intValue = temp.settings.rExtras[i].intValue; } _storage.settings.schema = temp.settings.schema; + _storage.settings.AstickCardinalSnapping = temp.settings.AstickCardinalSnapping; + _storage.settings.CstickCardinalSnapping = temp.settings.CstickCardinalSnapping; + _storage.settings.AstickAnalogScaler = temp.settings.AstickAnalogScaler; + _storage.settings.CstickAnalogScaler = temp.settings.CstickAnalogScaler; + _storage.settings.interlaceOffset = temp.settings.interlaceOffset; + _storage.settings.tournamentToggle = temp.settings.tournamentToggle; fresh = true; } } @@ -368,8 +374,64 @@ int getSchemaSetting() { getStoragePage(); return _storage.settings.schema; } + void setSchemaSetting(const int s) { getStoragePage(); _storage.settings.schema = s; } +int getCardinalSnappingSetting(const WhichStick whichStick) { + getStoragePage(); + if(whichStick == ASTICK) { + return _storage.settings.AstickCardinalSnapping; + } else { + return _storage.settings.CstickCardinalSnapping; + } +} + +void setCardinalSnappingSetting(const int cardinalSnapping, const WhichStick whichStick) { + getStoragePage(); + if(whichStick == ASTICK) { + _storage.settings.AstickCardinalSnapping = cardinalSnapping; + } else { + _storage.settings.CstickCardinalSnapping = cardinalSnapping; + } +} + +int getAnalogScalerSetting(const WhichStick whichStick) { + getStoragePage(); + if(whichStick == ASTICK) { + return _storage.settings.AstickAnalogScaler; + } else { + return _storage.settings.CstickAnalogScaler; + } +} + +void setAnalogScalerSetting(const int analogScaler, const WhichStick whichStick) { + getStoragePage(); + if(whichStick == ASTICK) { + _storage.settings.AstickAnalogScaler = analogScaler; + } else { + _storage.settings.CstickAnalogScaler = analogScaler; + } +} + +int getInterlaceOffsetSetting() { + getStoragePage(); + return _storage.settings.interlaceOffset; +} + +void setInterlaceOffsetSetting(const int o) { + getStoragePage(); + _storage.settings.interlaceOffset = o; +} + +int getTournamentToggleSetting() { + getStoragePage(); + return _storage.settings.tournamentToggle; +} + +void setTournamentToggleSetting(const int tournamentToggle) { + getStoragePage(); + _storage.settings.tournamentToggle = tournamentToggle; +} diff --git a/PhobGCC/teensy/Phob1_0Teensy3_2.h b/PhobGCC/teensy/Phob1_0Teensy3_2.h index e075f5e..5fed60a 100644 --- a/PhobGCC/teensy/Phob1_0Teensy3_2.h +++ b/PhobGCC/teensy/Phob1_0Teensy3_2.h @@ -3,6 +3,7 @@ #include #include +#include "debug.h" #include "settings.h" //Hardware-specific code for PhobGCC board revision 1.0 with a Teensy 3.2 @@ -46,7 +47,7 @@ void ADCSetup(ADC * adc, adc->adc0->setResolution(12); adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED); adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED); - + adc->adc1->setAveraging(32); adc->adc1->setResolution(16); adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED); diff --git a/PhobGCC/teensy/Phob1_0Teensy3_2DiodeShort.h b/PhobGCC/teensy/Phob1_0Teensy3_2DiodeShort.h index e542788..56e67e2 100644 --- a/PhobGCC/teensy/Phob1_0Teensy3_2DiodeShort.h +++ b/PhobGCC/teensy/Phob1_0Teensy3_2DiodeShort.h @@ -3,6 +3,7 @@ #include #include +#include "debug.h" #include "settings.h" //Hardware-specific code for PhobGCC board revision 1.0 with a Teensy 3.2 @@ -49,7 +50,7 @@ void ADCSetup(ADC * adc, adc->adc0->setResolution(12); adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED); adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED); - + adc->adc1->setAveraging(32); adc->adc1->setResolution(16); adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED); diff --git a/PhobGCC/teensy/Phob1_1Teensy3_2.h b/PhobGCC/teensy/Phob1_1Teensy3_2.h index b12fc25..55ebab0 100644 --- a/PhobGCC/teensy/Phob1_1Teensy3_2.h +++ b/PhobGCC/teensy/Phob1_1Teensy3_2.h @@ -3,6 +3,7 @@ #include #include +#include "debug.h" #include "settings.h" //Hardware specific code for PhobGCC board revision 1.1 with a Teensy 3.2 diff --git a/PhobGCC/teensy/Phob1_1Teensy3_2DiodeShort.h b/PhobGCC/teensy/Phob1_1Teensy3_2DiodeShort.h index 384b7b1..a145118 100644 --- a/PhobGCC/teensy/Phob1_1Teensy3_2DiodeShort.h +++ b/PhobGCC/teensy/Phob1_1Teensy3_2DiodeShort.h @@ -3,6 +3,7 @@ #include #include +#include "debug.h" #include "settings.h" //Hardware specific code for PhobGCC board revision 1.1 with a Teensy 3.2 diff --git a/PhobGCC/teensy/Phob1_1Teensy4_0.h b/PhobGCC/teensy/Phob1_1Teensy4_0.h index 6b01266..e433c39 100644 --- a/PhobGCC/teensy/Phob1_1Teensy4_0.h +++ b/PhobGCC/teensy/Phob1_1Teensy4_0.h @@ -3,6 +3,7 @@ #include #include +#include "debug.h" #include "settings.h" //Hardware specific code for PhobGCC board revision 1.1 with a Teensy 4.0 diff --git a/PhobGCC/teensy/Phob1_1Teensy4_0DiodeShort.h b/PhobGCC/teensy/Phob1_1Teensy4_0DiodeShort.h index 8bcbb25..b79361a 100644 --- a/PhobGCC/teensy/Phob1_1Teensy4_0DiodeShort.h +++ b/PhobGCC/teensy/Phob1_1Teensy4_0DiodeShort.h @@ -3,6 +3,7 @@ #include #include +#include "debug.h" #include "settings.h" //Hardware specific code for PhobGCC board revision 1.1 with a Teensy 4.0 diff --git a/PhobGCC/teensy/Phob1_2Teensy4_0.h b/PhobGCC/teensy/Phob1_2Teensy4_0.h index 63440b8..467f7a3 100644 --- a/PhobGCC/teensy/Phob1_2Teensy4_0.h +++ b/PhobGCC/teensy/Phob1_2Teensy4_0.h @@ -3,6 +3,7 @@ #include #include +#include "debug.h" #include "settings.h" //Hardware specific code for PhobGCC board revision 1.2 with a Teensy 4.0 diff --git a/PhobGCC/teensy/debug.h b/PhobGCC/teensy/debug.h new file mode 100644 index 0000000..b372f4a --- /dev/null +++ b/PhobGCC/teensy/debug.h @@ -0,0 +1,63 @@ +#ifndef DEBUG_H +#define DEBUG_H + +#define DEBUG_ENABLED 1 + +inline void debug_print(const char* str) { +#if (DEBUG_ENABLED) + Serial.print(str); +#endif +} +inline void debug_print(char c) { +#if (DEBUG_ENABLED) + Serial.print(c); +#endif +} +inline void debug_print(int i, int x = DEC) { +#if (DEBUG_ENABLED) + Serial.print(i, x); +#endif +} +inline void debug_print(long l, int x = DEC) { +#if (DEBUG_ENABLED) + Serial.print(l, x); +#endif +} +inline void debug_print(double d, int x = 2) { +#if (DEBUG_ENABLED) + Serial.print(d, x); +#endif +} + +inline void debug_println(const char* str) { +#if (DEBUG_ENABLED) + Serial.println(str); +#endif +} +inline void debug_println(char c) { +#if (DEBUG_ENABLED) + Serial.println(c); +#endif +} +inline void debug_println(int i, int x = DEC) { +#if (DEBUG_ENABLED) + Serial.println(i, x); +#endif +} +inline void debug_println(long l, int x = DEC) { +#if (DEBUG_ENABLED) + Serial.println(l, x); +#endif +} +inline void debug_println(double d, int x = 2) { +#if (DEBUG_ENABLED) + Serial.println(d, x); +#endif +} +inline void debug_println() { +#if (DEBUG_ENABLED) + Serial.println(); +#endif +} + +#endif //DEBUG_H diff --git a/PhobGCC/teensy/settings.h b/PhobGCC/teensy/settings.h index 9777d81..999b1ab 100644 --- a/PhobGCC/teensy/settings.h +++ b/PhobGCC/teensy/settings.h @@ -42,7 +42,12 @@ namespace Eeprom { const int _eepromExtrasLeft = _eepromExtrasDown+_bytesPerFloat*4; const int _eepromExtrasRight = _eepromExtrasLeft+_bytesPerFloat*4; const int _eepromSchema = _eepromExtrasRight+_bytesPerFloat*4; - //const int _nextSetting = _eepromSchema+bytesPerFloat; + const int _eepromAstickCardinalSnapping = _eepromSchema+_bytesPerFloat; + const int _eepromCstickCardinalSnapping = _eepromAstickCardinalSnapping+_bytesPerFloat; + const int _eepromAstickAnalogScaler = _eepromCstickCardinalSnapping+_bytesPerFloat; + const int _eepromCstickAnalogScaler =_eepromAstickAnalogScaler+_bytesPerFloat; + const int _eepromTournamentToggle = _eepromCstickAnalogScaler+_bytesPerFloat; + //const int _nextSetting = _eepromCstickAnalogScaler+bytesPerFloat; }; JumpConfig getJumpSetting() { @@ -229,6 +234,52 @@ void setWaveshapingSetting(const int waveshaping, const WhichStick whichStick, c } } +int getCardinalSnappingSetting(const WhichStick whichStick) { + int output; + if(whichStick == ASTICK) { + EEPROM.get(Eeprom::_eepromAstickCardinalSnapping, output); + } else { + EEPROM.get(Eeprom::_eepromCstickCardinalSnapping, output); + } + return output; +} + +void setCardinalSnappingSetting(const int cardinalSnapping, const WhichStick whichStick) { + if(whichStick == ASTICK) { + EEPROM.put(Eeprom::_eepromAstickCardinalSnapping, cardinalSnapping); + } else { + EEPROM.put(Eeprom::_eepromCstickCardinalSnapping, cardinalSnapping); + } +} + +int getAnalogScalerSetting(const WhichStick whichStick) { + int output; + if(whichStick == ASTICK) { + EEPROM.get(Eeprom::_eepromAstickAnalogScaler, output); + } else { + EEPROM.get(Eeprom::_eepromCstickAnalogScaler, output); + } + return output; +} + +void setAnalogScalerSetting(const int analogScaler, const WhichStick whichStick) { + if(whichStick == ASTICK) { + EEPROM.put(Eeprom::_eepromAstickAnalogScaler, analogScaler); + } else { + EEPROM.put(Eeprom::_eepromCstickAnalogScaler, analogScaler); + } +} + +int getTournamentToggleSetting() { + int output; + EEPROM.get(Eeprom::_eepromTournamentToggle, output); + return output; +} + +void setTournamentToggleSetting(const int tournamentToggle) { + EEPROM.put(Eeprom::_eepromTournamentToggle, tournamentToggle); +} + //pulls 32 points from eeprom void getFloatPoints(const int eepromAddress, float array[32]) { float tempArray[32];