diff --git a/README.md b/README.md index 68af19d..2835631 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,8 @@ AltColor = 1 AltColorPath = # Set to 1 if PUP DMD frame matching should be used, 0 if not. PUPCapture = 1 +# Set to 1 if Serum PUP frame matching should be used, 0 if not. +SerumPUPTriggers = 0 # Overwrite the PUPVideosPath sent by the client and set it to a fixed value. PUPVideosPath = # Set to 1 if PUP DMD frame matching should respect the exact colors, 0 if not. diff --git a/dmdserver.ini b/dmdserver.ini index 6fe33d8..7c6f8af 100644 --- a/dmdserver.ini +++ b/dmdserver.ini @@ -11,6 +11,8 @@ AltColor = 1 AltColorPath = # Set to 1 if PUP DMD frame matching should be used, 0 if not. PUPCapture = 1 +# Set to 1 if Serum PUP frame matching should be used, 0 if not. +SerumPUPTriggers = 0 # Overwrite the PUPVideosPath sent by the client and set it to a fixed value. PUPVideosPath = # Set to 1 if PUP DMD frame matching should respect the exact colors, 0 if not. diff --git a/include/DMDUtil/Config.h b/include/DMDUtil/Config.h index 337a203..39151d8 100644 --- a/include/DMDUtil/Config.h +++ b/include/DMDUtil/Config.h @@ -43,6 +43,8 @@ class DMDUTILAPI Config const char* GetAltColorPath() const { return m_altColorPath.c_str(); } bool IsPUPCapture() const { return m_pupCapture; } void SetPUPCapture(bool pupCapture) { m_pupCapture = pupCapture; } + bool IsSerumPUPTriggers() const { return m_serumPupTriggers; } + void SetSerumPUPTriggers(bool serumPupTriggers) { m_serumPupTriggers = serumPupTriggers; } void SetPUPVideosPath(const char* path) { m_pupVideosPath = path; } const char* GetPUPVideosPath() const { return m_pupVideosPath.c_str(); } bool IsPUPExactColorMatch() const { return m_pupExactColorMatch; } @@ -122,6 +124,7 @@ class DMDUTILAPI Config bool m_altColor; std::string m_altColorPath; bool m_pupCapture; + bool m_serumPupTriggers; std::string m_pupVideosPath; bool m_pupExactColorMatch; int m_framesTimeout; diff --git a/include/DMDUtil/DMD.h b/include/DMDUtil/DMD.h index c000cf8..c954e33 100644 --- a/include/DMDUtil/DMD.h +++ b/include/DMDUtil/DMD.h @@ -230,7 +230,6 @@ class DMDUTILAPI DMD std::thread* m_pSerumThread; std::shared_mutex m_dmdSharedMutex; std::condition_variable_any m_dmdCV; - std::atomic m_dmdFrameReady; std::atomic m_stopFlag; std::atomic m_updateBufferQueuePosition; std::atomic m_pupSceneId; diff --git a/platforms/config.sh b/platforms/config.sh index f0035dd..e6d7aea 100755 --- a/platforms/config.sh +++ b/platforms/config.sh @@ -2,8 +2,8 @@ set -e -LIBZEDMD_SHA=4c8211ac91dfeae3665ebd2530b8d6b9ece8cbc1 -LIBSERUM_SHA=9beac4e47d83ea2384316150c5b131c467d1ef8d +LIBZEDMD_SHA=cb969273720234df2f11f2fd7c81fe375f83cfe2 +LIBSERUM_SHA=0c2e688dca271b2c3e1dc31fe71fc0276d33ffab LIBPUPDMD_SHA=124f45e5ddd59ceb339591de88fcca72f8c54612 if [ -z "${BUILD_TYPE}" ]; then diff --git a/src/Config.cpp b/src/Config.cpp index d116d5f..19c68b8 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -19,6 +19,7 @@ Config::Config() m_altColor = true; m_altColorPath.clear(); m_pupCapture = false; + m_serumPupTriggers = false; m_pupVideosPath.clear(); m_pupExactColorMatch = true; m_framesTimeout = 0; @@ -92,6 +93,15 @@ void Config::parseConfigFile(const char* path) SetPUPCapture(false); } + try + { + SetSerumPUPTriggers(r.Get("DMDServer", "SerumPUPTriggers", false)); + } + catch (const std::exception&) + { + SetSerumPUPTriggers(false); + } + try { SetPUPVideosPath(r.Get("DMDServer", "PUPVideosPath", "").c_str()); diff --git a/src/DMD.cpp b/src/DMD.cpp index ea56c51..ce5358d 100644 --- a/src/DMD.cpp +++ b/src/DMD.cpp @@ -25,12 +25,12 @@ #include "AlphaNumeric.h" #include "FrameUtil.h" #include "Logger.h" +#include "TimeUtils.h" #include "ZeDMD.h" #include "komihash/komihash.h" #include "pupdmd.h" #include "serum-decode.h" #include "serum.h" -#include "TimeUtils.h" #include "sockpp/tcp_connector.h" namespace DMDUtil @@ -150,7 +150,6 @@ DMD::DMD() } m_updateBufferQueuePosition.store(0, std::memory_order_release); m_stopFlag.store(false, std::memory_order_release); - m_dmdFrameReady.store(false, std::memory_order_release); m_updateBuffered = std::make_shared(); m_pAlphaNumeric = new AlphaNumeric(); @@ -477,7 +476,6 @@ void DMD::QueueUpdate(const std::shared_ptr dmdUpdate, bool buffered) memcpy(m_pUpdateBufferQueue[(++updateBufferQueuePosition) % DMDUTIL_FRAME_BUFFER_SIZE], dmdUpdate.get(), sizeof(Update)); m_updateBufferQueuePosition.store(updateBufferQueuePosition, std::memory_order_release); - m_dmdFrameReady.store(true, std::memory_order_release); Log(DMDUtil_LogLevel_DEBUG, "Queued Frame: position=%d, mode=%d, depth=%d", updateBufferQueuePosition, dmdUpdate->mode, dmdUpdate->depth); @@ -745,18 +743,23 @@ uint16_t DMD::GetNextBufferQueuePosition(uint16_t bufferPosition, const uint16_t void DMD::DmdFrameThread() { char name[DMDUTIL_MAX_NAME_SIZE] = {0}; + uint16_t bufferPosition = 0; - (void)m_dmdFrameReady.load(std::memory_order_acquire); (void)m_stopFlag.load(std::memory_order_acquire); while (true) { std::shared_lock sl(m_dmdSharedMutex); - m_dmdCV.wait( - sl, [&]() - { return m_dmdFrameReady.load(std::memory_order_relaxed) || m_stopFlag.load(std::memory_order_relaxed); }); + m_dmdCV.wait(sl, + [&]() + { + return m_stopFlag.load(std::memory_order_relaxed) || + (m_updateBufferQueuePosition.load(std::memory_order_relaxed) != bufferPosition); + }); sl.unlock(); + bufferPosition = m_updateBufferQueuePosition.load(std::memory_order_relaxed); + if (strcmp(m_romName, name) != 0) { strcpy(name, m_romName); @@ -767,10 +770,6 @@ void DMD::DmdFrameThread() std::this_thread::sleep_for(std::chrono::milliseconds(2)); - std::unique_lock ul(m_dmdSharedMutex); - m_dmdFrameReady.store(false, std::memory_order_release); - ul.unlock(); - if (m_stopFlag) { return; @@ -790,7 +789,6 @@ void DMD::ZeDMDThread() uint8_t indexBuffer[256 * 64] = {0}; uint8_t renderBuffer[256 * 64 * 3] = {0}; - (void)m_dmdFrameReady.load(std::memory_order_acquire); (void)m_stopFlag.load(std::memory_order_acquire); Config* const pConfig = Config::GetInstance(); @@ -799,9 +797,12 @@ void DMD::ZeDMDThread() while (true) { std::shared_lock sl(m_dmdSharedMutex); - m_dmdCV.wait( - sl, [&]() - { return m_dmdFrameReady.load(std::memory_order_relaxed) || m_stopFlag.load(std::memory_order_relaxed); }); + m_dmdCV.wait(sl, + [&]() + { + return m_stopFlag.load(std::memory_order_relaxed) || + (m_updateBufferQueuePosition.load(std::memory_order_relaxed) != bufferPosition); + }); sl.unlock(); if (m_stopFlag.load(std::memory_order_acquire)) @@ -933,7 +934,9 @@ void DMD::ZeDMDThread() void DMD::SerumThread() { - if (Config::GetInstance()->IsAltColor()) + Config* const pConfig = Config::GetInstance(); + + if (pConfig->IsAltColor()) { Serum_SetLogCallback(Serum_LogCallback, nullptr); @@ -945,12 +948,11 @@ void DMD::SerumThread() Update* lastDmdUpdate = nullptr; uint8_t flags = 0; - (void)m_dmdFrameReady.load(std::memory_order_acquire); (void)m_stopFlag.load(std::memory_order_acquire); - Config* const pConfig = Config::GetInstance(); bool showNotColorizedFrames = pConfig->IsShowNotColorizedFrames(); bool dumpNotColorizedFrames = pConfig->IsDumpNotColorizedFrames(); + if (pConfig->IsSerumPUPTriggers()) Serum_EnablePupTrigers(); while (true) { @@ -979,9 +981,12 @@ void DMD::SerumThread() if (nextRotation == 0) { std::shared_lock sl(m_dmdSharedMutex); - m_dmdCV.wait( - sl, [&]() - { return m_dmdFrameReady.load(std::memory_order_relaxed) || m_stopFlag.load(std::memory_order_relaxed); }); + m_dmdCV.wait(sl, + [&]() + { + return m_stopFlag.load(std::memory_order_relaxed) || + (m_updateBufferQueuePosition.load(std::memory_order_relaxed) != bufferPosition); + }); sl.unlock(); } @@ -1227,7 +1232,6 @@ void DMD::PixelcadeDMDThread() uint16_t* rgb565Data = new uint16_t[targetLength]; memset(rgb565Data, 0, targetLength * sizeof(uint16_t)); - (void)m_dmdFrameReady.load(std::memory_order_acquire); (void)m_stopFlag.load(std::memory_order_acquire); Config* const pConfig = Config::GetInstance(); @@ -1236,9 +1240,12 @@ void DMD::PixelcadeDMDThread() while (true) { std::shared_lock sl(m_dmdSharedMutex); - m_dmdCV.wait( - sl, [&]() - { return m_dmdFrameReady.load(std::memory_order_relaxed) || m_stopFlag.load(std::memory_order_relaxed); }); + m_dmdCV.wait(sl, + [&]() + { + return m_stopFlag.load(std::memory_order_relaxed) || + (m_updateBufferQueuePosition.load(std::memory_order_relaxed) != bufferPosition); + }); sl.unlock(); if (m_stopFlag.load(std::memory_order_acquire)) { @@ -1411,15 +1418,17 @@ void DMD::LevelDMDThread() uint16_t bufferPosition = 0; uint8_t renderBuffer[256 * 64] = {0}; - (void)m_dmdFrameReady.load(std::memory_order_acquire); (void)m_stopFlag.load(std::memory_order_acquire); while (true) { std::shared_lock sl(m_dmdSharedMutex); - m_dmdCV.wait( - sl, [&]() - { return m_dmdFrameReady.load(std::memory_order_relaxed) || m_stopFlag.load(std::memory_order_relaxed); }); + m_dmdCV.wait(sl, + [&]() + { + return m_stopFlag.load(std::memory_order_relaxed) || + (m_updateBufferQueuePosition.load(std::memory_order_relaxed) != bufferPosition); + }); sl.unlock(); if (m_stopFlag.load(std::memory_order_acquire)) { @@ -1461,7 +1470,6 @@ void DMD::RGB24DMDThread() uint8_t rgb24Data[256 * 64 * 3] = {0}; uint8_t rgb24DataScaled[256 * 64 * 3] = {0}; - (void)m_dmdFrameReady.load(std::memory_order_acquire); (void)m_stopFlag.load(std::memory_order_acquire); Config* const pConfig = Config::GetInstance(); @@ -1470,9 +1478,12 @@ void DMD::RGB24DMDThread() while (true) { std::shared_lock sl(m_dmdSharedMutex); - m_dmdCV.wait( - sl, [&]() - { return m_dmdFrameReady.load(std::memory_order_relaxed) || m_stopFlag.load(std::memory_order_relaxed); }); + m_dmdCV.wait(sl, + [&]() + { + return m_stopFlag.load(std::memory_order_relaxed) || + (m_updateBufferQueuePosition.load(std::memory_order_relaxed) != bufferPosition); + }); sl.unlock(); if (m_stopFlag.load(std::memory_order_acquire)) { @@ -1622,15 +1633,17 @@ void DMD::ConsoleDMDThread() uint16_t bufferPosition = 0; uint8_t renderBuffer[256 * 64] = {0}; - (void)m_dmdFrameReady.load(std::memory_order_acquire); (void)m_stopFlag.load(std::memory_order_acquire); while (true) { std::shared_lock sl(m_dmdSharedMutex); - m_dmdCV.wait( - sl, [&]() - { return m_dmdFrameReady.load(std::memory_order_relaxed) || m_stopFlag.load(std::memory_order_relaxed); }); + m_dmdCV.wait(sl, + [&]() + { + return m_stopFlag.load(std::memory_order_relaxed) || + (m_updateBufferQueuePosition.load(std::memory_order_relaxed) != bufferPosition); + }); sl.unlock(); if (m_stopFlag.load(std::memory_order_acquire)) { @@ -1744,7 +1757,6 @@ void DMD::DumpDMDTxtThread() FILE* f = nullptr; std::unordered_set seenHashes; - (void)m_dmdFrameReady.load(std::memory_order_acquire); (void)m_stopFlag.load(std::memory_order_acquire); Config* const pConfig = Config::GetInstance(); @@ -1754,9 +1766,12 @@ void DMD::DumpDMDTxtThread() while (true) { std::shared_lock sl(m_dmdSharedMutex); - m_dmdCV.wait( - sl, [&]() - { return m_dmdFrameReady.load(std::memory_order_relaxed) || m_stopFlag.load(std::memory_order_relaxed); }); + m_dmdCV.wait(sl, + [&]() + { + return m_stopFlag.load(std::memory_order_relaxed) || + (m_updateBufferQueuePosition.load(std::memory_order_relaxed) != bufferPosition); + }); sl.unlock(); if (m_stopFlag.load(std::memory_order_acquire)) { @@ -1903,15 +1918,17 @@ void DMD::DumpDMDRawThread() std::chrono::steady_clock::time_point start; FILE* f = nullptr; - (void)m_dmdFrameReady.load(std::memory_order_acquire); (void)m_stopFlag.load(std::memory_order_acquire); while (true) { std::shared_lock sl(m_dmdSharedMutex); - m_dmdCV.wait( - sl, [&]() - { return m_dmdFrameReady.load(std::memory_order_relaxed) || m_stopFlag.load(std::memory_order_relaxed); }); + m_dmdCV.wait(sl, + [&]() + { + return m_stopFlag.load(std::memory_order_relaxed) || + (m_updateBufferQueuePosition.load(std::memory_order_relaxed) != bufferPosition); + }); sl.unlock(); if (m_stopFlag.load(std::memory_order_acquire)) { @@ -1978,15 +1995,17 @@ void DMD::PupDMDThread() uint8_t palette[192] = {0}; char name[DMDUTIL_MAX_NAME_SIZE] = {0}; - (void)m_dmdFrameReady.load(std::memory_order_acquire); (void)m_stopFlag.load(std::memory_order_acquire); while (true) { std::shared_lock sl(m_dmdSharedMutex); - m_dmdCV.wait( - sl, [&]() - { return m_dmdFrameReady.load(std::memory_order_relaxed) || m_stopFlag.load(std::memory_order_relaxed); }); + m_dmdCV.wait(sl, + [&]() + { + return m_stopFlag.load(std::memory_order_relaxed) || + (m_updateBufferQueuePosition.load(std::memory_order_relaxed) != bufferPosition); + }); sl.unlock(); if (m_stopFlag.load(std::memory_order_acquire)) {