Files
GP2040-CE/headers/playerleds.h
Luke A 534fd98c42 Haute M Ultra / Lite Case RGBs (#1300)
* Initial commit of a working Haute Lite / Ultra with translated comments.

Enabling/disabling the ambient light and counts will need to be moved to the web config.

* Moved AnimationStation over to our actual code base instead of a library. This allows us to use protobuf, modify the file formats a bit more, and make the code a lot more dynamic.

Also removed .hpp as we do not use that naming convention in our code.

* Renaming some lowercases

* Lowercase the folder as well

* Linux is sensitive to case while Windows doesn't care :(

* More casing

* More capitalizations

* Moved everything out of the animationstation and playerled libraries, removed as many statics as I could find. Still a few statics in Animation:: but still cleaning.

DO NOT USE: This doesn't work yet, but it is getting closer

* Removed the static case rgbs in favor of ambient / linkage now that we're fully integrated into the source.

This is very close to where we want to be

* Added COSMOX M Ultra and M Lite configs

Moved all of our ambient lighting over to boardconfig defines

Updated the OpenCore0 definitions to use our new ambient lighting

* Almost done, changed bytes over to our RGB define for colors, touched up a lot of different things. Chase effect is now properly working with wrap-around, cycling is all much better. Removed power-on animations as we have no real reason for them right now, we can add them back in later.

* Changed hotkeys for case lights a bit

* Slight code clean-ups, I'm happy with this

* Last bit of clean-up before moving to review

* Revert back to nothing

* More code cleanups. There's a known bug with linkage that will be solved in the next branch

* Deprecated some proto config settings
2025-03-21 11:18:18 -04:00

183 lines
3.7 KiB
C++

#ifndef PLAYER_LEDS_H_
#define PLAYER_LEDS_H_
#include <cstring>
#include <cstdio>
#include <stdint.h>
#include "pico/time.h"
#define PLED_COUNT 4
#define PLED_MAX_BRIGHTNESS 0xFF
#define PLED_MAX_LEVEL 0xFFFF
typedef enum
{
PLED_STATE_LED1 = (1 << 0),
PLED_STATE_LED2 = (1 << 1),
PLED_STATE_LED3 = (1 << 2),
PLED_STATE_LED4 = (1 << 3),
} PLEDStateMask;
typedef enum
{
PLED_ANIM_NONE,
PLED_ANIM_OFF,
PLED_ANIM_SOLID,
PLED_ANIM_BLINK,
PLED_ANIM_CYCLE,
PLED_ANIM_FADE,
PLED_ANIM_BLINK_CUSTOM,
} PLEDAnimationType;
const PLEDAnimationType ANIMATION_TYPES[] =
{
PLED_ANIM_NONE,
PLED_ANIM_OFF,
PLED_ANIM_SOLID,
PLED_ANIM_BLINK,
PLED_ANIM_CYCLE,
PLED_ANIM_FADE,
PLED_ANIM_BLINK_CUSTOM,
};
typedef enum
{
PLED_SPEED_OFF = 0,
PLED_SPEED_PLAID = 10,
PLED_SPEED_LUDICROUS = 20,
PLED_SPEED_RIDICULOUS = 50,
PLED_SPEED_FASTER = 100,
PLED_SPEED_FAST = 250,
PLED_SPEED_NORMAL = 500,
PLED_SPEED_SLOW = 1000,
} PLEDAnimationSpeed;
const PLEDAnimationSpeed ANIMATION_SPEEDS[] =
{
PLED_SPEED_OFF,
PLED_SPEED_PLAID,
PLED_SPEED_LUDICROUS,
PLED_SPEED_RIDICULOUS,
PLED_SPEED_FASTER,
PLED_SPEED_FAST,
PLED_SPEED_NORMAL,
PLED_SPEED_SLOW,
};
struct PLEDAnimationState
{
uint8_t state = 0;
PLEDAnimationType animation;
PLEDAnimationSpeed speed;
uint32_t speedOn = 0;
uint32_t speedOff = 0;
};
class PlayerLEDs
{
public:
virtual void setup() = 0;
virtual void display() = 0;
void animate(PLEDAnimationState animationState);
protected:
void parseState(uint8_t state)
{
memcpy(lastPledState, currentPledState, sizeof(currentPledState));
for (int i = 0; i < PLED_COUNT; i++)
currentPledState[i] = (state & (1 << i)) == (1 << i);
}
inline void reset()
{
memset(lastPledState, 0, sizeof(lastPledState));
memset(currentPledState, 0, sizeof(currentPledState));
nextAnimationTime = get_absolute_time();
brightness = PLED_MAX_BRIGHTNESS;
fadeIn = false;
}
inline void handleBlink(PLEDAnimationSpeed speed)
{
for (int i = 0; i < PLED_COUNT; i++)
{
if (lastPledState[i])
currentPledState[i] = false;
}
nextAnimationTime = make_timeout_time_ms(speed);
}
inline void handleBlinkCustom(uint32_t speed, uint32_t speedOff)
{
uint32_t nextSpeed = 0;
for (int i = 0; i < PLED_COUNT; i++)
{
if (speed > 0 && speedOff == 0) {
if (lastPledState[i]) {
currentPledState[i] = true;
nextSpeed = speed;
}
} else {
if (lastPledState[i]) {
currentPledState[i] = false;
nextSpeed = speed;
} else {
currentPledState[i] = true;
nextSpeed = speedOff;
}
}
}
nextAnimationTime = make_timeout_time_ms(nextSpeed);
}
inline void handleCycle(PLEDAnimationSpeed speed)
{
for (int i = 0; i < PLED_COUNT; i++)
{
if (lastPledState[i] != 0)
{
memset(currentPledState, 0, sizeof(currentPledState));
for (int j = 0; j < PLED_COUNT; j++)
{
if (lastPledState[j])
{
currentPledState[(j + 1) % PLED_COUNT] = true;
break;
}
}
break;
}
}
nextAnimationTime = make_timeout_time_ms(speed);
}
inline void handleFade()
{
if (fadeIn)
{
brightness += 5;
if (brightness == PLED_MAX_BRIGHTNESS)
fadeIn = false;
}
else
{
brightness -= 5;
if (brightness == 0)
fadeIn = true;
}
nextAnimationTime = make_timeout_time_ms(PLED_SPEED_LUDICROUS);
}
uint16_t ledLevels[PLED_COUNT] = {PLED_MAX_LEVEL, PLED_MAX_LEVEL, PLED_MAX_LEVEL, PLED_MAX_LEVEL};
absolute_time_t nextAnimationTime;
PLEDAnimationType selectedAnimation = PLED_ANIM_NONE;
bool lastPledState[PLED_COUNT] = { };
bool currentPledState[PLED_COUNT] = { };
uint8_t brightness = PLED_MAX_BRIGHTNESS;
bool fadeIn = false;
};
#endif