@@ -878,11 +878,14 @@ void DMD::SerumThread()
878878 int sceneCurrentFrame = 0 ;
879879 int sceneDurationPerFrame = 0 ;
880880 bool sceneInterruptable = false ;
881+ bool sceneStartImmediately = false ;
882+ int sceneRepeatCount = 0 ;
883+ int sceneEndFrame = 0 ;
881884 uint32_t nextSceneFrame = 0 ;
882885
883886 while (true )
884887 {
885- if (nextRotation == 0 && sceneCurrentFrame >= sceneFrameCount)
888+ if (nextRotation == 0 && sceneCurrentFrame > sceneFrameCount)
886889 {
887890 std::shared_lock<std::shared_mutex> sl (m_dmdSharedMutex);
888891 m_dmdCV.wait (
@@ -909,28 +912,59 @@ void DMD::SerumThread()
909912 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ())
910913 .count ();
911914
912- if (!m_stopFlag.load (std::memory_order_relaxed) && sceneCurrentFrame < sceneFrameCount && nextSceneFrame <= now)
915+ if (!m_stopFlag.load (std::memory_order_relaxed) && sceneCurrentFrame <= sceneFrameCount && nextSceneFrame <= now)
913916 {
914- Update* sceneUpdate = new Update ();
915- sceneUpdate->mode = Mode::Data;
916- sceneUpdate->depth = 2 ;
917- sceneUpdate->width = 128 ;
918- sceneUpdate->height = 32 ;
919- sceneUpdate->hasData = true ;
920- sceneUpdate->r = 0 ;
921- sceneUpdate->g = 0 ;
922- sceneUpdate->b = 0 ;
923- if (generator.generateFrame (prevTriggerId, sceneCurrentFrame++, sceneUpdate->data ))
917+ if (sceneCurrentFrame >= sceneFrameCount)
924918 {
925- uint32_t result = Serum_Colorize (sceneUpdate->data );
926-
927- if (result != IDENTIFY_NO_FRAME)
919+ // The scene is finished.
920+ if (sceneRepeatCount > 0 )
921+ {
922+ sceneCurrentFrame = 0 ;
923+ sceneRepeatCount--;
924+ }
925+ else
926+ {
927+ sceneFrameCount = 0 ;
928+ if (lastDmdUpdate && sceneEndFrame >= 0 )
929+ {
930+ uint32_t result = Serum_Colorize (lastDmdUpdate->data );
931+ if (result != IDENTIFY_NO_FRAME)
932+ {
933+ if (sceneEndFrame == 1 )
934+ {
935+ // Black frame.
936+ memset (m_pSerum->palette , 0 , PALETTE_SIZE);
937+ if (m_pSerum->width32 > 0 ) memset (m_pSerum->frame32 , 0 , m_pSerum->width32 * 32 * sizeof (uint16_t ));
938+ if (m_pSerum->width64 > 0 ) memset (m_pSerum->frame64 , 0 , m_pSerum->width64 * 64 * sizeof (uint16_t ));
939+ }
940+ QueueSerumFrames (lastDmdUpdate);
941+ }
942+ }
943+ }
944+ }
945+ else
946+ {
947+ Update* sceneUpdate = new Update ();
948+ sceneUpdate->mode = Mode::Data;
949+ sceneUpdate->depth = 2 ;
950+ sceneUpdate->width = 128 ;
951+ sceneUpdate->height = 32 ;
952+ sceneUpdate->hasData = true ;
953+ sceneUpdate->r = 0 ;
954+ sceneUpdate->g = 0 ;
955+ sceneUpdate->b = 0 ;
956+ if (generator.generateFrame (prevTriggerId, sceneCurrentFrame++, sceneUpdate->data ))
928957 {
929- QueueSerumFrames (sceneUpdate);
958+ uint32_t result = Serum_Colorize (sceneUpdate->data );
959+
960+ if (result != IDENTIFY_NO_FRAME)
961+ {
962+ QueueSerumFrames (sceneUpdate);
963+ }
930964 }
965+ nextSceneFrame = nextSceneFrame + sceneDurationPerFrame;
966+ delete sceneUpdate;
931967 }
932- nextSceneFrame = nextSceneFrame + sceneDurationPerFrame;
933- delete sceneUpdate;
934968 }
935969
936970 const uint8_t updateBufferQueuePosition = m_updateBufferQueuePosition.load (std::memory_order_acquire);
@@ -995,7 +1029,6 @@ void DMD::SerumThread()
9951029 // m_pSerum->rotationtimer, m_pSerum->flags);
9961030
9971031 lastDmdUpdate = m_pUpdateBufferQueue[bufferPosition];
998- QueueSerumFrames (lastDmdUpdate);
9991032
10001033 if (result > 0 && ((result & 0xffff ) < 2048 ))
10011034 nextRotation = now + m_pSerum->rotationtimer ;
@@ -1004,22 +1037,35 @@ void DMD::SerumThread()
10041037
10051038 if (m_pSerum->triggerID < 0xffffffff )
10061039 {
1007- HandleTrigger (m_pSerum->triggerID );
1008-
10091040 if (generator.getSceneInfo (m_pSerum->triggerID , sceneFrameCount, sceneDurationPerFrame,
1010- sceneInterruptable))
1041+ sceneInterruptable, sceneStartImmediately, sceneRepeatCount, sceneEndFrame ))
10111042 {
10121043 Log (DMDUtil_LogLevel_DEBUG, " Serum: trigger ID %lu found in scenes, frame count=%d, duration=%dms" ,
10131044 m_pSerum->triggerID , sceneFrameCount, sceneDurationPerFrame);
10141045 sceneCurrentFrame = 0 ;
1015- nextSceneFrame = now + sceneDurationPerFrame;
1046+ nextSceneFrame = now + (sceneStartImmediately ? 0 : sceneDurationPerFrame);
1047+ if (sceneStartImmediately)
1048+ {
1049+ nextSceneFrame = now;
1050+ }
1051+ else
1052+ {
1053+ nextSceneFrame = now + sceneDurationPerFrame;
1054+ QueueSerumFrames (lastDmdUpdate);
1055+ }
1056+ }
1057+ else
1058+ {
1059+ QueueSerumFrames (lastDmdUpdate);
10161060 }
10171061
1062+ HandleTrigger (m_pSerum->triggerID );
10181063 prevTriggerId = m_pSerum->triggerID ;
10191064 }
10201065 else
10211066 {
10221067 sceneFrameCount = 0 ;
1068+ QueueSerumFrames (lastDmdUpdate);
10231069 }
10241070 }
10251071 else if (showNotColorizedFrames || dumpNotColorizedFrames)
0 commit comments