void FCDevice::opcSetGlobalColorCorrection(const OPCSink::Message &msg) { /* * Parse the message as JSON text, and if successful, write new * color correction data to the device. */ // Mutable NUL-terminated copy of the message string std::string text((char*)msg.data + 4, msg.length() - 4); if (mVerbose) { std::clog << "New global color correction settings: " << text << "\n"; } // Parse it in-place rapidjson::Document doc; doc.ParseInsitu<0>(&text[0]); if (doc.HasParseError()) { if (mVerbose) { std::clog << "Parse error in color correction JSON at character " << doc.GetErrorOffset() << ": " << doc.GetParseError() << "\n"; } return; } /* * Successfully parsed the JSON. From here, it's handled identically to * objects that come through the config file. */ writeColorCorrection(doc); }
void FCDevice::opcSysEx(const OPCSink::Message &msg) { if (msg.length() < 4) { if (mVerbose) { std::clog << "SysEx message too short!\n"; } return; } unsigned id = (unsigned(msg.data[0]) << 24) | (unsigned(msg.data[1]) << 16) | (unsigned(msg.data[2]) << 8) | unsigned(msg.data[3]) ; switch (id) { case OPCSink::FCSetGlobalColorCorrection: return opcSetGlobalColorCorrection(msg); case OPCSink::FCSetFirmwareConfiguration: return opcSetFirmwareConfiguration(msg); } // Quietly ignore unhandled SysEx messages. }
void FCDevice::opcMapPixelColors(const OPCSink::Message &msg, const Value &inst) { /* * Parse one JSON mapping instruction, and copy any relevant parts of 'msg' * into our framebuffer. This looks for any mapping instructions that we * recognize: * * [ OPC Channel, First OPC Pixel, First output pixel, pixel count ] */ unsigned msgPixelCount = msg.length() / 3; if (inst.IsArray() && inst.Size() == 4) { // Map a range from an OPC channel to our framebuffer const Value &vChannel = inst[0u]; const Value &vFirstOPC = inst[1]; const Value &vFirstOut = inst[2]; const Value &vCount = inst[3]; if (vChannel.IsUint() && vFirstOPC.IsUint() && vFirstOut.IsUint() && vCount.IsUint()) { unsigned channel = vChannel.GetUint(); unsigned firstOPC = vFirstOPC.GetUint(); unsigned firstOut = vFirstOut.GetUint(); unsigned count = vCount.GetUint(); if (channel != msg.channel) { return; } // Clamping, overflow-safe firstOPC = std::min<unsigned>(firstOPC, msgPixelCount); firstOut = std::min<unsigned>(firstOut, unsigned(NUM_PIXELS)); count = std::min<unsigned>(count, msgPixelCount - firstOPC); count = std::min<unsigned>(count, NUM_PIXELS - firstOut); // Copy pixels const uint8_t *inPtr = msg.data + (firstOPC * 3); unsigned outIndex = firstOut; while (count--) { uint8_t *outPtr = fbPixel(outIndex++); outPtr[0] = inPtr[0]; outPtr[1] = inPtr[1]; outPtr[2] = inPtr[2]; inPtr += 3; } return; } } // Still haven't found a match? if (mVerbose) { std::clog << "Unsupported JSON mapping instruction\n"; } }
void FCDevice::opcSetFirmwareConfiguration(const OPCSink::Message &msg) { /* * Raw firmware configuration packet */ memcpy(mFirmwareConfig.data, msg.data + 4, std::min<size_t>(sizeof mFirmwareConfig.data, msg.length() - 4)); submitTransfer(new Transfer(this, &mFirmwareConfig, sizeof mFirmwareConfig)); if (mVerbose) { std::clog << "New Fadecandy firmware configuration:"; for (unsigned i = 0; i < sizeof mFirmwareConfig.data; i++) { if (!(i & 31)) { std::clog << "\n"; } char hex[4]; sprintf(hex, " %02x", mFirmwareConfig.data[i]); std::clog << hex; } std::clog << "\n"; } }
void FCDevice::opcSetFirmwareConfiguration(const OPCSink::Message &msg) { /* * Raw firmware configuration packet */ memcpy(mFirmwareConfig.data, msg.data + 4, std::min<size_t>(sizeof mFirmwareConfig.data, msg.length() - 4)); writeFirmwareConfiguration(); }