Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: Add new VirtualDMD class and replace RGB32 with RGB24
Browse files Browse the repository at this point in the history
jsm174 committed Feb 1, 2024
1 parent 4877111 commit 8045990
Showing 10 changed files with 278 additions and 145 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/libdmdutil.yml
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ jobs:
- uses: actions/checkout@v4
- if: (matrix.platform == 'win')
name: Add msbuild to path (win runner)
uses: microsoft/setup-msbuild@v1.1
uses: microsoft/setup-msbuild@v2
- if: (matrix.platform == 'macos')
name: Add autoconf and automake (mac runner)
run: |
@@ -164,7 +164,7 @@ jobs:
fi
echo "artifact_path=${ARTIFACT_PATH}" >> $GITHUB_OUTPUT
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: libdmdutil-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}
path: ${{ steps.artifacts.outputs.artifact_path }}
@@ -174,7 +174,7 @@ jobs:
needs: [ version, build ]
name: Build libdmdutil-macos
steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
- name: Unpack artifacts
run: |
cd libdmdutil-${{ needs.version.outputs.tag }}-macos-x64
@@ -208,7 +208,7 @@ jobs:
cd tmp
tar -czvf ../libdmdutil-${{ needs.version.outputs.tag }}-macos.tar.gz *
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: libdmdutil-${{ needs.version.outputs.tag }}-macos
path: libdmdutil-${{ needs.version.outputs.tag }}-macos.tar.gz
126 changes: 68 additions & 58 deletions CMakeLists.txt

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -15,18 +15,25 @@ void setup()
DMDUtil::Config* pConfig = DMDUtil::Config::GetInstance();
pConfig->SetZeDMD(true);
pConfig->SetZeDMDDevice("/dev/cu.usbserial-0001");
pConfig->SetPixelcade(false);
pConfig->SetPixelcadeDMD(false);
}
void test()
{
uint8_t* pData = (uint8_t*)malloc(128 * 32);
DMDUtil::DMD* pDmd = new DMDUtil::DMD(128, 32, false, "t2_l8");
DMDUtil::VirtualDMD* pVirtualDMD = pDmd->CreateVirtualDMD();
uint8_t* pData = (uint8_t*)malloc(128 * 32);
.
.
.
pDmd->UpdateData((const UINT8*)pData, 2, 255, 0, 0);
uint32_t* pRGB32Data = pDmd->GetRGB32Data();
uint8_t* pRGB24Data = pVirtualDMD->GetRGB24Data();
if (pRGB24Data) {
// Render pRGB24Data
}
}
```

18 changes: 8 additions & 10 deletions include/DMDUtil/DMD.h
Original file line number Diff line number Diff line change
@@ -46,7 +46,8 @@ enum class AlphaNumericLayout

class AlphaNumeric;
class Serum;
class Pixelcade;
class PixelcadeDMD;
class VirtualDMD;

class DMDUTILAPI DMD
{
@@ -59,14 +60,11 @@ class DMDUTILAPI DMD
int GetWidth() const { return m_width; }
int GetHeight() const { return m_height; }
int GetLength() const { return m_length; }
bool IsUpdated() const { return m_updated; }
void ResetUpdated() { m_updated = false; }
VirtualDMD* CreateVirtualDMD();
void UpdateData(const uint8_t* pData, int depth, uint8_t r, uint8_t g, uint8_t b);
void UpdateRGB24Data(const uint8_t* pData, int depth, uint8_t r, uint8_t g, uint8_t b);
void UpdateAlphaNumericData(AlphaNumericLayout layout, const uint16_t* pData1, const uint16_t* pData2, uint8_t r,
uint8_t g, uint8_t b);
const uint8_t* GetLevelData() const { return m_pLevelData; }
const uint32_t* GetRGB32Data() const { return m_pRGB32Data; }

private:
enum class DmdMode
@@ -107,12 +105,12 @@ class DMDUTILAPI DMD
int m_height;
int m_length;
bool m_sam;
uint8_t* m_pData;
uint8_t* m_pRGB24Data;
uint8_t* m_pBuffer;
uint8_t* m_pRGB24Buffer;
uint16_t m_segData1[128];
uint16_t m_segData2[128];
uint8_t* m_pLevelData;
uint32_t* m_pRGB32Data;
uint8_t* m_pRGB24Data;
uint16_t* m_pRGB565Data;
uint8_t m_palette[192];
AlphaNumeric* m_pAlphaNumeric;
@@ -121,9 +119,9 @@ class DMDUTILAPI DMD
#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
Pixelcade* m_pPixelcade;
PixelcadeDMD* m_pPixelcadeDMD;
#endif
bool m_updated;
std::vector<VirtualDMD*> m_virtualDMDs;

std::thread* m_pThread;
std::queue<DMDUpdate*> m_updates;
5 changes: 3 additions & 2 deletions include/DMDUtil/DMDUtil.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#define DMDUTIL_VERSION_MAJOR 0 // X Digits
#define DMDUTIL_VERSION_MINOR 1 // Max 2 Digits
#define DMDUTIL_VERSION_MINOR 2 // Max 2 Digits
#define DMDUTIL_VERSION_PATCH 0 // Max 2 Digits

#define _DMDUTIL_STR(x) #x
@@ -12,4 +12,5 @@
#define DMDUTIL_MINOR_VERSION DMDUTIL_STR(DMDUTIL_VERSION_MAJOR) "." DMDUTIL_STR(DMDUTIL_VERSION_MINOR)

#include "Config.h"
#include "DMD.h"
#include "DMD.h"
#include "VirtualDMD.h"
41 changes: 41 additions & 0 deletions include/DMDUtil/VirtualDMD.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#ifdef _MSC_VER
#define DMDUTILAPI __declspec(dllexport)
#define DMDUTILCALLBACK __stdcall
#else
#define DMDUTILAPI __attribute__((visibility("default")))
#define DMDUTILCALLBACK
#endif

#include <cstdint>

namespace DMDUtil
{

class DMDUTILAPI VirtualDMD
{
public:
VirtualDMD(int width, int height);
~VirtualDMD();

void Update(uint8_t* pLevelData, uint8_t* pRGB24Data);
int GetWidth() { return m_width; }
int GetHeight() { return m_height; }
int GetLength() const { return m_length; }
int GetPitch() const { return m_pitch; }
uint8_t* GetLevelData();
uint8_t* GetRGB24Data();

private:
int m_width;
int m_height;
int m_length;
int m_pitch;
int m_update;

uint8_t* m_pLevelData;
uint8_t* m_pRGB24Data;
};

} // namespace DMDUtil
102 changes: 61 additions & 41 deletions src/DMD.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#include "DMDUtil/DMD.h"

#include "DMDUtil/Config.h"
#include "DMDUtil/VirtualDMD.h"

#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
#include "Pixelcade.h"
#include "PixelcadeDMD.h"
#endif
#include <cstring>

@@ -34,16 +35,16 @@ DMD::DMD(int width, int height, bool sam, const char* name)
m_height = height;
m_length = width * height;
m_sam = sam;
m_pData = (uint8_t*)malloc(m_length);
memset(m_pData, 0, m_length);
m_pRGB24Data = (uint8_t*)malloc(m_length * 3);
memset(m_pRGB24Data, 0, m_length * 3);
m_pBuffer = (uint8_t*)malloc(m_length);
memset(m_pBuffer, 0, m_length);
m_pRGB24Buffer = (uint8_t*)malloc(m_length * 3);
memset(m_pRGB24Buffer, 0, m_length * 3);
memset(m_segData1, 0, 128 * sizeof(uint16_t));
memset(m_segData2, 0, 128 * sizeof(uint16_t));
m_pLevelData = (uint8_t*)malloc(m_length);
memset(m_pLevelData, 0, m_length);
m_pRGB32Data = (uint32_t*)malloc(m_length * sizeof(uint32_t));
memset(m_pRGB32Data, 0, m_length * sizeof(uint32_t));
m_pRGB24Data = (uint8_t*)malloc(m_length * 3);
memset(m_pRGB24Data, 0, m_length * 3);
m_pRGB565Data = (uint16_t*)malloc(m_length * sizeof(uint16_t));
memset(m_pRGB565Data, 0, m_length * sizeof(uint16_t));
memset(m_palette, 0, 192);
@@ -53,11 +54,10 @@ DMD::DMD(int width, int height, bool sam, const char* name)
#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
m_pPixelcade = nullptr;
m_pPixelcadeDMD = nullptr;
#endif
m_pThread = nullptr;
m_running = false;
m_updated = false;

FindDevices();

@@ -84,19 +84,21 @@ DMD::~DMD()
delete pUpdate;
}

free(m_pData);
free(m_pRGB24Data);
free(m_pBuffer);
free(m_pRGB24Buffer);
free(m_pLevelData);
free(m_pRGB32Data);
free(m_pRGB24Data);
free(m_pRGB565Data);
delete m_pAlphaNumeric;
delete m_pSerum;
delete m_pZeDMD;
#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
delete m_pPixelcade;
delete m_pPixelcadeDMD;
#endif

for (VirtualDMD* pVirtualDMD : m_virtualDMDs) delete pVirtualDMD;
}

bool DMD::IsFinding() { return m_finding; }
@@ -106,12 +108,19 @@ bool DMD::HasDisplay() const
#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
return (m_pZeDMD != nullptr) || (m_pPixelcade != nullptr);
return (m_pZeDMD != nullptr) || (m_pPixelcadeDMD != nullptr);
#else
return (m_pZeDMD != nullptr);
#endif
}

VirtualDMD* DMD::CreateVirtualDMD()
{
VirtualDMD* const pVirtualDMD = new VirtualDMD(m_width, m_height);
m_virtualDMDs.push_back(pVirtualDMD);
return pVirtualDMD;
}

void DMD::UpdateData(const uint8_t* pData, int depth, uint8_t r, uint8_t g, uint8_t b)
{
DMDUpdate* const pUpdate = new DMDUpdate();
@@ -192,7 +201,7 @@ void DMD::FindDevices()
#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
Pixelcade* pPixelcade = nullptr;
PixelcadeDMD* pPixelcadeDMD = nullptr;
#endif

Config* const pConfig = Config::GetInstance();
@@ -224,14 +233,15 @@ void DMD::FindDevices()
#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
if (pConfig->IsPixelcade()) pPixelcade = Pixelcade::Connect(pConfig->GetPixelcadeDevice(), m_width, m_height);
if (pConfig->IsPixelcade())
pPixelcadeDMD = PixelcadeDMD::Connect(pConfig->GetPixelcadeDevice(), m_width, m_height);
#endif

m_pZeDMD = pZeDMD;
#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
m_pPixelcade = pPixelcade;
m_pPixelcadeDMD = pPixelcadeDMD;
#endif

m_finding = false;
@@ -342,16 +352,16 @@ void DMD::UpdateData(const DMDUpdate* pUpdate, bool update)
{
if (pData)
{
if (memcmp(m_pData, pData, m_length) != 0)
if (memcmp(m_pBuffer, pData, m_length) != 0)
{
memcpy(m_pData, pData, m_length);
memcpy(m_pBuffer, pData, m_length);
update = true;
}
}

if (UpdatePalette(pUpdate)) update = true;
}
else if (m_pSerum->Convert(pData, m_pData, m_palette))
else if (m_pSerum->Convert(pData, m_pBuffer, m_palette))
{
// if we have serum, run a conversion, and if success, we have an update (needed for rotations)
// serum will take care of updating the data buffer
@@ -362,12 +372,16 @@ void DMD::UpdateData(const DMDUpdate* pUpdate, bool update)

for (int i = 0; i < m_length; i++)
{
int pos = m_pData[i] * 3;
int pos = m_pBuffer[i] * 3;
uint32_t r = m_palette[pos];
uint32_t g = m_palette[pos + 1];
uint32_t b = m_palette[pos + 2];

m_pRGB32Data[i] = r | g << 8 | b << 16 | 0xFFu << 24;
pos = i * 3;
m_pRGB24Data[pos] = r;
m_pRGB24Data[pos + 1] = g;
m_pRGB24Data[pos + 2] = b;

m_pRGB565Data[i] = (uint16_t)(((r & 0xF8u) << 8) | ((g & 0xFCu) << 3) | (b >> 3));
}

@@ -376,30 +390,30 @@ void DMD::UpdateData(const DMDUpdate* pUpdate, bool update)
if (m_pSerum)
{
m_pZeDMD->SetPalette(m_palette, 64);
m_pZeDMD->RenderColoredGray6(m_pData, nullptr);
m_pZeDMD->RenderColoredGray6(m_pBuffer, nullptr);
}
else
{
if (pUpdate->depth == 2)
{
m_pZeDMD->SetPalette(m_palette, 4);
m_pZeDMD->RenderGray2(m_pData);
m_pZeDMD->RenderGray2(m_pBuffer);
}
else
{
m_pZeDMD->SetPalette(m_palette, 16);
m_pZeDMD->RenderGray4(m_pData);
m_pZeDMD->RenderGray4(m_pBuffer);
}
}
}

#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
if (m_pPixelcade) m_pPixelcade->Update(m_pRGB565Data);
if (m_pPixelcadeDMD) m_pPixelcadeDMD->Update(m_pRGB565Data);
#endif

m_updated = true;
for (VirtualDMD* pVirtualDMD : m_virtualDMDs) pVirtualDMD->Update(m_pLevelData, m_pRGB24Data);
}

void DMD::UpdateRGB24Data(const DMDUpdate* pUpdate, bool update)
@@ -411,18 +425,18 @@ void DMD::UpdateRGB24Data(const DMDUpdate* pUpdate, bool update)
if (UpdatePalette(pUpdate)) update = true;
}

if (memcmp(m_pRGB24Data, pData, m_length * 3) != 0) update = true;
if (memcmp(m_pRGB24Buffer, pData, m_length * 3) != 0) update = true;

if (!update) return;

memcpy(m_pRGB24Data, pData, m_length * 3);
memcpy(m_pRGB24Buffer, pData, m_length * 3);

int pos = 0;
for (int i = 0; i < m_length; i++)
{
uint32_t r = m_pRGB24Data[pos++];
uint32_t g = m_pRGB24Data[pos++];
uint32_t b = m_pRGB24Data[pos++];
int pos = i * 3;
uint32_t r = m_pRGB24Buffer[pos];
uint32_t g = m_pRGB24Buffer[pos + 1];
uint32_t b = m_pRGB24Buffer[pos + 2];

if (pUpdate->depth != 24)
{
@@ -438,13 +452,15 @@ void DMD::UpdateRGB24Data(const DMDUpdate* pUpdate, bool update)
m_pLevelData[i] = level;

int pos2 = level * 3;

r = m_palette[pos2];
g = m_palette[pos2 + 1];
b = m_palette[pos2 + 2];
}

m_pRGB32Data[i] = r | g << 8 | b << 16 | 0xFFu << 24;
m_pRGB24Data[pos] = (uint8_t)r;
m_pRGB24Data[pos + 1] = (uint8_t)g;
m_pRGB24Data[pos + 2] = (uint8_t)b;

m_pRGB565Data[i] = (uint16_t)(((r & 0xF8u) << 8) | ((g & 0xFCu) << 3) | (b >> 3));
}

@@ -466,16 +482,16 @@ void DMD::UpdateRGB24Data(const DMDUpdate* pUpdate, bool update)
}
else if (pUpdate->depth == 24)
{
if (m_pZeDMD) m_pZeDMD->RenderRgb24((uint8_t*)m_pRGB24Data);
if (m_pZeDMD) m_pZeDMD->RenderRgb24((uint8_t*)m_pRGB24Buffer);
}

#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
if (m_pPixelcade) m_pPixelcade->Update(m_pRGB565Data);
if (m_pPixelcadeDMD) m_pPixelcadeDMD->Update(m_pRGB565Data);
#endif

m_updated = true;
for (VirtualDMD* pVirtualDMD : m_virtualDMDs) pVirtualDMD->Update(m_pLevelData, m_pRGB24Data);
}

void DMD::UpdateAlphaNumericData(const DMDUpdate* pUpdate, bool update)
@@ -512,7 +528,11 @@ void DMD::UpdateAlphaNumericData(const DMDUpdate* pUpdate, bool update)
uint32_t g = m_palette[pos + 1];
uint32_t b = m_palette[pos + 2];

m_pRGB32Data[i] = r | g << 8 | b << 16 | 0xFFu << 24;
pos = i * 3;
m_pRGB24Data[pos] = (uint8_t)r;
m_pRGB24Data[pos + 1] = (uint8_t)g;
m_pRGB24Data[pos + 2] = (uint8_t)b;

m_pRGB565Data[i] = (uint16_t)(((r & 0xF8u) << 8) | ((g & 0xFCu) << 3) | (b >> 3));
}

@@ -525,10 +545,10 @@ void DMD::UpdateAlphaNumericData(const DMDUpdate* pUpdate, bool update)
#if !( \
(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \
defined(__ANDROID__))
if (m_pPixelcade) m_pPixelcade->Update(m_pRGB565Data);
if (m_pPixelcadeDMD) m_pPixelcadeDMD->Update(m_pRGB565Data);
#endif

m_updated = true;
for (VirtualDMD* pVirtualDMD : m_virtualDMDs) pVirtualDMD->Update(m_pLevelData, m_pRGB24Data);
}

} // namespace DMDUtil
44 changes: 22 additions & 22 deletions src/Pixelcade.cpp → src/PixelcadeDMD.cpp
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* https://github.com/freezy/dmd-extensions/blob/master/LibDmd/Output/Pixelcade/Pixelcade.cs
*/

#include "Pixelcade.h"
#include "PixelcadeDMD.h"

#include <chrono>
#include <cstring>
@@ -16,7 +16,7 @@
namespace DMDUtil
{

Pixelcade::Pixelcade(struct sp_port* pSerialPort, int width, int height)
PixelcadeDMD::PixelcadeDMD(struct sp_port* pSerialPort, int width, int height)
{
m_pSerialPort = pSerialPort;
m_width = width;
@@ -28,7 +28,7 @@ Pixelcade::Pixelcade(struct sp_port* pSerialPort, int width, int height)
Run();
}

Pixelcade::~Pixelcade()
PixelcadeDMD::~PixelcadeDMD()
{
if (m_pThread)
{
@@ -46,41 +46,41 @@ Pixelcade::~Pixelcade()
}
}

Pixelcade* Pixelcade::Connect(const char* pDevice, int width, int height)
PixelcadeDMD* PixelcadeDMD::Connect(const char* pDevice, int width, int height)
{
Pixelcade* pPixelcade = nullptr;
PixelcadeDMD* pPixelcadeDMD = nullptr;

if (pDevice && *pDevice != 0)
{
Log("Connecting to Pixelcade on %s...", pDevice);
Log("Connecting to PixelcadeDMD on %s...", pDevice);

pPixelcade = Open(pDevice, width, height);
pPixelcadeDMD = Open(pDevice, width, height);

if (!pPixelcade) Log("Unable to connect to Pixelcade on %s", pDevice);
if (!pPixelcadeDMD) Log("Unable to connect to PixelcadeDMD on %s", pDevice);
}
else
{
Log("Searching for Pixelcade...");
Log("Searching for PixelcadeDMD...");

struct sp_port** ppPorts;
enum sp_return result = sp_list_ports(&ppPorts);
if (result == SP_OK)
{
for (int i = 0; ppPorts[i]; i++)
{
pPixelcade = Open(sp_get_port_name(ppPorts[i]), width, height);
if (pPixelcade) break;
pPixelcadeDMD = Open(sp_get_port_name(ppPorts[i]), width, height);
if (pPixelcadeDMD) break;
}
sp_free_port_list(ppPorts);
}

if (!pPixelcade) Log("Unable to find Pixelcade");
if (!pPixelcadeDMD) Log("Unable to find PixelcadeDMD");
}

return pPixelcade;
return pPixelcadeDMD;
}

Pixelcade* Pixelcade::Open(const char* pDevice, int width, int height)
PixelcadeDMD* PixelcadeDMD::Open(const char* pDevice, int width, int height)
{
struct sp_port* pSerialPort = nullptr;
enum sp_return result = sp_get_port_by_name(pDevice, &pSerialPort);
@@ -115,15 +115,15 @@ Pixelcade* Pixelcade::Open(const char* pDevice, int width, int height)
{
sp_close(pSerialPort);
sp_free_port(pSerialPort);
// Log("Pixelcade: expected new connection to return 0x0, but got 0x%02d", response[0]);
// Log("Pixelcade expected new connection to return 0x0, but got 0x%02d", response[0]);
return nullptr;
}

if (response[1] != 'I' || response[2] != 'O' || response[3] != 'I' || response[4] != 'O')
{
sp_close(pSerialPort);
sp_free_port(pSerialPort);
// Log("Pixelcade: expected magic code to equal IOIO but got %c%c%c%c", response[1], response[2], response[3],
// Log("Pixelcade expected magic code to equal IOIO but got %c%c%c%c", response[1], response[2], response[3],
// response[4]);
return nullptr;
}
@@ -140,10 +140,10 @@ Pixelcade* Pixelcade::Open(const char* pDevice, int width, int height)
Log("Pixelcade found: device=%s, Hardware ID=%s, Bootloader ID=%s, Firmware=%s", pDevice, hardwareId, bootloaderId,
firmware);

return new Pixelcade(pSerialPort, width, height);
return new PixelcadeDMD(pSerialPort, width, height);
}

void Pixelcade::Update(uint16_t* pData)
void PixelcadeDMD::Update(uint16_t* pData)
{
uint16_t* pFrame = (uint16_t*)malloc(m_length * sizeof(uint16_t));
memcpy(pFrame, pData, m_length * sizeof(uint16_t));
@@ -154,14 +154,14 @@ void Pixelcade::Update(uint16_t* pData)
}
}

void Pixelcade::EnableRgbLedMatrix(int shifterLen32, int rows)
void PixelcadeDMD::EnableRgbLedMatrix(int shifterLen32, int rows)
{
uint8_t data[2] = {PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE,
(uint8_t)((shifterLen32 & 0x0F) | ((rows == 8 ? 0 : 1) << 4))};
sp_blocking_write(m_pSerialPort, data, 2, 0);
}

void Pixelcade::Run()
void PixelcadeDMD::Run()
{
if (m_running) return;

@@ -170,7 +170,7 @@ void Pixelcade::Run()
m_pThread = new std::thread(
[this]()
{
Log("Pixelcade run thread starting");
Log("PixelcadeDMD run thread starting");
EnableRgbLedMatrix(4, 16);

int errors = 0;
@@ -255,7 +255,7 @@ void Pixelcade::Run()

m_pSerialPort = nullptr;

Log("Pixelcade run thread finished");
Log("PixelcadeDMD run thread finished");
});
}

10 changes: 5 additions & 5 deletions src/Pixelcade.h → src/PixelcadeDMD.h
Original file line number Diff line number Diff line change
@@ -24,17 +24,17 @@
namespace DMDUtil
{

class Pixelcade
class PixelcadeDMD
{
public:
Pixelcade(struct sp_port* pSerialPort, int width, int height);
~Pixelcade();
PixelcadeDMD(struct sp_port* pSerialPort, int width, int height);
~PixelcadeDMD();

static Pixelcade* Connect(const char* pDevice, int width, int height);
static PixelcadeDMD* Connect(const char* pDevice, int width, int height);
void Update(uint16_t* pData);

private:
static Pixelcade* Open(const char* pDevice, int width, int height);
static PixelcadeDMD* Open(const char* pDevice, int width, int height);
void Run();
void EnableRgbLedMatrix(int shifterLen32, int rows);

56 changes: 56 additions & 0 deletions src/VirtualDMD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "DMDUtil/VirtualDMD.h"

#include <cstdint>
#include <cstring>
#include <string>

namespace DMDUtil
{

VirtualDMD::VirtualDMD(int width, int height)
{
m_width = width;
m_height = height;
m_length = width * height;
m_pitch = width * 3;

m_pLevelData = (uint8_t*)malloc(m_length);
memset(m_pLevelData, 0, m_length);

m_pRGB24Data = (uint8_t*)malloc(m_length * 3);
memset(m_pRGB24Data, 0, m_length * 3);

m_update = false;
}

VirtualDMD::~VirtualDMD()
{
free(m_pLevelData);
free(m_pRGB24Data);
}

void VirtualDMD::Update(uint8_t* pLevelData, uint8_t* pRGB24Data)
{
memcpy(m_pLevelData, pLevelData, m_length);
memcpy(m_pRGB24Data, pRGB24Data, m_length * 3);

m_update = true;
}

uint8_t* VirtualDMD::GetLevelData()
{
if (!m_update) return nullptr;

m_update = false;
return m_pLevelData;
}

uint8_t* VirtualDMD::GetRGB24Data()
{
if (!m_update) return nullptr;

m_update = false;
return m_pRGB24Data;
}

} // namespace DMDUtil

0 comments on commit 8045990

Please sign in to comment.