From e8943edff6edac9586d981e07ce0313ac0e8a898 Mon Sep 17 00:00:00 2001 From: 6d16ce71d2cb7fb29ef6c9b6fd0f0943018cd3d0 <6d16ce71d2cb7fb29ef6c9b6fd0f0943018cd3d0@redacted> Date: Sun, 8 Dec 2019 13:17:33 -0800 Subject: [PATCH] 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. --- src/imports/SMX.h | 42 ++++++++++++++++++----------- src/imports/import_32_indep_SMX.def | 1 + src/main/ddrio-smx/ddrio.c | 26 ++++++++++-------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/imports/SMX.h b/src/imports/SMX.h index a478b50..1269e40 100644 --- a/src/imports/SMX.h +++ b/src/imports/SMX.h @@ -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 diff --git a/src/imports/import_32_indep_SMX.def b/src/imports/import_32_indep_SMX.def index 1dc81dc..0362e58 100644 --- a/src/imports/import_32_indep_SMX.def +++ b/src/imports/import_32_indep_SMX.def @@ -7,6 +7,7 @@ EXPORTS SMX_GetInfo SMX_GetInputState SMX_SetLights + SMX_SetLights2 SMX_ReenableAutoLights SMX_GetConfig SMX_SetConfig diff --git a/src/main/ddrio-smx/ddrio.c b/src/main/ddrio-smx/ddrio.c index f909216..def8018 100644 --- a/src/main/ddrio-smx/ddrio.c +++ b/src/main/ddrio-smx/ddrio.c @@ -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;