1 /* Extended Module Player
2 * Copyright (C) 1996-2021 Claudio Matsuoka and Hipolito Carraro Jr
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23 /*
24 * Sun, 31 May 1998 17:50:02 -0600
25 * Reported by ToyKeeper <scriven@CS.ColoState.EDU>:
26 * For loop-prevention, I know a way to do it which lets most songs play
27 * fine once through even if they have backward-jumps. Just keep a small
28 * array (256 bytes, or even bits) of flags, each entry determining if a
29 * pattern in the song order has been played. If you get to an entry which
30 * is already non-zero, skip to the next song (assuming looping is off).
31 */
32
33 /*
34 * Tue, 6 Oct 1998 21:23:17 +0200 (CEST)
35 * Reported by John v/d Kamp <blade_@dds.nl>:
36 * scan.c was hanging when it jumps to an invalid restart value.
37 * (Fixed by hipolito)
38 */
39
40
41 #include "common.h"
42 #include "effects.h"
43 #include "mixer.h"
44
45 #define S3M_END 0xff
46 #define S3M_SKIP 0xfe
47
48
scan_module(struct context_data * ctx,int ep,int chain)49 static int scan_module(struct context_data *ctx, int ep, int chain)
50 {
51 struct player_data *p = &ctx->p;
52 struct module_data *m = &ctx->m;
53 struct xmp_module *mod = &m->mod;
54 int parm, gvol_memory, f1, f2, p1, p2, ord, ord2;
55 int row, last_row, break_row, row_count, row_count_total;
56 int orders_since_last_valid, any_valid;
57 int gvl, bpm, speed, base_time, chn;
58 int frame_count;
59 double time, start_time;
60 int loop_chn, loop_num, inside_loop;
61 int pdelay = 0;
62 int loop_count[XMP_MAX_CHANNELS];
63 int loop_row[XMP_MAX_CHANNELS];
64 struct xmp_event* event;
65 int i, pat;
66 int has_marker;
67 struct ord_data *info;
68 #ifndef LIBXMP_CORE_PLAYER
69 int st26_speed;
70 #endif
71
72 if (mod->len == 0)
73 return 0;
74
75 for (i = 0; i < mod->len; i++) {
76 int pat = mod->xxo[i];
77 memset(m->scan_cnt[i], 0, pat >= mod->pat ? 1 :
78 mod->xxp[pat]->rows ? mod->xxp[pat]->rows : 1);
79 }
80
81 for (i = 0; i < mod->chn; i++) {
82 loop_count[i] = 0;
83 loop_row[i] = -1;
84 }
85 loop_num = 0;
86 loop_chn = -1;
87
88 gvl = mod->gvl;
89 bpm = mod->bpm;
90
91 speed = mod->spd;
92 base_time = m->rrate;
93 #ifndef LIBXMP_CORE_PLAYER
94 st26_speed = 0;
95 #endif
96
97 has_marker = HAS_QUIRK(QUIRK_MARKER);
98
99 /* By erlk ozlr <erlk.ozlr@gmail.com>
100 *
101 * xmp doesn't handle really properly the "start" option (-s for the
102 * command-line) for DeusEx's .umx files. These .umx files contain
103 * several loop "tracks" that never join together. That's how they put
104 * multiple musics on each level with a file per level. Each "track"
105 * starts at the same order in all files. The problem is that xmp starts
106 * decoding the module at order 0 and not at the order specified with
107 * the start option. If we have a module that does "0 -> 2 -> 0 -> ...",
108 * we cannot play order 1, even with the supposed right option.
109 *
110 * was: ord2 = ord = -1;
111 *
112 * CM: Fixed by using different "sequences" for each loop or subsong.
113 * Each sequence has its entry point. Sequences don't overlap.
114 */
115 ord2 = -1;
116 ord = ep - 1;
117
118 gvol_memory = break_row = row_count = row_count_total = frame_count = 0;
119 orders_since_last_valid = any_valid = 0;
120 start_time = time = 0.0;
121 inside_loop = 0;
122
123 while (42) {
124 /* Sanity check to prevent getting stuck due to broken patterns. */
125 if (orders_since_last_valid > 512) {
126 D_(D_CRIT "orders_since_last_valid = %d @ ord %d; ending scan", orders_since_last_valid, ord);
127 break;
128 }
129 orders_since_last_valid++;
130
131 if ((uint32)++ord >= mod->len) {
132 if (mod->rst > mod->len || mod->xxo[mod->rst] >= mod->pat) {
133 ord = ep;
134 } else {
135 if (libxmp_get_sequence(ctx, mod->rst) == chain) {
136 ord = mod->rst;
137 } else {
138 ord = ep;
139 }
140 }
141
142 pat = mod->xxo[ord];
143 if (has_marker && pat == S3M_END) {
144 break;
145 }
146 }
147
148 pat = mod->xxo[ord];
149 info = &m->xxo_info[ord];
150
151 /* Allow more complex order reuse only in main sequence */
152 if (ep != 0 && p->sequence_control[ord] != 0xff) {
153 break;
154 }
155 p->sequence_control[ord] = chain;
156
157 /* All invalid patterns skipped, only S3M_END aborts replay */
158 if (pat >= mod->pat) {
159 if (has_marker && pat == S3M_END) {
160 ord = mod->len;
161 continue;
162 }
163 continue;
164 }
165
166 if (break_row >= mod->xxp[pat]->rows) {
167 break_row = 0;
168 }
169
170 /* Loops can cross pattern boundaries, so check if we're not looping */
171 if (m->scan_cnt[ord][break_row] && !inside_loop) {
172 break;
173 }
174
175 /* Only update pattern information if we weren't here before. This also
176 * means that we don't update pattern information if we're inside a loop,
177 * otherwise a loop containing e.g. a global volume fade can make the
178 * pattern start with the wrong volume. (fixes xyce-dans_la_rue.xm replay,
179 * see https://github.com/libxmp/libxmp/issues/153 for more details).
180 */
181 if (info->time < 0) {
182 info->gvl = gvl;
183 info->bpm = bpm;
184 info->speed = speed;
185 info->time = time + m->time_factor * frame_count * base_time / bpm;
186 #ifndef LIBXMP_CORE_PLAYER
187 info->st26_speed = st26_speed;
188 #endif
189 }
190
191 if (info->start_row == 0 && ord != 0) {
192 if (ord == ep) {
193 start_time = time + m->time_factor * frame_count * base_time / bpm;
194 }
195
196 info->start_row = break_row;
197 }
198
199 last_row = mod->xxp[pat]->rows;
200 for (row = break_row, break_row = 0; row < last_row; row++, row_count++, row_count_total++) {
201 /* Prevent crashes caused by large softmixer frames */
202 if (bpm < XMP_MIN_BPM) {
203 bpm = XMP_MIN_BPM;
204 }
205
206 /* Date: Sat, 8 Sep 2007 04:01:06 +0200
207 * Reported by Zbigniew Luszpinski <zbiggy@o2.pl>
208 * The scan routine falls into infinite looping and doesn't let
209 * xmp play jos-dr4k.xm.
210 * Claudio's workaround: we'll break infinite loops here.
211 *
212 * Date: Oct 27, 2007 8:05 PM
213 * From: Adric Riedel <adric.riedel@gmail.com>
214 * Jesper Kyd: Global Trash 3.mod (the 'Hardwired' theme) only
215 * plays the first 4:41 of what should be a 10 minute piece.
216 * (...) it dies at the end of position 2F
217 */
218
219 if (row_count_total > 512) { /* was 255, but Global trash goes to 318. */
220 D_(D_CRIT "row_count_total = %d @ ord %d, pat %d, row %d; ending scan", row_count_total, ord, pat, row);
221 goto end_module;
222 }
223
224 if (!loop_num && m->scan_cnt[ord][row]) {
225 row_count--;
226 goto end_module;
227 }
228 m->scan_cnt[ord][row]++;
229 orders_since_last_valid = 0;
230 any_valid = 1;
231
232 /* If the scan count for this row overflows, break.
233 * A scan count of 0 will help break this loop in playback (storlek_11.it).
234 */
235 if (!m->scan_cnt[ord][row]) {
236 goto end_module;
237 }
238
239 pdelay = 0;
240
241 for (chn = 0; chn < mod->chn; chn++) {
242 if (row >= mod->xxt[mod->xxp[pat]->index[chn]]->rows)
243 continue;
244
245 event = &EVENT(mod->xxo[ord], chn, row);
246
247 f1 = event->fxt;
248 p1 = event->fxp;
249 f2 = event->f2t;
250 p2 = event->f2p;
251
252 if (f1 == FX_GLOBALVOL || f2 == FX_GLOBALVOL) {
253 gvl = (f1 == FX_GLOBALVOL) ? p1 : p2;
254 gvl = gvl > m->gvolbase ? m->gvolbase : gvl < 0 ? 0 : gvl;
255 }
256
257 /* Process fine global volume slide */
258 if (f1 == FX_GVOL_SLIDE || f2 == FX_GVOL_SLIDE) {
259 int h, l;
260 parm = (f1 == FX_GVOL_SLIDE) ? p1 : p2;
261
262 process_gvol:
263 if (parm) {
264 gvol_memory = parm;
265 h = MSN(parm);
266 l = LSN(parm);
267
268 if (HAS_QUIRK(QUIRK_FINEFX)) {
269 if (l == 0xf && h != 0) {
270 gvl += h;
271 } else if (h == 0xf && l != 0) {
272 gvl -= l;
273 } else {
274 if (m->quirk & QUIRK_VSALL) {
275 gvl += (h - l) * speed;
276 } else {
277 gvl += (h - l) * (speed - 1);
278 }
279 }
280 } else {
281 if (m->quirk & QUIRK_VSALL) {
282 gvl += (h - l) * speed;
283 } else {
284 gvl += (h - l) * (speed - 1);
285 }
286 }
287 } else {
288 if ((parm = gvol_memory) != 0)
289 goto process_gvol;
290 }
291 }
292
293 if ((f1 == FX_SPEED && p1) || (f2 == FX_SPEED && p2)) {
294 parm = (f1 == FX_SPEED) ? p1 : p2;
295 frame_count += row_count * speed;
296 row_count = 0;
297 if (parm) {
298 if (HAS_QUIRK(QUIRK_NOBPM) || p->flags & XMP_FLAGS_VBLANK || parm < 0x20) {
299 if (parm > 0) {
300 speed = parm;
301 #ifndef LIBXMP_CORE_PLAYER
302 st26_speed = 0;
303 #endif
304 }
305 } else {
306 time += m->time_factor * frame_count * base_time / bpm;
307 frame_count = 0;
308 bpm = parm;
309 }
310 }
311 }
312
313 #ifndef LIBXMP_CORE_PLAYER
314 if (f1 == FX_SPEED_CP) {
315 f1 = FX_S3M_SPEED;
316 }
317 if (f2 == FX_SPEED_CP) {
318 f2 = FX_S3M_SPEED;
319 }
320
321 /* ST2.6 speed processing */
322
323 if (f1 == FX_ICE_SPEED && p1) {
324 if (LSN(p1)) {
325 st26_speed = (MSN(p1) << 8) | LSN(p1);
326 } else {
327 st26_speed = MSN(p1);
328 }
329 }
330 #endif
331
332 if ((f1 == FX_S3M_SPEED && p1) || (f2 == FX_S3M_SPEED && p2)) {
333 parm = (f1 == FX_S3M_SPEED) ? p1 : p2;
334 if (parm > 0) {
335 frame_count += row_count * speed;
336 row_count = 0;
337 speed = parm;
338 #ifndef LIBXMP_CORE_PLAYER
339 st26_speed = 0;
340 #endif
341 }
342 }
343
344 if ((f1 == FX_S3M_BPM && p1) || (f2 == FX_S3M_BPM && p2)) {
345 parm = (f1 == FX_S3M_BPM) ? p1 : p2;
346 if (parm >= 0x20) {
347 frame_count += row_count * speed;
348 row_count = 0;
349 time += m->time_factor * frame_count * base_time / bpm;
350 frame_count = 0;
351 bpm = parm;
352 }
353 }
354
355 #ifndef LIBXMP_CORE_DISABLE_IT
356 if ((f1 == FX_IT_BPM && p1) || (f2 == FX_IT_BPM && p2)) {
357 parm = (f1 == FX_IT_BPM) ? p1 : p2;
358 frame_count += row_count * speed;
359 row_count = 0;
360 time += m->time_factor * frame_count * base_time / bpm;
361 frame_count = 0;
362
363 if (MSN(parm) == 0) {
364 time += m->time_factor * base_time / bpm;
365 for (i = 1; i < speed; i++) {
366 bpm -= LSN(parm);
367 if (bpm < 0x20)
368 bpm = 0x20;
369 time += m->time_factor * base_time / bpm;
370 }
371
372 /* remove one row at final bpm */
373 time -= m->time_factor * speed * base_time / bpm;
374
375 } else if (MSN(parm) == 1) {
376 time += m->time_factor * base_time / bpm;
377 for (i = 1; i < speed; i++) {
378 bpm += LSN(parm);
379 if (bpm > 0xff)
380 bpm = 0xff;
381 time += m->time_factor * base_time / bpm;
382 }
383
384 /* remove one row at final bpm */
385 time -= m->time_factor * speed * base_time / bpm;
386
387 } else {
388 bpm = parm;
389 }
390 }
391
392 if (f1 == FX_IT_ROWDELAY) {
393 /* Don't allow the scan count for this row to overflow here. */
394 int x = m->scan_cnt[ord][row] + (p1 & 0x0f);
395 m->scan_cnt[ord][row] = MIN(x, 255);
396 frame_count += (p1 & 0x0f) * speed;
397 }
398
399 if (f1 == FX_IT_BREAK) {
400 break_row = p1;
401 last_row = 0;
402 }
403 #endif
404
405 if (f1 == FX_JUMP || f2 == FX_JUMP) {
406 ord2 = (f1 == FX_JUMP) ? p1 : p2;
407 break_row = 0;
408 last_row = 0;
409
410 /* prevent infinite loop, see OpenMPT PatLoop-Various.xm */
411 inside_loop = 0;
412 }
413
414 if (f1 == FX_BREAK || f2 == FX_BREAK) {
415 parm = (f1 == FX_BREAK) ? p1 : p2;
416 break_row = 10 * MSN(parm) + LSN(parm);
417 last_row = 0;
418 }
419
420 if (f1 == FX_EXTENDED || f2 == FX_EXTENDED) {
421 parm = (f1 == FX_EXTENDED) ? p1 : p2;
422
423 if ((parm >> 4) == EX_PATT_DELAY) {
424 if (m->read_event_type != READ_EVENT_ST3 || !pdelay) {
425 pdelay = parm & 0x0f;
426 frame_count += pdelay * speed;
427 }
428 }
429
430 if ((parm >> 4) == EX_PATTERN_LOOP) {
431 if (parm &= 0x0f) {
432 /* Loop end */
433 if (loop_count[chn]) {
434 if (--loop_count[chn]) {
435 /* next iteraction */
436 loop_chn = chn;
437 } else {
438 /* finish looping */
439 loop_num--;
440 inside_loop = 0;
441 if (m->quirk & QUIRK_S3MLOOP)
442 loop_row[chn] = row;
443 }
444 } else {
445 loop_count[chn] = parm;
446 loop_chn = chn;
447 loop_num++;
448 }
449 } else {
450 /* Loop start */
451 loop_row[chn] = row - 1;
452 inside_loop = 1;
453 if (HAS_QUIRK(QUIRK_FT2BUGS))
454 break_row = row;
455 }
456 }
457 }
458 }
459
460 if (loop_chn >= 0) {
461 row = loop_row[loop_chn];
462 loop_chn = -1;
463 }
464
465 #ifndef LIBXMP_CORE_PLAYER
466 if (st26_speed) {
467 frame_count += row_count * speed;
468 row_count = 0;
469 if (st26_speed & 0x10000) {
470 speed = (st26_speed & 0xff00) >> 8;
471 } else {
472 speed = st26_speed & 0xff;
473 }
474 st26_speed ^= 0x10000;
475 }
476 #endif
477 }
478
479 if (break_row && pdelay) {
480 break_row++;
481 }
482
483 if (ord2 >= 0) {
484 ord = ord2 - 1;
485 ord2 = -1;
486 }
487
488 frame_count += row_count * speed;
489 row_count_total = 0;
490 row_count = 0;
491 }
492 row = break_row;
493
494 end_module:
495
496 /* Sanity check */
497 {
498 if (!any_valid) {
499 return -1;
500 }
501 pat = mod->xxo[ord];
502 if (pat >= mod->pat || row >= mod->xxp[pat]->rows) {
503 row = 0;
504 }
505 }
506
507 p->scan[chain].num = m->scan_cnt[ord][row];
508 p->scan[chain].row = row;
509 p->scan[chain].ord = ord;
510
511 time -= start_time;
512 frame_count += row_count * speed;
513
514 return (time + m->time_factor * frame_count * base_time / bpm);
515 }
516
libxmp_get_sequence(struct context_data * ctx,int ord)517 int libxmp_get_sequence(struct context_data *ctx, int ord)
518 {
519 struct player_data *p = &ctx->p;
520 return p->sequence_control[ord];
521 }
522
libxmp_scan_sequences(struct context_data * ctx)523 int libxmp_scan_sequences(struct context_data *ctx)
524 {
525 struct player_data *p = &ctx->p;
526 struct module_data *m = &ctx->m;
527 struct xmp_module *mod = &m->mod;
528 int i, ep;
529 int seq;
530 unsigned char temp_ep[XMP_MAX_MOD_LENGTH];
531
532 /* Initialize order data to prevent overwrite when a position is used
533 * multiple times at different starting points (see janosik.xm).
534 */
535 for (i = 0; i < XMP_MAX_MOD_LENGTH; i++) {
536 m->xxo_info[i].time = -1;
537 }
538
539 ep = 0;
540 memset(p->sequence_control, 0xff, XMP_MAX_MOD_LENGTH);
541 temp_ep[0] = 0;
542 p->scan[0].time = scan_module(ctx, ep, 0);
543 seq = 1;
544
545 if (p->scan[0].time < 0) {
546 D_(D_CRIT "scan was not able to find any valid orders");
547 return -1;
548 }
549
550 while (1) {
551 /* Scan song starting at given entry point */
552 /* Check if any patterns left */
553 for (i = 0; i < mod->len; i++) {
554 if (p->sequence_control[i] == 0xff) {
555 break;
556 }
557 }
558 if (i != mod->len && seq < MAX_SEQUENCES) {
559 /* New entry point */
560 ep = i;
561 temp_ep[seq] = ep;
562 p->scan[seq].time = scan_module(ctx, ep, seq);
563 if (p->scan[seq].time > 0)
564 seq++;
565 } else {
566 break;
567 }
568 }
569
570 m->num_sequences = seq;
571
572 /* Now place entry points in the public accessible array */
573 for (i = 0; i < m->num_sequences; i++) {
574 m->seq_data[i].entry_point = temp_ep[i];
575 m->seq_data[i].duration = p->scan[i].time;
576 }
577
578
579 return 0;
580 }
581