Add light support for SMX gen 4 pads

The old set lights API doesn't support gen 4 pads. Replace the call to SMX_SetLights with SMX_SetLights2 which adds support for gen 4 pads while maintaining backwards compatibility.
This commit is contained in:
6d16ce71d2cb7fb29ef6c9b6fd0f0943018cd3d0
2019-12-08 13:17:33 -08:00
committed by icex2
parent 61f3eb44d2
commit e8943edff6
3 changed files with 42 additions and 27 deletions

View File

@@ -61,14 +61,24 @@ SMX_EXTERN_C SMX_API void SMX_GetInfo(int pad, struct SMXInfo *info);
// Get a mask of the currently pressed panels.
SMX_EXTERN_C SMX_API uint16_t SMX_GetInputState(int pad);
// Update the lights. Both pads are always updated together. lightsData is a
// list of 8-bit RGB colors, one for each LED. Each panel has lights in the
// following order:
// (deprecated) Equivalent to SMX_SetLights2(lightsData, 864).
SMX_API void SMX_SetLights(const char lightData[864]);
// Update the lights. Both pads are always updated together. lightData is a list of 8-bit RGB
// colors, one for each LED.
//
// 0123
// 4567
// 89AB
// CDEF
// lightDataSize is the number of bytes in lightsData. This should be 1350 (2 pads * 9 panels *
// 25 lights * 3 RGB colors). For backwards-compatibility, this can also be 864.
//
// Each panel has lights in the following order:
//
// 00 01 02 03
// 16 17 18
// 04 05 06 07
// 19 20 21
// 08 09 10 11
// 22 23 24
// 12 13 14 15
//
// Panels are in the following order:
//
@@ -76,17 +86,17 @@ SMX_EXTERN_C SMX_API uint16_t SMX_GetInputState(int pad);
// 345 CDE
// 678 F01
//
// With 18 panels, 16 LEDs per panel and 3 bytes per LED, each light update has
// 864 bytes of data.
// With 18 panels, 25 LEDs per panel and 3 bytes per LED, each light update has 1350 bytes of data.
//
// Lights will update at up to 30 FPS. If lights data is sent more quickly, a
// best effort will be made to send the most recent lights data available, but
// the panels won't update more quickly.
// Lights will update at up to 30 FPS. If lights data is sent more quickly, a best effort will be
// made to send the most recent lights data available, but the panels won't update more quickly.
//
// The panels will return to automatic lighting if no lights are received for a
// while, so applications controlling lights should send light updates
// continually, even if the lights aren't changing.
SMX_EXTERN_C SMX_API void SMX_SetLights(const char lightsData[864]);
// The panels will return to automatic lighting if no lights are received for a while, so applications
// controlling lights should send light updates continually, even if the lights aren't changing.
//
// For backwards compatibility, if lightDataSize is 864, the old 4x4-only order is used,
// which simply omits lights 16-24.
SMX_API void SMX_SetLights2(const char *lightData, int lightDataSize);
// By default, the panels light automatically when stepped on. If a lights
// command is sent by the application, this stops happening to allow the

View File

@@ -7,6 +7,7 @@ EXPORTS
SMX_GetInfo
SMX_GetInputState
SMX_SetLights
SMX_SetLights2
SMX_ReenableAutoLights
SMX_GetConfig
SMX_SetConfig

View File

@@ -41,24 +41,28 @@ static const struct ddr_io_smx_pad_map ddr_io_smx_pad_map[] = {
{1, 1 << 7, 1 << DDR_P2_DOWN},
};
#define DDR_IO_SMX_LIGHT_VALUES_PER_PANEL 75
#define DDR_IO_SMX_NUMBER_OF_PANELS 18
#define DDR_IO_SMX_TOTAL_LIGHT_VALUES DDR_IO_SMX_LIGHT_VALUES_PER_PANEL * DDR_IO_SMX_NUMBER_OF_PANELS
static const struct ddr_io_smx_light_map ddr_io_smx_light_map[] = {
/* Light L/R blue and U/D red to match DDR pad color scheme */
{1 << LIGHT_P1_UP, 48 * 1, 0xFF, 0x00, 0x00},
{1 << LIGHT_P1_LEFT, 48 * 3, 0x00, 0x00, 0xFF},
{1 << LIGHT_P1_RIGHT, 48 * 5, 0x00, 0x00, 0xFF},
{1 << LIGHT_P1_DOWN, 48 * 7, 0xFF, 0x00, 0x00},
{1 << LIGHT_P1_UP, DDR_IO_SMX_LIGHT_VALUES_PER_PANEL * 1, 0xFF, 0x00, 0x00},
{1 << LIGHT_P1_LEFT, DDR_IO_SMX_LIGHT_VALUES_PER_PANEL * 3, 0x00, 0x00, 0xFF},
{1 << LIGHT_P1_RIGHT, DDR_IO_SMX_LIGHT_VALUES_PER_PANEL * 5, 0x00, 0x00, 0xFF},
{1 << LIGHT_P1_DOWN, DDR_IO_SMX_LIGHT_VALUES_PER_PANEL * 7, 0xFF, 0x00, 0x00},
{1 << LIGHT_P2_UP, 48 * 10, 0xFF, 0x00, 0x00},
{1 << LIGHT_P2_LEFT, 48 * 12, 0x00, 0x00, 0xFF},
{1 << LIGHT_P2_RIGHT, 48 * 14, 0x00, 0x00, 0xFF},
{1 << LIGHT_P2_DOWN, 48 * 16, 0xFF, 0x00, 0x00},
{1 << LIGHT_P2_UP, DDR_IO_SMX_LIGHT_VALUES_PER_PANEL * 10, 0xFF, 0x00, 0x00},
{1 << LIGHT_P2_LEFT, DDR_IO_SMX_LIGHT_VALUES_PER_PANEL * 12, 0x00, 0x00, 0xFF},
{1 << LIGHT_P2_RIGHT, DDR_IO_SMX_LIGHT_VALUES_PER_PANEL * 14, 0x00, 0x00, 0xFF},
{1 << LIGHT_P2_DOWN, DDR_IO_SMX_LIGHT_VALUES_PER_PANEL * 16, 0xFF, 0x00, 0x00},
};
static _Atomic uint32_t ddr_io_smx_pad_state[2];
static CRITICAL_SECTION ddr_io_smx_lights_lock;
static uint8_t ddr_io_smx_lights_counter;
static char ddr_io_smx_lights[864];
static char ddr_io_smx_lights[DDR_IO_SMX_TOTAL_LIGHT_VALUES];
void ddr_io_set_loggers(
log_formatter_t misc,
@@ -109,7 +113,7 @@ uint32_t ddr_io_read_pad(void)
EnterCriticalSection(&ddr_io_smx_lights_lock);
if (ddr_io_smx_lights_counter == 0) {
SMX_SetLights(ddr_io_smx_lights);
SMX_SetLights2(ddr_io_smx_lights, lengthof(ddr_io_smx_lights));
}
ddr_io_smx_lights_counter++;
@@ -149,7 +153,7 @@ void ddr_io_set_lights_extio(uint32_t lights)
if (lights & map->extio_bit) {
offset = map->smx_light_offset;
for (j = 0; j < 48; j += 3) {
for (j = 0; j < DDR_IO_SMX_LIGHT_VALUES_PER_PANEL; j += 3) {
ddr_io_smx_lights[offset + j] = map->r;
ddr_io_smx_lights[offset + j + 1] = map->g;
ddr_io_smx_lights[offset + j + 2] = map->b;