Skip to content

Commit

Permalink
[Imp] Insert pattern break commands in MOD/S3M when trying to save pa…
Browse files Browse the repository at this point in the history
…tterns shorter than 64 rows.

git-svn-id: https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@21788 56274372-70c3-4bfc-bfc3-4c3a0b034d27
  • Loading branch information
sagamusix committed Oct 8, 2024
1 parent d164002 commit 938d49c
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 4 deletions.
6 changes: 6 additions & 0 deletions soundlib/Load_mod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,7 @@ bool CSoundFile::SaveMod(std::ostream &f) const
continue;
}
const auto rowBase = Patterns[pat].GetRow(row);
bool writePatternBreak = (Patterns[pat].GetNumRows() < 64 && row + 1 == Patterns[pat].GetNumRows() && !Patterns[pat].RowHasJump(row));

events.resize(writeChannels * 4);
size_t eventByte = 0;
Expand All @@ -1019,6 +1020,11 @@ bool CSoundFile::SaveMod(std::ostream &f) const
command = 0x0C;
param = std::min(m.vol, uint8(64));
}
if(writePatternBreak && !command && !param)
{
command = 0x0D;
writePatternBreak = false;
}

uint16 period = 0;
// Convert note to period
Expand Down
7 changes: 7 additions & 0 deletions soundlib/Load_s3m.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,7 @@ bool CSoundFile::SaveS3M(std::ostream &f) const
const auto rowBase = Patterns[pat].GetRow(row);

CHANNELINDEX writeChannels = std::min(CHANNELINDEX(32), GetNumChannels());
bool writePatternBreak = (Patterns[pat].GetNumRows() < 64 && row + 1 == Patterns[pat].GetNumRows() && !Patterns[pat].RowHasJump(row));
for(CHANNELINDEX chn = 0; chn < writeChannels; chn++)
{
const ModCommand &m = rowBase[chn];
Expand Down Expand Up @@ -979,6 +980,12 @@ bool CSoundFile::SaveS3M(std::ostream &f) const
}
}
}
if(writePatternBreak && !(info & s3mEffectPresent))
{
info |= s3mEffectPresent;
command = 'C' ^ 0x40;
writePatternBreak = false;
}

if(info & s3mAnyPresent)
{
Expand Down
19 changes: 15 additions & 4 deletions soundlib/pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,32 @@ CHANNELINDEX CPattern::GetNumChannels() const noexcept
bool CPattern::IsEmptyRow(ROWINDEX row) const noexcept
{
if(m_ModCommands.empty() || !IsValidRow(row))
{
return true;
}

for(const auto &m : GetRow(row))
{
if(!m.IsEmpty())
{
return false;
}
}
return true;
}


// Check if the row contains any position jumps or pattern breaks.
bool CPattern::RowHasJump(ROWINDEX row) const noexcept
{
if(m_ModCommands.empty() || !IsValidRow(row))
return false;

for(const auto &m : GetRow(row))
{
if(m.command == CMD_PATTERNBREAK || m.command == CMD_POSITIONJUMP)
return true;
}
return false;
}


bool CPattern::SetSignature(const ROWINDEX rowsPerBeat, const ROWINDEX rowsPerMeasure) noexcept
{
if(rowsPerBeat < 1
Expand Down
2 changes: 2 additions & 0 deletions soundlib/pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class CPattern

// Check if there is any note data on a given row.
bool IsEmptyRow(ROWINDEX row) const noexcept;
// Check if the row contains any position jumps or pattern breaks.
bool RowHasJump(ROWINDEX row) const noexcept;

// Allocate new pattern memory and replace old pattern data.
bool AllocatePattern(ROWINDEX rows);
Expand Down

0 comments on commit 938d49c

Please sign in to comment.