Skip to content

Commit ac622f9

Browse files
committed
mplemented frame groups, random, repeat, ...
1 parent 8511867 commit ac622f9

File tree

3 files changed

+98
-33
lines changed

3 files changed

+98
-33
lines changed

include/DMDUtil/SceneGenerator.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ struct SceneData
2323
bool interruptable = false;
2424
bool immediateStart = false;
2525
int repeat = 0; // 0 - play once, 1 - loop, >= 2 - repeat x times
26-
int frameGroup = 0;
26+
int frameGroups = 0;
27+
int currentGroup = 0; // Current group for frame generation, used internally
2728
bool random = false;
2829
int autoStart = 0; // 0 - no autostart, >= 1 - start this scene after x seconds of inactivity (no new frames), only
2930
// use once, could be combined with frame groups
@@ -38,7 +39,8 @@ class DMDUTILAPI SceneGenerator
3839

3940
bool parseCSV(const std::string& csv_filename);
4041
bool generateDump(const std::string& dump_filename, int id = -1);
41-
bool getSceneInfo(int sceneId, int& frameCount, int& durationPerFrame, bool& interruptable) const;
42+
bool getSceneInfo(int sceneId, int& frameCount, int& durationPerFrame, bool& interruptable, bool& startImmediately,
43+
int& repeat, int& endFrame) const;
4244
bool generateFrame(int sceneId, int frameIndex, uint8_t* buffer, int group = -1);
4345
void setDepth(int depth);
4446
void Reset()
@@ -65,7 +67,6 @@ class DMDUTILAPI SceneGenerator
6567
void initializeTemplate();
6668

6769
int m_depth = 2; // Default depth for rendering
68-
int m_currentGroup = 0;
6970
};
7071

7172
} // namespace DMDUtil

src/DMD.cpp

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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)

src/SceneGenerator.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ bool SceneGenerator::parseCSV(const std::string& csv_filename)
100100
if (row.size() >= 4) data.interruptable = (std::stoi(row[3]) == 1);
101101
if (row.size() >= 5) data.immediateStart = (std::stoi(row[4]) == 1);
102102
if (row.size() >= 6) data.repeat = std::stoi(row[5]);
103-
if (row.size() >= 7) data.frameGroup = std::stoi(row[6]);
103+
if (row.size() >= 7) data.frameGroups = std::stoi(row[6]) == 0 ? 1 : std::stoi(row[6]);
104104
if (row.size() >= 8) data.random = (std::stoi(row[7]) == 1);
105105
if (row.size() >= 9) data.autoStart = std::stoi(row[8]);
106106
if (row.size() >= 10) data.endFrame = std::stoi(row[9]);
@@ -134,7 +134,7 @@ bool SceneGenerator::generateDump(const std::string& dump_filename, int id)
134134
continue; // Skip scenes that don't match the specified ID
135135
}
136136

137-
int goups = scene.frameGroup > 0 ? scene.frameGroup : 1;
137+
int goups = scene.frameGroups > 0 ? scene.frameGroups : 1;
138138
for (int group = 1; group <= goups; group++)
139139
{
140140
for (int frameIndex = 0; frameIndex < scene.frameCount; frameIndex++)
@@ -171,7 +171,8 @@ bool SceneGenerator::generateDump(const std::string& dump_filename, int id)
171171
return true;
172172
}
173173

174-
bool SceneGenerator::getSceneInfo(int sceneId, int& frameCount, int& durationPerFrame, bool& interruptable) const
174+
bool SceneGenerator::getSceneInfo(int sceneId, int& frameCount, int& durationPerFrame, bool& interruptable,
175+
bool& startImmediately, int& repeat, int& endFrame) const
175176
{
176177
auto it = std::find_if(m_sceneData.begin(), m_sceneData.end(),
177178
[sceneId](const SceneData& data) { return data.sceneId == sceneId; });
@@ -184,6 +185,9 @@ bool SceneGenerator::getSceneInfo(int sceneId, int& frameCount, int& durationPer
184185
frameCount = it->frameCount;
185186
durationPerFrame = it->durationPerFrame;
186187
interruptable = it->interruptable;
188+
startImmediately = it->immediateStart;
189+
repeat = it->repeat;
190+
endFrame = it->endFrame;
187191
return true;
188192
}
189193

@@ -206,12 +210,26 @@ bool SceneGenerator::generateFrame(int sceneId, int frameIndex, uint8_t* buffer,
206210
{
207211
if (group == -1)
208212
{
209-
// @todo random or order play.
210-
m_currentGroup = 1;
213+
if (it->frameGroups > 1)
214+
{
215+
if (it->random)
216+
{
217+
it->currentGroup = rand() % it->frameGroups + 1;
218+
}
219+
else
220+
{
221+
it->currentGroup++;
222+
if (it->currentGroup > it->frameGroups) it->currentGroup = 1;
223+
}
224+
}
225+
else
226+
{
227+
it->currentGroup = 1;
228+
}
211229
}
212230
else
213231
{
214-
m_currentGroup = group;
232+
it->currentGroup = group;
215233
}
216234
}
217235

@@ -222,7 +240,7 @@ bool SceneGenerator::generateFrame(int sceneId, int frameIndex, uint8_t* buffer,
222240
std::string sceneIdStr = formatNumber(sceneId, NUMBER_WIDTH);
223241
renderString(buffer, sceneIdStr, NUM_X, SCENE_Y);
224242

225-
std::string groupStr = formatNumber(m_currentGroup, NUMBER_WIDTH);
243+
std::string groupStr = formatNumber(it->currentGroup, NUMBER_WIDTH);
226244
renderString(buffer, groupStr, NUM_X, GROUP_Y);
227245

228246
std::string frameStr = formatNumber(frameIndex + 1, NUMBER_WIDTH);

0 commit comments

Comments
 (0)