Files
spice2x-r3d/src/spice2x/rawinput/smxdedicab.cpp
T

96 lines
3.1 KiB
C++

#include "smxdedicab.h"
#include "smx.h"
#include "util/logging.h"
namespace {
static const std::string DEVICE_NAMES[] = {
"Marquee",
"Left Vertical Strip",
"Left Spotlights",
"Right Vertical Strip",
"Right Spotlights"
};
static const size_t DEVICE_LED_COUNTS[] = {
24, 28, 8, 28, 8
};
void NullSmxCallback(int pad, SMXUpdateCallbackReason reason, void *pUser) {
}
}
namespace rawinput {
std::string SmxDedicabDevice::GetLightNameByIndex(size_t index) {
const size_t subpixel = index % 3;
const size_t device = (index / 3);
switch (subpixel) {
case 0: return fmt::format("{} Red", DEVICE_NAMES[device]);
case 1: return fmt::format("{} Green", DEVICE_NAMES[device]);
case 2: return fmt::format("{} Blue", DEVICE_NAMES[device]);
}
return "StepManiaX Dedicated Cabinet - Invalid Index";
}
SmxDedicabDevice::SmxDedicabDevice() :
m_lightData {
new uint8_t[DEVICE_LED_COUNTS[0] * 3],
new uint8_t[DEVICE_LED_COUNTS[1] * 3],
new uint8_t[DEVICE_LED_COUNTS[2] * 3],
new uint8_t[DEVICE_LED_COUNTS[3] * 3],
new uint8_t[DEVICE_LED_COUNTS[4] * 3]
},
m_lightDataMutex()
{
}
bool SmxDedicabDevice::Initialize() {
SMXWrapper::getInstance().SMX_Start(&NullSmxCallback, nullptr);
// After initializing the connection, we need to momentarily pause in order for the
// IO device to not miss our first packets. Then we need to send 0x00 to flush out each
// channel on initialization. If we don't do this, the lights have garbage data for each
// channel until they're fully flushed.
Sleep(1000);
for (size_t device = 0; device < DEVICE_COUNT; device++) {
const size_t numLeds = DEVICE_LED_COUNTS[device];
for (size_t j = 0; j < numLeds * 3; j++) {
m_lightData[device][j] = 0x00;
}
SMXWrapper::getInstance().SMX_SetDedicatedCabinetLights(
static_cast<SMXDedicatedCabinetLights>(device),
reinterpret_cast<const char*>(&(m_lightData[device][0])),
numLeds * 3
);
}
return true;
}
void SmxDedicabDevice::SetLightByIndex(size_t index, uint8_t value) {
const size_t subpixel = index % 3;
const size_t device = (index / 3);
const size_t numLeds = DEVICE_LED_COUNTS[device];
m_lightDataMutex.lock();
for (size_t i = 0; i < numLeds; i++) {
m_lightData[device][(i * 3) + subpixel] = value;
}
m_lightDataMutex.unlock();
}
void SmxDedicabDevice::Update() {
m_lightDataMutex.lock();
for (int i = 0; i < DEVICE_COUNT; i++) {
const size_t numLeds = DEVICE_LED_COUNTS[i];
SMXWrapper::getInstance().SMX_SetDedicatedCabinetLights(
static_cast<SMXDedicatedCabinetLights>(i),
reinterpret_cast<const char*>(&(m_lightData[i][0])),
numLeds * 3
);
}
m_lightDataMutex.unlock();
}
}