diff --git a/configs/OpenCore0/BoardConfig.h b/configs/OpenCore0/BoardConfig.h
index 44763d416..01293d849 100644
--- a/configs/OpenCore0/BoardConfig.h
+++ b/configs/OpenCore0/BoardConfig.h
@@ -106,6 +106,15 @@
#define PLED4_PIN 27
#define PLED_COLOR ColorGreen
+#define TURBO_LED_INDEX 28
+#define TURBO_LED_TYPE PLED_TYPE_RGB
+#define TURBO_LED_COLOR ColorRed
+
+#define CASE_RGB_TYPE CASE_RGB_TYPE_STATIC
+#define CASE_RGB_INDEX 29
+#define CASE_RGB_COUNT 20
+#define CASE_RGB_COLOR ColorGreen
+
#define HAS_I2C_DISPLAY 1
#define I2C0_ENABLED 1
#define I2C0_PIN_SDA 0
diff --git a/configs/OpenCore0WASD/BoardConfig.h b/configs/OpenCore0WASD/BoardConfig.h
index 2805de444..b79ffa374 100644
--- a/configs/OpenCore0WASD/BoardConfig.h
+++ b/configs/OpenCore0WASD/BoardConfig.h
@@ -105,9 +105,17 @@
#define PLED2_PIN 14
#define PLED3_PIN 15
#define PLED4_PIN 16
-
#define PLED_COLOR ColorGreen
+#define TURBO_LED_INDEX 17
+#define TURBO_LED_TYPE PLED_TYPE_RGB
+#define TURBO_LED_COLOR ColorRed
+
+#define CASE_RGB_TYPE CASE_RGB_TYPE_STATIC
+#define CASE_RGB_INDEX 18
+#define CASE_RGB_COUNT 20
+#define CASE_RGB_COLOR ColorGreen
+
#define HAS_I2C_DISPLAY 1
#define I2C0_ENABLED 1
#define I2C0_PIN_SDA 0
diff --git a/headers/helper.h b/headers/helper.h
index 313948c46..eaefc9711 100644
--- a/headers/helper.h
+++ b/headers/helper.h
@@ -35,6 +35,22 @@
#define PLED_COLOR ColorWhite // White
#endif
+#ifndef CASE_RGB_TYPE
+#define CASE_RGB_TYPE CASE_RGB_TYPE_NONE
+#endif
+
+#ifndef CASE_RGB_INDEX
+#define CASE_RGB_INDEX -1
+#endif
+
+#ifndef CASE_RGB_COLOR
+#define CASE_RGB_COLOR ColorGreen // Green
+#endif
+
+#ifndef CASE_RGB_COUNT
+#define CASE_RGB_COUNT 0
+#endif
+
static inline bool isValidPin(int32_t pin) {
int32_t numBank0GPIOS = NUM_BANK0_GPIOS;
return pin >= 0 && pin < numBank0GPIOS; }
diff --git a/proto/config.proto b/proto/config.proto
index 851eda73b..2c80040e6 100644
--- a/proto/config.proto
+++ b/proto/config.proto
@@ -288,6 +288,11 @@ message LEDOptions
optional int32 pledIndex2 = 33;
optional int32 pledIndex3 = 34;
optional int32 pledIndex4 = 35;
+
+ optional CaseRGBType caseRGBType = 36;
+ optional int32 caseRGBIndex = 37;
+ optional uint32 caseRGBColor = 38;
+ optional uint32 caseRGBCount = 39;
};
// This has to be kept in sync with AnimationOptions in AnimationStation.hpp
diff --git a/proto/enums.proto b/proto/enums.proto
index 1473951e5..968e751ec 100644
--- a/proto/enums.proto
+++ b/proto/enums.proto
@@ -347,6 +347,14 @@ enum PLEDType
PLED_TYPE_RGB = 1;
};
+enum CaseRGBType
+{
+ option (nanopb_enumopt).long_names = false;
+
+ CASE_RGB_TYPE_NONE = -1;
+ CASE_RGB_TYPE_STATIC = 0;
+};
+
enum ForcedSetupMode
{
option (nanopb_enumopt).long_names = false;
diff --git a/src/addons/neopicoleds.cpp b/src/addons/neopicoleds.cpp
index 2fc5fe5d0..45bb33a34 100644
--- a/src/addons/neopicoleds.cpp
+++ b/src/addons/neopicoleds.cpp
@@ -209,8 +209,7 @@ void NeoPicoLEDAddon::setup()
gamepad->auxState.playerID.enabled = true;
gamepad->auxState.sensors.statusLight.enabled = true;
- if ( ledOptions.pledType == PLED_TYPE_RGB ||
- turboOptions.turboLedType == PLED_TYPE_RGB) {
+ if ( ledOptions.pledType == PLED_TYPE_RGB ) {
neoPLEDs = new NeoPicoPlayerLEDs();
}
@@ -318,6 +317,17 @@ void NeoPicoLEDAddon::process()
}
}
+ // Case RGB LEDs for a single static color go here
+ if ( ledOptions.caseRGBType == CASE_RGB_TYPE_STATIC &&
+ ledOptions.caseRGBIndex >= 0 &&
+ ledOptions.caseRGBCount > 0 ) {
+ float brightness = as.GetBrightnessX();
+ uint32_t colorVal = ((RGB)ledOptions.caseRGBColor).value(neopico->GetFormat(), brightness);
+ for(int i = 0; i < ledOptions.caseRGBCount; i++) {
+ frame[ledOptions.caseRGBIndex+i] = colorVal;
+ }
+ }
+
neopico->SetFrame(frame);
neopico->Show();
AnimationStore.save();
@@ -621,6 +631,10 @@ void NeoPicoLEDAddon::configureLEDs()
if (turboOptions.turboLedType == PLED_TYPE_RGB)
ledCount += 1;
+ if (ledOptions.caseRGBType == CASE_RGB_TYPE_STATIC ) {
+ ledCount += ledOptions.caseRGBCount;
+ }
+
// Remove the old neopico (config can call this)
delete neopico;
neopico = new NeoPico(ledOptions.dataPin, ledCount, static_cast(ledOptions.ledFormat));
diff --git a/src/config_utils.cpp b/src/config_utils.cpp
index d8dd5fbf4..d697da66c 100644
--- a/src/config_utils.cpp
+++ b/src/config_utils.cpp
@@ -472,6 +472,11 @@ void ConfigUtils::initUnsetPropertiesWithDefaults(Config& config)
INIT_UNSET_PROPERTY(config.ledOptions, pledIndex3, PLED3_PIN);
INIT_UNSET_PROPERTY(config.ledOptions, pledIndex4, PLED4_PIN);
+ INIT_UNSET_PROPERTY(config.ledOptions, caseRGBType, CASE_RGB_TYPE);
+ INIT_UNSET_PROPERTY(config.ledOptions, caseRGBIndex, CASE_RGB_INDEX);
+ INIT_UNSET_PROPERTY(config.ledOptions, caseRGBColor, static_cast(CASE_RGB_COLOR.r) << 16 | static_cast(CASE_RGB_COLOR.g) << 8 | static_cast(CASE_RGB_COLOR.b));
+ INIT_UNSET_PROPERTY(config.ledOptions, caseRGBCount, CASE_RGB_COUNT);
+
// animationOptions
INIT_UNSET_PROPERTY(config.animationOptions, baseAnimationIndex, LEDS_BASE_ANIMATION_INDEX);
INIT_UNSET_PROPERTY(config.animationOptions, brightness, LEDS_BRIGHTNESS);
diff --git a/src/configs/webconfig.cpp b/src/configs/webconfig.cpp
index 4b6754f3d..89713c858 100644
--- a/src/configs/webconfig.cpp
+++ b/src/configs/webconfig.cpp
@@ -799,6 +799,10 @@ std::string setLedOptions()
readDoc(ledOptions.pledIndex3, doc, "pledIndex3");
readDoc(ledOptions.pledIndex4, doc, "pledIndex4");
readDoc(ledOptions.pledColor, doc, "pledColor");
+ readDoc(ledOptions.caseRGBType, doc, "caseRGBType");
+ readDoc(ledOptions.caseRGBIndex, doc, "caseRGBIndex");
+ readDoc(ledOptions.caseRGBCount, doc, "caseRGBCount");
+ readDoc(ledOptions.caseRGBColor, doc, "caseRGBColor");
Storage::getInstance().save(true);
return serialize_json(doc);
@@ -855,6 +859,10 @@ std::string getLedOptions()
writeDoc(doc, "pledIndex3", ledOptions.pledIndex3);
writeDoc(doc, "pledIndex4", ledOptions.pledIndex4);
writeDoc(doc, "pledColor", ((RGB)ledOptions.pledColor).value(LED_FORMAT_RGB));
+ writeDoc(doc, "caseRGBType", ledOptions.caseRGBType);
+ writeDoc(doc, "caseRGBIndex", ledOptions.caseRGBIndex);
+ writeDoc(doc, "caseRGBCount", ledOptions.caseRGBCount);
+ writeDoc(doc, "caseRGBColor", ((RGB)ledOptions.caseRGBColor).value(LED_FORMAT_RGB));
return serialize_json(doc);
}
diff --git a/www/server/app.js b/www/server/app.js
index c47c3f970..0e313f01b 100644
--- a/www/server/app.js
+++ b/www/server/app.js
@@ -237,6 +237,10 @@ app.get('/api/getLedOptions', (req, res) => {
pledIndex3: 14,
pledIndex4: 15,
pledColor: 65280,
+ caseRGBType: 0,
+ caseRGBColor: 65280,
+ caseRGBIndex: -1,
+ caseRGBCount: 0,
turnOffWhenSuspended: 0,
});
});
diff --git a/www/src/Locales/en/LedConfig.jsx b/www/src/Locales/en/LedConfig.jsx
index 97678639c..cf6a51ab6 100644
--- a/www/src/Locales/en/LedConfig.jsx
+++ b/www/src/Locales/en/LedConfig.jsx
@@ -20,6 +20,17 @@ export default {
'pled-type-rgb': 'RGB',
'pled-color-label': 'RGB PLED Color',
},
+ case: {
+ 'header-text': 'Case RGB LEDs',
+ 'sub-header-text':
+ 'For Case RGB LEDs, set a starting index and the case RGB count. The index must be after the last LED button defined but can be before or after the player LEDs and turbo LED.',
+ 'case-index-label': 'RGB LED Index',
+ 'case-count-label': 'RGB LED Count',
+ 'case-type-label': 'Color Type',
+ 'case-type-off': 'Off',
+ 'case-type-static': 'Static',
+ 'case-color-label': 'Case RGB Color',
+ },
'pled-pin-label': 'PLED #{{pin}} Pin',
'pled-index-label': 'PLED #{{index}} Index',
'rgb-order': {
diff --git a/www/src/Pages/LEDConfigPage.jsx b/www/src/Pages/LEDConfigPage.jsx
index 4cdd116bd..d2620b631 100644
--- a/www/src/Pages/LEDConfigPage.jsx
+++ b/www/src/Pages/LEDConfigPage.jsx
@@ -58,6 +58,10 @@ const defaultValue = {
pledIndex3: -1,
pledIndex4: -1,
pledColor: '#00ff00',
+ caseRGBType: 0,
+ caseRGBIndex: -1,
+ caseRGBCount: 0,
+ caseRGBColor: '#00ff00',
ledButtonMap: {},
};
@@ -137,6 +141,21 @@ const schema = yup.object().shape({
.label('PLED Index 4')
.validateMinWhenEqualTo('pledType', 1, 0),
turnOffWhenSuspended: yup.number().label('Turn Off When Suspended'),
+ caseRGBType: yup.number().required().label('Case RGB Type'),
+ caseRGBColor: yup.string().label('Case RGB LEDs').validateColor(),
+ caseRGBCount: yup
+ .number()
+ .required()
+ .positive()
+ .integer()
+ .min(0)
+ .max(100)
+ .label('Case RGB Count'),
+ caseRGBIndex: yup
+ .number()
+ .label('Case RGB Index')
+ .min(-1)
+ .max(100),
ledButtonMap: yup.object(),
});
@@ -272,6 +291,7 @@ export default function LEDConfigPage() {
const data = {
...values,
pledColor: hexToInt(values.pledColor || '#000000'),
+ caseRGBColor: hexToInt(values.caseRGBColor || '#000000'),
};
const success = await WebApi.setLedOptions(data);
@@ -646,6 +666,93 @@ export default function LEDConfigPage() {
+
+
+
+
+ setFieldValue('caseRGBType', parseInt(e.target.value))
+ }
+ >
+
+
+
+
+ setFieldValue('caseRGBIndex', parseInt(e.target.value))
+ }
+ min={0}
+ />
+
+ setFieldValue('caseRGBCount', parseInt(e.target.value))
+ }
+ min={0}
+ />
+ {
+ handleChange(e);
+ setShowPicker(false);
+ }}
+ />
+ setFieldValue('caseRGBColor', c)}
+ onDismiss={() => setShowPicker(false)}
+ placement="top"
+ presetColors={LEDColors.map((c) => ({
+ title: c.name,
+ color: c.value,
+ }))}
+ show={showPicker}
+ target={colorPickerTarget}
+ >
+
+
+ {t('LedConfig:case.sub-header-text')}
+
+
+
{saveMessage ? {saveMessage} : null}