Skip to content

Commit

Permalink
fix(DmStyle): fix broken pattern selection
Browse files Browse the repository at this point in the history
  • Loading branch information
lmichaelis committed May 1, 2024
1 parent fe4b0ed commit 03ac0f0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/Performance.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ static void DmPerformance_handleCommandMessage(DmPerformance* slf, DmMessage_Com
Dm_report(DmLogLevel_WARN, "DmPerformance: Command message with command %d not implemented", msg->command);
}

DmPattern* pttn = DmStyle_getRandomPattern(slf, msg->command);
DmPattern* pttn = DmStyle_getRandomPattern(slf->style, slf->groove, msg->command);
if (pttn == NULL) {
Dm_report(DmLogLevel_WARN, "DmPerformance: No suitable pattern found. Silence ensues ...", msg->command);
return;
Expand Down
45 changes: 24 additions & 21 deletions src/Style.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,39 +102,42 @@ static uint32_t Dm_toEmbellishmentFlagset(DmCommandType cmd) {
}

// See: https://documentation.help/DirectMusic/howmusicvariesduringplayback.htm
DmPattern* DmStyle_getRandomPattern(DmPerformance* slf, DmCommandType cmd) {
DmPattern* DmStyle_getRandomPattern(DmStyle* slf, uint32_t groove, DmCommandType cmd) {
uint32_t embellishment = Dm_toEmbellishmentFlagset(cmd);

// Select a random pattern according to the current groove level.
// TODO(lmichaelis): This behaviour seems to be associated with DX < 8 only, newer versions should
// have some way of defining how to select the pattern if more than 1 choice is available
// but I couldn't find it.

uint32_t index = rand() % slf->style->patterns.length;
for (size_t i = 0; i < slf->style->patterns.length; ++i) {
DmPattern* pttn = &slf->style->patterns.data[i];
int32_t index = rand() % slf->patterns.length;
do {
for (size_t i = 0; i < slf->patterns.length; ++i) {
DmPattern* pttn = &slf->patterns.data[i];

// Ignore patterns outside the current groove level.
if (slf->groove < pttn->groove_bottom || slf->groove > pttn->groove_top) {
continue;
}
// Ignore patterns outside the current groove level.
if (groove < pttn->groove_bottom || groove > pttn->groove_top) {
continue;
}

// Patterns with a differing embellishment are not supported
if (pttn->embellishment != embellishment && !(pttn->embellishment & embellishment)) {
continue;
}
// Patterns with a differing embellishment are not supported
if (pttn->embellishment != embellishment && !(pttn->embellishment & embellishment)) {
continue;
}

// Fix for Gothic 2 in which some patterns are empty but have a groove range of 1-100 with no embellishment set.
if (pttn->embellishment == DmCommand_GROOVE && pttn->length_measures == 1) {
continue;
}
// Fix for Gothic 2 in which some patterns are empty but have a groove range of 1-100 with no embellishment
// set.
if (pttn->embellishment == DmCommand_GROOVE && pttn->length_measures == 1) {
continue;
}

if (index == 0) {
return pttn;
}
if (index == 0) {
return pttn;
}

index -= 1;
}
index -= 1;
}
} while (index >= 0);

return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion src/_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ DMINT void DmStyle_release(DmStyle* slf);
DMINT DmResult DmStyle_parse(DmStyle* slf, void* buf, size_t len);
DMINT DmResult DmStyle_download(DmStyle* slf, DmLoader* loader);
DMINT DmPart* DmStyle_findPart(DmStyle* slf, DmPartReference* pref);
DMINT DmPattern* DmStyle_getRandomPattern(DmPerformance* slf, DmCommandType cmd);
DMINT DmPattern* DmStyle_getRandomPattern(DmStyle* slf, uint32_t groove, DmCommandType cmd);

DMINT void DmPart_init(DmPart* slf);
DMINT void DmPart_free(DmPart* slf);
Expand Down

0 comments on commit 03ac0f0

Please sign in to comment.