From 03ac0f01ad2359a7ba2bc1ba64f8b1b8cbacceaa Mon Sep 17 00:00:00 2001 From: Luis Michaelis Date: Wed, 1 May 2024 21:25:45 +0200 Subject: [PATCH] fix(DmStyle): fix broken pattern selection --- src/Performance.c | 2 +- src/Style.c | 45 ++++++++++++++++++++++++--------------------- src/_Internal.h | 2 +- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/Performance.c b/src/Performance.c index fd7ea11..e7e89e9 100644 --- a/src/Performance.c +++ b/src/Performance.c @@ -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; diff --git a/src/Style.c b/src/Style.c index b05324f..1cdb5af 100644 --- a/src/Style.c +++ b/src/Style.c @@ -102,7 +102,7 @@ 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. @@ -110,31 +110,34 @@ DmPattern* DmStyle_getRandomPattern(DmPerformance* slf, DmCommandType cmd) { // 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; } diff --git a/src/_Internal.h b/src/_Internal.h index fe5d97c..2567bdb 100644 --- a/src/_Internal.h +++ b/src/_Internal.h @@ -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);