mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 06:40:42 -07:00
Add support for outputting IIDX tape LED data via spiceapi (#315)
## Link to GitHub Issue, if one exists #41 (partially) ## Description of change This PR adds support for outputting IIDX tape LED data via spiceapi (`iidx_tapeled_get()`). It returns the data as a `dict`, with the key being the LED name and the value being the list of RGB values. You can optionally pass in a variadic list of names to filter the returned data. The new API function is only implemented in Python since I'm not able to test the wrappers in other languages. An example script using the new API is available in this Beef Board PR: https://github.com/HWXLR8/beef-board/pull/133. Demo use case: https://streamable.com/pq5e1e ## Testing Tested in IIDX 32 with custom Beef Board firmware along with a Python script to read and send the tape LED data over USB.
This commit is contained in:
@@ -409,50 +409,27 @@ namespace games::iidx {
|
||||
* 16 - side panel right - 183 bytes - 61 colors
|
||||
*
|
||||
* data is stored in RGB order, 3 bytes per color
|
||||
*
|
||||
* TODO: expose this data via API
|
||||
*/
|
||||
|
||||
// data mapping
|
||||
static struct TapeLedMapping {
|
||||
size_t data_size;
|
||||
int index_r, index_g, index_b;
|
||||
|
||||
TapeLedMapping(size_t data_size, int index_r, int index_g, int index_b)
|
||||
: data_size(data_size), index_r(index_r), index_g(index_g), index_b(index_b) {}
|
||||
|
||||
} mapping[] = {
|
||||
{ 19, Lights::StageLeftAvgR, Lights::StageLeftAvgG, Lights::StageLeftAvgB },
|
||||
{ 19, Lights::StageRightAvgR, Lights::StageRightAvgG, Lights::StageRightAvgB },
|
||||
{ 45, Lights::CabinetLeftAvgR, Lights::CabinetLeftAvgG, Lights::CabinetLeftAvgB },
|
||||
{ 45, Lights::CabinetRightAvgR, Lights::CabinetRightAvgG, Lights::CabinetRightAvgB },
|
||||
{ 21, Lights::ControlPanelUnderAvgR, Lights::ControlPanelUnderAvgG, Lights::ControlPanelUnderAvgB },
|
||||
{ 54, Lights::CeilingLeftAvgR, Lights::CeilingLeftAvgG, Lights::CeilingLeftAvgB },
|
||||
{ 11, Lights::TitleLeftAvgR, Lights::TitleLeftAvgG, Lights::TitleLeftAvgB },
|
||||
{ 11, Lights::TitleRightAvgR, Lights::TitleRightAvgG, Lights::TitleRightAvgB },
|
||||
{ 54, Lights::CeilingRightAvgR, Lights::CeilingRightAvgG, Lights::CeilingRightAvgB },
|
||||
{ 17, Lights::TouchPanelLeftAvgR, Lights::TouchPanelLeftAvgG, Lights::TouchPanelLeftAvgB },
|
||||
{ 17, Lights::TouchPanelRightAvgR, Lights::TouchPanelRightAvgG, Lights::TouchPanelRightAvgB },
|
||||
{ 68, Lights::SidePanelLeftInnerAvgR, Lights::SidePanelLeftInnerAvgG, Lights::SidePanelLeftInnerAvgB },
|
||||
{ 68, Lights::SidePanelLeftOuterAvgR, Lights::SidePanelLeftOuterAvgG, Lights::SidePanelLeftOuterAvgB },
|
||||
{ 61, Lights::SidePanelLeftAvgR, Lights::SidePanelLeftAvgG, Lights::SidePanelLeftAvgB },
|
||||
{ 68, Lights::SidePanelRightOuterAvgR, Lights::SidePanelRightOuterAvgG, Lights::SidePanelRightOuterAvgB },
|
||||
{ 68, Lights::SidePanelRightInnerAvgR, Lights::SidePanelRightInnerAvgG, Lights::SidePanelRightInnerAvgB },
|
||||
{ 61, Lights::SidePanelRightAvgR, Lights::SidePanelRightAvgG, Lights::SidePanelRightAvgB },
|
||||
};
|
||||
|
||||
// check index bounds
|
||||
if (tapeledutils::is_enabled() && index < std::size(mapping)) {
|
||||
auto &map = mapping[index];
|
||||
if (tapeledutils::is_enabled() && index < std::size(TAPELED_MAPPING)) {
|
||||
auto &map = TAPELED_MAPPING[index];
|
||||
const auto data_size = map.data.capacity();
|
||||
|
||||
// pick a color to use
|
||||
const auto rgb = tapeledutils::pick_color_from_led_tape(data, map.data_size);
|
||||
const auto rgb = tapeledutils::pick_color_from_led_tape(data, data_size);
|
||||
|
||||
// program the lights into API
|
||||
auto &lights = get_lights();
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[map.index_r], rgb.r);
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[map.index_g], rgb.g);
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[map.index_b], rgb.b);
|
||||
|
||||
for (unsigned int i = 0; i < data_size; ++i) {
|
||||
map.data[i].r = data[i * 3];
|
||||
map.data[i].g = data[i * 3 + 1];
|
||||
map.data[i].b = data[i * 3 + 2];
|
||||
}
|
||||
}
|
||||
|
||||
if (This != custom_node) {
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "util/sigscan.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
#include "external/robin_hood.h"
|
||||
|
||||
#include "bi2a.h"
|
||||
#include "bi2x_hook.h"
|
||||
#include "ezusb.h"
|
||||
@@ -74,6 +76,26 @@ namespace games::iidx {
|
||||
bool IIDXIO_LED_TICKER_READONLY = false;
|
||||
std::mutex IIDX_LED_TICKER_LOCK;
|
||||
|
||||
tapeledutils::tape_led TAPELED_MAPPING[IIDX_TAPELED_TOTAL] = {
|
||||
{ 19, Lights::StageLeftAvgR, Lights::StageLeftAvgG, Lights::StageLeftAvgB, "Stage Left" },
|
||||
{ 19, Lights::StageRightAvgR, Lights::StageRightAvgG, Lights::StageRightAvgB, "Stage Right" },
|
||||
{ 45, Lights::CabinetLeftAvgR, Lights::CabinetLeftAvgG, Lights::CabinetLeftAvgB, "Cabinet Left" },
|
||||
{ 45, Lights::CabinetRightAvgR, Lights::CabinetRightAvgG, Lights::CabinetRightAvgB, "Cabinet Right" },
|
||||
{ 21, Lights::ControlPanelUnderAvgR, Lights::ControlPanelUnderAvgG, Lights::ControlPanelUnderAvgB, "Control Panel Under" },
|
||||
{ 54, Lights::CeilingLeftAvgR, Lights::CeilingLeftAvgG, Lights::CeilingLeftAvgB, "Ceiling Left" },
|
||||
{ 11, Lights::TitleLeftAvgR, Lights::TitleLeftAvgG, Lights::TitleLeftAvgB, "Title Left" },
|
||||
{ 11, Lights::TitleRightAvgR, Lights::TitleRightAvgG, Lights::TitleRightAvgB, "Title Right" },
|
||||
{ 54, Lights::CeilingRightAvgR, Lights::CeilingRightAvgG, Lights::CeilingRightAvgB, "Ceiling Right" },
|
||||
{ 17, Lights::TouchPanelLeftAvgR, Lights::TouchPanelLeftAvgG, Lights::TouchPanelLeftAvgB, "Touch Panel Left" },
|
||||
{ 17, Lights::TouchPanelRightAvgR, Lights::TouchPanelRightAvgG, Lights::TouchPanelRightAvgB, "Touch Panel Right" },
|
||||
{ 68, Lights::SidePanelLeftInnerAvgR, Lights::SidePanelLeftInnerAvgG, Lights::SidePanelLeftInnerAvgB, "Side Panel Left Inner" },
|
||||
{ 68, Lights::SidePanelLeftOuterAvgR, Lights::SidePanelLeftOuterAvgG, Lights::SidePanelLeftOuterAvgB, "Side Panel Left Outer" },
|
||||
{ 61, Lights::SidePanelLeftAvgR, Lights::SidePanelLeftAvgG, Lights::SidePanelLeftAvgB, "Side Panel Left" },
|
||||
{ 68, Lights::SidePanelRightOuterAvgR, Lights::SidePanelRightOuterAvgG, Lights::SidePanelRightOuterAvgB, "Side Panel Right Outer" },
|
||||
{ 68, Lights::SidePanelRightInnerAvgR, Lights::SidePanelRightInnerAvgG, Lights::SidePanelRightInnerAvgB, "Side Panel Right Inner" },
|
||||
{ 61, Lights::SidePanelRightAvgR, Lights::SidePanelRightAvgG, Lights::SidePanelRightAvgB, "Side Panel Right" },
|
||||
};
|
||||
|
||||
static LONG WINAPI RegOpenKeyA_hook(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult) {
|
||||
if (lpSubKey != nullptr && phkResult != nullptr) {
|
||||
if (hKey == HKEY_LOCAL_MACHINE &&
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "games/game.h"
|
||||
|
||||
#include "external/robin_hood.h"
|
||||
#include "util/tapeled.h"
|
||||
|
||||
namespace games::iidx {
|
||||
|
||||
// settings
|
||||
@@ -30,6 +34,10 @@ namespace games::iidx {
|
||||
extern bool IIDXIO_LED_TICKER_READONLY;
|
||||
extern std::mutex IIDX_LED_TICKER_LOCK;
|
||||
|
||||
constexpr int IIDX_TAPELED_TOTAL = 17;
|
||||
// data mapping
|
||||
extern tapeledutils::tape_led TAPELED_MAPPING[IIDX_TAPELED_TOTAL];
|
||||
|
||||
class IIDXGame : public games::Game {
|
||||
public:
|
||||
IIDXGame();
|
||||
|
||||
Reference in New Issue
Block a user