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