forked from libxmp/libxmp
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement flow-specific quirks system for Pattern Loop et. al. (libxm…
…p#816) This patch splits off Pattern Loop-only quirks from m->quirk into a new flow-specific field, m->flow_mode, and implements several new loop mode quirks. Due to the complexity of the Pattern Loop effect, it has been split into its own function, and the module scan now invokes this function (the alternative was two implementations). This could probably be extended to all of the flow control effects eventually, but effects.c would pull a bunch of other compilation units into the development tests right now and I am not interested in further scope creep for 4.6.1. I've kept this patch limited to the formats implicated in the discussion in libxmp#707, plus any format that was referencing `QUIRK_S3MLOOP` (almost all of them erroneously). I didn't bother splitting off FastTracker 2's shared loop target/ entry position field from `QUIRK_FT2BUGS` for the time being, as FT2 is a mess and I didn't want to entangle this branch further with it. Loop quirks implemented: * Global loop target: Scream Tracker 3, Digital Tracker, Octalyser, Poly Tracker, and probably other trackers use a shared loop target between all tracks. * Global loop count: Scream Tracker 3, Digital Tracker (until 1.9?), Octalyser, Poly Tracker, and probably other trackers use a shared loop count between all tracks. * Loop end advances target (originally `QUIRK_S3MLOOP`): Scream Tracker 3 and Impulse Tracker (2.10+) will advance the loop target to the row after the loop end effect when a loop terminates. Scream Tracker 3.01b has a bug where it will instead set the loop end to the row of the effect, which I've chosen not to emulate. * Loop end cancels jump: Liquid Tracker 0.80+ (and possibly some earlier versions) will cancel any jumps initiated by previous tracks on the same row when a loop terminates. This quirk is also applied to Octalyser to "fix" Dammed Illusion, though it is inaccurate and won't necessarily fix other similar cases. * Reset loop vars on pattern change: Scream Tracker 3 and Imago Orpheus reset the loop variables every time the current position changes (except for one bug in Imago Orpheus). Liquid Tracker 1.03+ will also do this if the "Scream Tracker compatibility" setting is enabled. * SBx sets loop target if it is unset: Scream Tracker 3.01b SBx will set the loop target if no SB0 was used ever in the pattern. * Only execute the first E60/E6x in a row: Digital Tracker (until 1.9?) will only handle the first Pattern Loop effect in a row, including E60. * Only one loop can run at a time: Modplug Tracker 1.16 will prevent E6x/SBx from starting a loop if another loop is already running in a different channel. * Ignore E60 when a loop is active: Liquid Tracker and Octalyser will not update the loop target when the loop count is non-zero. Trackers this new system attempts to support: * Scream Tracker 3.01b * Scream Tracker 3.03b/3.20/3.21 (also applied to GDMs for now) * Impulse Tracker 1.00 * Impulse Tracker 1.04 * Impulse Tracker 2.10 (also applied to some S3Ms) * Modplug Tracker 1.16 (applied to some S3Ms, XMs, ITs) * Imago Orpheus (also applied to some S3Ms) * Liquid Tracker * Poly Tracker * Octalyser * Digital Tracker 2.015/2.03/2.04 (also applied to Digital Tracker MODs) * Digital Tracker 1.9 I've left `QUIRK_S3MLOOP` in place for now, but it doesn't do anything anymore and its quirk slot can be repurposed for something else.
- Loading branch information
Showing
86 changed files
with
7,516 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* Extended Module Player | ||
* Copyright (C) 1996-2024 Claudio Matsuoka and Hipolito Carraro Jr | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a | ||
* copy of this software and associated documentation files (the "Software"), | ||
* to deal in the Software without restriction, including without limitation | ||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
* and/or sell copies of the Software, and to permit persons to whom the | ||
* Software is furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
* THE SOFTWARE. | ||
*/ | ||
|
||
#include "common.h" | ||
|
||
/* Process a pattern loop effect with the parameter fxp. A parameter of 0 | ||
* will set the loop target, and a parameter of 1-15 (most formats) or | ||
* 1-255 (OctaMED) will perform a loop. | ||
* | ||
* The compatibility logic for Pattern Loop is complex, so a flow_control | ||
* argument is taken such that the scan can use this function directly. | ||
* | ||
* If the development tests ever start building against effects.c, this | ||
* can be moved back to effects.c. | ||
*/ | ||
void libxmp_process_pattern_loop(struct context_data *ctx, | ||
struct flow_control *f, int chn, int row, int fxp) | ||
{ | ||
struct module_data *m = &ctx->m; | ||
struct xmp_module *mod = &m->mod; | ||
int *start = &f->loop[chn].start; | ||
int *count = &f->loop[chn].count; | ||
int i; | ||
|
||
/* Digital Tracker: only the first E60 or E6x is handled per row. */ | ||
if (HAS_FLOW_MODE(FLOW_LOOP_FIRST_EFFECT) && f->loop_param >= 0) { | ||
return; | ||
} | ||
f->loop_param = fxp; | ||
|
||
/* Scream Tracker 3, Digital Tracker, Octalyser, and probably others | ||
* use global loop targets and counts. Later versions of Digital | ||
* Tracker use a global target but per-track counts. */ | ||
if (HAS_FLOW_MODE(FLOW_LOOP_GLOBAL_TARGET)) { | ||
start = &f->loop_start; | ||
} | ||
if (HAS_FLOW_MODE(FLOW_LOOP_GLOBAL_COUNT)) { | ||
count = &f->loop_count; | ||
} | ||
|
||
if (fxp == 0) { | ||
/* mark start of loop */ | ||
/* Liquid Tracker: M60 is ignored for channels with count >= 1 */ | ||
if (HAS_FLOW_MODE(FLOW_LOOP_IGNORE_TARGET) && *count >= 1) { | ||
return; | ||
} | ||
*start = row; | ||
if (HAS_QUIRK(QUIRK_FT2BUGS)) | ||
f->jumpline = row; | ||
} else { | ||
/* end of loop */ | ||
if (*start < 0) { | ||
/* Scream Tracker 3.01b: if SB0 wasn't used, the first | ||
* SBx used will set the loop target to its row. */ | ||
if (HAS_FLOW_MODE(FLOW_LOOP_INIT_SAMEROW)) { | ||
*start = row; | ||
} else { | ||
*start = 0; | ||
} | ||
} | ||
|
||
if (*count) { | ||
if (--(*count)) { | ||
f->loop_dest = *start; | ||
} else { | ||
/* S3M and IT: loop termination advances the | ||
* loop target past SBx. */ | ||
if (HAS_FLOW_MODE(FLOW_LOOP_END_ADVANCES)) { | ||
*start = row + 1; | ||
} | ||
/* Liquid Tracker cancels any other loop jumps | ||
* this row started on loop termination. */ | ||
if (HAS_FLOW_MODE(FLOW_LOOP_END_CANCELS)) { | ||
f->loop_dest = -1; | ||
} | ||
f->loop_active_num--; | ||
} | ||
} else { | ||
/* Modplug Tracker: only begin a loop if no | ||
* other channel is currently looping. */ | ||
if (HAS_FLOW_MODE(FLOW_LOOP_ONE_AT_A_TIME)) { | ||
for (i = 0; i < mod->chn; i++) { | ||
if (i != chn && f->loop[i].count != 0) | ||
return; | ||
} | ||
} | ||
*count = fxp; | ||
f->loop_dest = *start; | ||
f->loop_active_num++; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#ifndef LIBXMP_CORE_PLAYER | ||
#define LIBXMP_CORE_PLAYER | ||
#endif | ||
#include "../flow.c" |
Oops, something went wrong.