1 /*  _______         ____    __         ___    ___
2  * \    _  \       \    /  \  /       \   \  /   /       '   '  '
3  *  |  | \  \       |  |    ||         |   \/   |         .      .
4  *  |  |  |  |      |  |    ||         ||\  /|  |
5  *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
6  *  |  |  |  |      |  |    ||         ||    |  |         .      .
7  *  |  |_/  /        \  \__//          ||    |  |
8  * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
9  *                                                      /  \
10  *                                                     / .  \
11  * readpsm.c - Code to read a Protracker Studio       / / \  \
12  *             module from an open file.             | <  /   \_
13  *                                                   |  \/ /\   /
14  * By Chris Moeller.                                  \_  /  > /
15  *                                                      | \ / /
16  *                                                      |  ' /
17  *                                                       \__/
18  */
19 
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "dumb.h"
24 #include "internal/it.h"
25 
26 #ifndef min
27 #define min(a, b) (((a) < (b)) ? (a) : (b))
28 #endif
29 
30 #ifdef _MSC_VER
31 #define snprintf sprintf_s
32 #endif
33 
34 #define PSMV_OLD 940730
35 #define PSMV_NEW 940902
36 
37 typedef struct _PSMCHUNK
38 {
39 	int id;
40 	int len;
41 	unsigned char * data;
42 } PSMCHUNK;
43 
44 typedef struct _PSMEVENT
45 {
46 	int type;
47 	unsigned char data[8];
48 } PSMEVENT;
49 
50 #define PSM_EVENT_END               0
51 #define PSM_EVENT_PLAY_PATTERN      1
52 #define PSM_EVENT_JUMP_TO_LINE      4
53 #define PSM_EVENT_SET_SPEED         7
54 #define PSM_EVENT_SET_BPM           8
55 #define PSM_EVENT_SAMPLE_MAP_TABLE 12
56 #define PSM_EVENT_CHANGE_PAN       13
57 #define PSM_EVENT_CHANGE_VOL       14
58 
it_psm_process_sample(IT_SAMPLE * sample,const unsigned char * data,int len,int id,int version)59 static int it_psm_process_sample(IT_SAMPLE * sample, const unsigned char * data, int len, int id, int version) {
60 	int flags;
61 	int insno;
62 	int length;
63 	int loopstart;
64 	int loopend;
65 	int panpos;
66 	int defvol;
67 	int samplerate;
68 
69 	if (len < 0x60) return -1;
70 
71 	flags = data[0];
72 
73 	if (version == PSMV_OLD) {
74 		memcpy(sample->name, data + 0x0D, 34);
75 		sample->name[34] = 0;
76 
77 		insno = data[0x34] | (data[0x35] << 8);
78 		length = data[0x36] | (data[0x37] << 8) | (data[0x38] << 16) | (data[0x39] << 24);
79 		loopstart = data[0x3A] | (data[0x3B] << 8) | (data[0x3C] << 16) | (data[0x3D] << 24);
80 		loopend = data[0x3E] | (data[0x3F] << 8) | (data[0x40] << 16) | (data[0x41] << 24);
81 		panpos = data[0x43];
82 		defvol = data[0x44];
83 		samplerate = data[0x49] | (data[0x4A] << 8) | (data[0x4B] << 16) | (data[0x4C] << 24);
84 	} else /*if (version == PSMV_NEW)*/ {
85 		memcpy(sample->name, data + 0x11, 34);
86 		sample->name[34] = 0;
87 
88 		insno = data[0x38] | (data[0x39] << 8);
89 		length = data[0x3A] | (data[0x3B] << 8) | (data[0x3C] << 16) | (data[0x3D] << 24);
90 		loopstart = data[0x3E] | (data[0x3F] << 8) | (data[0x40] << 16) | (data[0x41] << 24);
91 		loopend = data[0x42] | (data[0x43] << 8) | (data[0x44] << 16) | (data[0x45] << 24);
92 		panpos = data[0x48];
93 		defvol = data[0x49];
94 		samplerate = data[0x4E] | (data[0x4F] << 8) | (data[0x50] << 16) | (data[0x51] << 24);
95 	}
96 
97 	if (insno != id) return -1;
98 
99 	if (!length) {
100 		sample->flags &= ~IT_SAMPLE_EXISTS;
101 		return 0;
102 	}
103 
104 	if ((length > len - 0x60) || ((flags & 0x7F) != 0)) return -1;
105 
106 	sample->flags = IT_SAMPLE_EXISTS;
107 	sample->length = length;
108 	sample->loop_start = loopstart;
109 	sample->loop_end = loopend;
110 	sample->C5_speed = samplerate;
111 	sample->default_volume = defvol >> 1;
112 	sample->default_pan = 0;
113 	sample->filename[0] = 0;
114 	sample->global_volume = 64;
115 	sample->vibrato_speed = 0;
116 	sample->vibrato_depth = 0;
117 	sample->vibrato_rate = 0;
118 	sample->vibrato_waveform = IT_VIBRATO_SINE;
119 	sample->finetune = 0;
120 	sample->max_resampling_quality = -1;
121 
122 	if (flags & 0x80) {
123 		if (((unsigned int)sample->loop_end <= (unsigned int)sample->length) &&
124 			((unsigned int)sample->loop_start < (unsigned int)sample->loop_end)) {
125 			sample->length = sample->loop_end;
126 			sample->flags |= IT_SAMPLE_LOOP;
127 		}
128 	}
129 
130 	sample->data = malloc(sample->length);
131 	if (!sample->data)
132 		return -1;
133 
134 	flags = 0;
135 	data += 0x60;
136 
137 	for (insno = 0; insno < sample->length; insno++) {
138 		flags += (signed char)(*data++);
139 		((signed char *)sample->data)[insno] = flags;
140 	}
141 
142 	return 0;
143 }
144 
it_psm_process_pattern(IT_PATTERN * pattern,const unsigned char * data,int len,int speed,int bpm,const unsigned char * pan,const int * vol,int version)145 static int it_psm_process_pattern(IT_PATTERN * pattern, const unsigned char * data, int len, int speed, int bpm, const unsigned char * pan, const int * vol, int version) {
146 	int length, nrows, row, rowlen, pos;
147 	unsigned flags, chan;
148 	IT_ENTRY * entry;
149 
150 	length = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
151 	if (len > length) len = length;
152 
153 	if (version == PSMV_OLD) {
154 		if (len < 10) return -1;
155 		data += 8;
156 		len -= 8;
157 	} else /*if (version == PSMV_NEW)*/ {
158 		if (len < 14) return -1;
159 		data += 12;
160 		len -= 12;
161 	}
162 
163 	nrows = data[0] | (data[1] << 8);
164 
165 	if (!nrows) return 0;
166 
167 	pattern->n_rows = nrows;
168 
169 	data += 2;
170 	len -= 2;
171 
172 	pattern->n_entries = 0;
173 
174 	row = 0;
175 	pos = 2;
176 	rowlen = data[0] | (data[1] << 8);
177 
178 	while ((row < nrows) && (pos < len)) {
179 		if (pos >= rowlen) {
180 			row++;
181 			rowlen += data[pos] | (data[pos+1] << 8);
182 			pos += 2;
183 			continue;
184 		}
185 
186 		flags = data[pos++];
187 		chan = data[pos++];
188 
189 		if (chan > 63) return -1;
190 
191 		if (flags & 0xF0) {
192 			pattern->n_entries++;
193 			if (flags & 0x80) pos++;
194 			if (flags & 0x40) pos++;
195 			if (flags & 0x20) pos++;
196 			if (flags & 0x10) {
197 				switch (data[pos]) {
198 					case 0x29:
199 						pos++;
200 					case 0x33:
201 						pos++;
202 					default:
203 						pos += 2;
204 				}
205 			}
206 		}
207 	}
208 
209 	if (!pattern->n_entries) return 0;
210 
211 	pattern->n_entries += nrows;
212 	if (speed) pattern->n_entries++;
213 	if (bpm >= 0x20) pattern->n_entries++;
214 
215 	for (pos = 0; pos < 32; pos++) {
216 		if (!(pan[pos*2+1] & 0xF9)) pattern->n_entries++;
217 		if (vol[pos] != -1) pattern->n_entries++;
218 	}
219 
220 	pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry));
221 	if (!pattern->entry) return -1;
222 
223 	entry = pattern->entry;
224 
225 	if (speed) {
226 		entry->channel = 0;
227 		entry->mask = IT_ENTRY_EFFECT;
228 		entry->effect = IT_SET_SPEED;
229 		entry->effectvalue = speed;
230 		entry++;
231 	}
232 
233 	if (bpm >= 0x20) {
234 		entry->channel = 0;
235 		entry->mask = IT_ENTRY_EFFECT;
236 		entry->effect = IT_SET_SONG_TEMPO;
237 		entry->effectvalue = bpm;
238 		entry++;
239 	}
240 
241 	for (pos = 0; pos < 32; pos++) {
242 		if (!(pan[pos*2+1] & 0xF9)) {
243 			entry->channel = pos;
244 			entry->mask = IT_ENTRY_EFFECT;
245 			switch (pan[pos*2+1]) {
246 			case 0:
247 				entry->effect = IT_SET_PANNING;
248 				entry->effectvalue = pan[pos*2] ^ 128;
249 				break;
250 			case 2:
251 				entry->effect = IT_S;
252 				entry->effectvalue = EFFECT_VALUE(IT_S_SET_SURROUND_SOUND,1);
253 				break;
254 			case 4:
255 				entry->effect = IT_SET_PANNING;
256 				entry->effectvalue = 128;
257 				break;
258 			}
259 			entry++;
260 		}
261 		if (vol[pos] != -1) {
262 			entry->channel = pos;
263 			entry->mask = IT_ENTRY_EFFECT;
264 			entry->effect = IT_SET_CHANNEL_VOLUME;
265 			entry->effectvalue = (vol[pos] + 2) >> 2;
266 			entry++;
267 		}
268 	}
269 
270 	row = 0;
271 	pos = 2;
272 	rowlen = data[0] | (data[1] << 8);
273 
274 	while ((row < nrows) && (pos < len)) {
275 		if (pos >= rowlen) {
276 			IT_SET_END_ROW(entry);
277 			entry++;
278 			row++;
279 			rowlen += data[pos] | (data[pos+1] << 8);
280 			pos += 2;
281 			continue;
282 		}
283 
284 		flags = data[pos++];
285 		entry->channel = data[pos++];
286 		entry->mask = 0;
287 
288 		if (flags & 0xF0) {
289 			if (flags & 0x80) {
290 				entry->mask |= IT_ENTRY_NOTE;
291 				if (version == PSMV_OLD) {
292 					if ((data[pos] < 0x80)) entry->note = (data[pos]>>4)*12+(data[pos]&0x0f)+12;
293 					else entry->mask &= ~IT_ENTRY_NOTE;
294 				} else /*if (version == PSMV_NEW)*/ {
295 					if ((data[pos]) && (data[pos] < 84)) entry->note = data[pos] + 35;
296 					else entry->mask &= ~IT_ENTRY_NOTE;
297 				}
298 				pos++;
299 			}
300 
301 			if (flags & 0x40) {
302 				entry->mask |= IT_ENTRY_INSTRUMENT;
303 				entry->instrument = data[pos++] + 1;
304 			}
305 
306 			if (flags & 0x20) {
307 				entry->mask |= IT_ENTRY_VOLPAN;
308 				entry->volpan = (data[pos++] + 1) >> 1;
309 			}
310 
311 			if (flags & 0x10) {
312 				entry->mask |= IT_ENTRY_EFFECT;
313 				length = data[pos+1];
314 				switch (data[pos]) {
315 					case 1:
316 						entry->effect = IT_VOLUME_SLIDE;
317 						if (version == PSMV_OLD) entry->effectvalue = ((length&0x1e)<<3) | 0xF;
318 						else /*if (version == PSMV_NEW)*/ entry->effectvalue = (length<<4) | 0xF;
319 						break;
320 
321 					case 2:
322 						entry->effect = IT_VOLUME_SLIDE;
323 						if (version == PSMV_OLD) entry->effectvalue = (length << 3) & 0xF0;
324 						else /*if (version == PSMV_NEW)*/ entry->effectvalue = (length << 4) & 0xF0;
325 						break;
326 
327 					case 3:
328 						entry->effect = IT_VOLUME_SLIDE;
329 						if (version == PSMV_OLD) entry->effectvalue = (length >> 1) | 0xF0;
330 						else /*if (version == PSMV_NEW)*/ entry->effectvalue = length | 0xF0;
331 						break;
332 
333 					case 4:
334 						entry->effect = IT_VOLUME_SLIDE;
335 						if (version == PSMV_OLD) entry->effectvalue = (length >> 1) & 0xF;
336 						else /*if (version == PSMV_NEW)*/ entry->effectvalue = length & 0xF;
337 						break;
338 
339 					case 12:
340 						entry->effect = IT_PORTAMENTO_UP;
341 						if (version == PSMV_OLD) {
342 							if (length < 4) entry->effectvalue = length | 0xF0;
343 							else entry->effectvalue = length >> 2;
344 						} else /*if (version == PSMV_NEW)*/ {
345 							entry->effectvalue = length;
346 						}
347 						break;
348 
349 					case 14:
350 						entry->effect = IT_PORTAMENTO_DOWN;
351 						if (version == PSMV_OLD) {
352 							if (length < 4) entry->effectvalue = length | 0xF0;
353 							else entry->effectvalue = length >> 2;
354 						} else /*if (version == PSMV_NEW)*/ {
355 							entry->effectvalue = length;
356 						}
357 						break;
358 
359 					case 15:
360 						entry->effect = IT_TONE_PORTAMENTO;
361 						if (version == PSMV_OLD) entry->effectvalue = length >> 2;
362 						else /*if (version == PSMV_NEW)*/ entry->effectvalue = length;
363 						break;
364 
365 					case 0x15:
366 						entry->effect = IT_VIBRATO;
367 						entry->effectvalue = length;
368 						break;
369 
370 					case 0x18:
371 						entry->effect = IT_VOLSLIDE_VIBRATO;
372 						entry->effectvalue = length;
373 						break;
374 
375 					case 0x29:
376 						entry->effect = IT_SET_SAMPLE_OFFSET;
377 						entry->effectvalue = data[pos+2];
378 						pos += 2;
379 						break;
380 
381 					case 0x2A:
382 						entry->effect = IT_RETRIGGER_NOTE;
383 						entry->effectvalue = length;
384 						break;
385 
386 					case 0x33:
387 #if 0
388 						entry->effect = IT_POSITION_JUMP;
389 						entry->effectvalue = data[pos+2];
390 #else
391 						entry->mask &= ~IT_ENTRY_EFFECT;
392 #endif
393 						pos++;
394 						break;
395 
396 					case 0x34:
397 						entry->effect = IT_BREAK_TO_ROW;
398 						entry->effectvalue = length;
399 						break;
400 
401 					case 0x3D:
402 						entry->effect = IT_SET_SPEED;
403 						entry->effectvalue = length;
404 						break;
405 
406 					case 0x3E:
407 						if (length >= 0x20) {
408 							entry->effect = IT_SET_SONG_TEMPO;
409 							entry->effectvalue = length;
410 						} else {
411 							entry->mask &= ~IT_ENTRY_EFFECT;
412 						}
413 						break;
414 
415 					case 0x47:
416 						entry->effect = IT_ARPEGGIO;
417 						entry->effectvalue = length;
418 						break;
419 
420 					default:
421 						return -1;
422 				}
423 				pos += 2;
424 			}
425 			if (entry->mask) entry++;
426 		}
427 	}
428 
429 	while (row < nrows) {
430 		IT_SET_END_ROW(entry);
431 		entry++;
432 		row++;
433 	}
434 
435 	pattern->n_entries = entry - pattern->entry;
436 	if (!pattern->n_entries) return -1;
437 
438 	return 0;
439 }
440 
441 
free_chunks(PSMCHUNK * chunk,int count)442 static void free_chunks(PSMCHUNK * chunk, int count) {
443 	int n;
444 
445 	for (n = 0; n < count; n++) {
446 		if (chunk[n].data)
447 			free(chunk[n].data);
448 	}
449 
450 	free(chunk);
451 }
452 
453 static void dumb_it_optimize_orders(DUMB_IT_SIGDATA * sigdata);
454 
455 static int pattcmp( const unsigned char *, const unsigned char *, size_t );
456 
it_psm_load_sigdata(DUMBFILE * f,int * ver,int subsong)457 static DUMB_IT_SIGDATA *it_psm_load_sigdata(DUMBFILE *f, int * ver, int subsong)
458 {
459 	DUMB_IT_SIGDATA *sigdata;
460 
461 	PSMCHUNK *chunk;
462 	int n_chunks = 0;
463 
464 	PSMCHUNK *songchunk;
465 	int n_song_chunks = 0;
466 
467 	PSMEVENT *event = 0;
468 	int n_events = 0;
469 
470 	unsigned char * ptr;
471 
472 	int n, length, o;
473 
474 	int found;
475 
476 	int n_patterns = 0;
477 
478 	int first_pattern_line = -1;
479 	int first_pattern;
480 
481 	int speed, bpm;
482 	unsigned char pan[64];
483 	int vol[32];
484 
485 	if (dumbfile_mgetl(f) != DUMB_ID('P','S','M',' ')) goto error;
486 
487 	length = dumbfile_igetl(f);
488 
489 	if (dumbfile_mgetl(f) != DUMB_ID('F','I','L','E')) goto error;
490 
491 	chunk = calloc(768, sizeof(*chunk));
492 
493 	while (length >= 8) {
494 		chunk[n_chunks].id = dumbfile_mgetl(f);
495 		n = dumbfile_igetl(f);
496 		length -= 8;
497 		if (n < 0 || n > length)
498 			goto error_fc;
499 		chunk[n_chunks].len = n;
500 		if (n) {
501 			ptr = malloc(n);
502 			if (!ptr) goto error_fc;
503             if (dumbfile_getnc((char *)ptr, n, f) < n)
504 			{
505 				free(ptr);
506 				goto error_fc;
507 			}
508 			chunk[n_chunks].data = ptr;
509 		}
510 		n_chunks++;
511 		length -= n;
512 	}
513 
514 	if (!n_chunks) goto error_fc;
515 
516 	sigdata = malloc(sizeof(*sigdata));
517 	if (!sigdata) goto error_fc;
518 
519 	sigdata->n_patterns = 0;
520 	sigdata->n_samples = 0;
521 	sigdata->name[0] = 0;
522 
523 	found = 0;
524 
525 	for (n = 0; n < n_chunks; n++) {
526 		PSMCHUNK * c = &chunk[n];
527 		switch(c->id) {
528 		case DUMB_ID('S','D','F','T'):
529 			/* song data format? */
530 			if ((found & 1) || (c->len != 8) || memcmp(c->data, "MAINSONG", 8)) goto error_sd;
531 			found |= 1;
532 			break;
533 
534 		case DUMB_ID('S','O','N','G'):
535 			if (/*(found & 2) ||*/ (c->len < 11) /*|| memcmp(c->data, "MAINSONG", 8)*/) goto error_sd;
536 			found |= 2;
537 			break;
538 
539 		case DUMB_ID('D','S','M','P'):
540 			sigdata->n_samples++;
541 			break;
542 
543 		case DUMB_ID('T','I','T','L'):
544             length = min(sizeof(sigdata->name) - 1, (unsigned)c->len);
545 			memcpy(sigdata->name, c->data, length);
546 			sigdata->name[length] = 0;
547 		}
548 	}
549 
550 	if (found != 3 || !sigdata->n_samples) goto error_sd;
551 
552 	sigdata->song_message = NULL;
553 	sigdata->order = NULL;
554 	sigdata->instrument = NULL;
555 	sigdata->sample = NULL;
556 	sigdata->pattern = NULL;
557 	sigdata->midi = NULL;
558 	sigdata->checkpoint = NULL;
559 
560 	sigdata->n_instruments = 0;
561 	sigdata->n_orders = 0;
562 
563 	for (n = 0; n < n_chunks; n++) {
564 		PSMCHUNK * c = &chunk[n];
565 		if (c->id == DUMB_ID('S','O','N','G')) {
566 			if (subsong == 0) break;
567 			subsong--;
568 		}
569 	}
570 
571 	if (n == n_chunks) return NULL;
572 	subsong = n;
573 
574 	/*for (n = 0; n < n_chunks; n++) {
575 		PSMCHUNK * c = &chunk[n];
576 		if (c->id == DUMB_ID('S','O','N','G')) {*/
577 	{
578 		PSMCHUNK * c = &chunk[subsong];
579 		{
580 			ptr = c->data;
581 			if (ptr[10] > 32) goto error_usd;
582 			sigdata->n_pchannels = ptr[10];
583 			length = c->len - 11;
584 			ptr += 11;
585 			songchunk = 0;
586 			if (length >= 8) {
587 				songchunk = malloc(128 * sizeof(*songchunk));
588 				if (!songchunk) goto error_usd;
589 				while (length >= 8) {
590 					songchunk[n_song_chunks].id = DUMB_ID(ptr[0], ptr[1], ptr[2], ptr[3]);
591 					n = ptr[4] | (ptr[5] << 8) | (ptr[6] << 16) | (ptr[7] << 24);
592 					length -= 8;
593 					if (n > length) goto error_sc;
594 					songchunk[n_song_chunks].len = n;
595 					songchunk[n_song_chunks].data = ptr + 8;
596 					n_song_chunks++;
597 					length -= n;
598 					ptr += 8 + n;
599 				}
600 			}
601 			/*break;*/
602 		}
603 	}
604 
605 	if (!n_song_chunks) goto error_sc;
606 
607 	found = 0;
608 
609 	for (n = 0; n < n_song_chunks; n++) {
610 		PSMCHUNK * c = &songchunk[n];
611 
612 		if (c->id == DUMB_ID('D','A','T','E')) {
613 			/* date of the library build / format spec */
614 			if (c->len == 6) {
615 				length = c->len;
616 				ptr = c->data;
617 				while (length > 0) {
618 					if (*ptr >= '0' && *ptr <= '9') {
619 						found = (found * 10) + (*ptr - '0');
620 					} else {
621 						found = 0;
622 						break;
623 					}
624 					ptr++;
625 					length--;
626 				}
627 			}
628 			break;
629 		}
630 	}
631 
632 	/*
633 	if (found != 940506 &&
634 		found != 940509 &&
635 		found != 940510 &&
636 		found != 940530 &&
637 		found != 940629 &&
638 		found != PSMV_OLD &&
639 		found != 941011 &&
640 		found != PSMV_NEW &&
641 		found != 940906 &&
642 		found != 940903 &&
643 		found != 940914 &&
644 		found != 941213 &&
645         found != 800211)    WTF?
646 		goto error_sc;
647 	*/
648 
649 	*ver = found;
650 
651 	if (found == 800211 ||
652 		found == PSMV_NEW ||
653 		found == 940903 ||
654 		found == 940906 ||
655 		found == 940914 ||
656 		found == 941213) found = PSMV_NEW;
657 	else found = PSMV_OLD;
658 
659 	memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);
660 
661 	for (n = 0; n < DUMB_IT_N_CHANNELS; n += 4) {
662 		int sep = 32 * dumb_it_default_panning_separation / 100;
663 		sigdata->channel_pan[n  ] = 32 - sep;
664 		sigdata->channel_pan[n+1] = 32 + sep;
665 		sigdata->channel_pan[n+2] = 32 + sep;
666 		sigdata->channel_pan[n+3] = 32 - sep;
667 	}
668 
669 	for (n = 0; n < n_song_chunks; n++) {
670 		PSMCHUNK * c = &songchunk[n];
671 
672 		switch (c->id) {
673 			case DUMB_ID('O','P','L','H'):
674 				if (c->len < 2) goto error_sc;
675 				ptr = c->data;
676 				o = ptr[0] | (ptr[1] << 8);
677 				if (!o) goto error_sc;
678 				event = malloc(o * sizeof(*event));
679 				if (!event) goto error_sc;
680 				length = c->len - 2;
681 				ptr += 2;
682 				while ((length > 0) && (n_events < o)) {
683 					event[n_events].type = *ptr;
684 					switch (*ptr) {
685 					case PSM_EVENT_END:
686 						ptr++;
687 						length--;
688 						break;
689 
690 					case PSM_EVENT_PLAY_PATTERN:
691 						if (found == PSMV_OLD) {
692 							if (length < 5) goto error_ev;
693 							memcpy(event[n_events].data, ptr + 1, 4);
694 							ptr += 5;
695 							length -= 5;
696 						} else /*if (found == PSMV_NEW)*/ {
697 							if (length < 9) goto error_ev;
698 							memcpy(event[n_events].data, ptr + 1, 8);
699 							ptr += 9;
700 							length -= 9;
701 						}
702 						break;
703 
704 					case PSM_EVENT_SET_SPEED:
705 					case PSM_EVENT_SET_BPM:
706 						if (length < 2) goto error_ev;
707 						event[n_events].data[0] = ptr[1];
708 						ptr += 2;
709 						length -= 2;
710 						break;
711 
712 					case PSM_EVENT_JUMP_TO_LINE:
713 					case PSM_EVENT_CHANGE_VOL:
714 						if (length < 3) goto error_ev;
715 						memcpy(event[n_events].data, ptr + 1, 2);
716 						ptr += 3;
717 						length -= 3;
718 						break;
719 
720 					case PSM_EVENT_SAMPLE_MAP_TABLE:
721 						if (length < 7) goto error_ev;
722 						memcpy(event[n_events].data, ptr + 1, 6);
723 						ptr += 7;
724 						length -= 7;
725 						break;
726 
727 					case PSM_EVENT_CHANGE_PAN:
728 						if (length < 4) goto error_ev;
729 						memcpy(event[n_events].data, ptr + 1, 3);
730 						ptr += 4;
731 						length -= 4;
732 						break;
733 
734 					default:
735 						goto error_ev;
736 					}
737 					n_events++;
738 				}
739 				break;
740 
741 			case DUMB_ID('P','P','A','N'):
742 				length = c->len;
743 				if (length & 1) goto error_ev;
744 				ptr = c->data;
745 				o = 0;
746 				while (length > 0) {
747 					switch (ptr[0]) {
748 					case 0:
749 						sigdata->channel_pan[o] = ((((int)(signed char)ptr[1]) * 32) / 127) + 32;
750 						break;
751 					case 2:
752 						sigdata->channel_pan[o] = IT_SURROUND;
753 						break;
754 					case 4:
755 						sigdata->channel_pan[o] = 32;
756 						break;
757 					}
758 					ptr += 2;
759 					length -= 2;
760 					if (++o >= DUMB_IT_N_CHANNELS) break;
761 				}
762 				break;
763 
764 			/*
765 			case DUMB_ID('P','A','T','T'):
766 			case DUMB_ID('D','S','A','M'):
767 			*/
768 		}
769 	}
770 
771 	sigdata->flags = IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX;
772 
773 	sigdata->global_volume = 128;
774 	sigdata->speed = 6;
775 	sigdata->tempo = 125;
776 	sigdata->mixing_volume = 48;
777 	sigdata->pan_separation = 128;
778 
779 	speed = 0;
780 	bpm = 0;
781 	memset(pan, 255, sizeof(pan));
782 	memset(vol, 255, sizeof(vol));
783 
784 	sigdata->n_patterns = n_events;
785 	sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
786 	if (!sigdata->pattern) goto error_ev;
787 	for (n = 0; n < sigdata->n_patterns; n++)
788 		sigdata->pattern[n].entry = NULL;
789 
790 	for (n = 0; n < n_events; n++) {
791 		PSMEVENT * e = &event[n];
792 		switch (e->type) {
793 		case PSM_EVENT_END:
794 			n = n_events;
795 			break;
796 
797 		case PSM_EVENT_PLAY_PATTERN:
798 			for (o = 0; o < n_chunks; o++) {
799 				PSMCHUNK * c = &chunk[o];
800 				if (c->id == DUMB_ID('P','B','O','D')) {
801 					ptr = c->data;
802 					length = c->len;
803 					if (found == PSMV_OLD) {
804 						if (length < 8) goto error_ev;
805 						if (!pattcmp(ptr + 4, e->data, 4)) {
806 							if (it_psm_process_pattern(&sigdata->pattern[n_patterns], ptr, length, speed, bpm, pan, vol, found)) goto error_ev;
807 							if (first_pattern_line < 0) {
808 								first_pattern_line = n;
809 								first_pattern = o;
810 							}
811 							e->data[0] = n_patterns;
812 							e->data[1] = n_patterns >> 8;
813 							n_patterns++;
814 							break;
815 						}
816 					} else /*if (found == PSMV_NEW)*/ {
817 						if (length < 12) goto error_ev;
818 						if (!pattcmp(ptr + 4, e->data, 8)) {
819 							if (it_psm_process_pattern(&sigdata->pattern[n_patterns], ptr, length, speed, bpm, pan, vol, found)) goto error_ev;
820 							if (first_pattern_line < 0) {
821 								first_pattern_line = n;
822 								first_pattern = o;
823 							}
824 							e->data[0] = n_patterns;
825 							e->data[1] = n_patterns >> 8;
826 							n_patterns++;
827 							break;
828 						}
829 					}
830 				}
831 			}
832 			if (o == n_chunks) goto error_ev;
833 
834 			speed = 0;
835 			bpm = 0;
836 			memset(pan, 255, sizeof(pan));
837 			memset(vol, 255, sizeof(vol));
838 
839 			e->type = PSM_EVENT_END;
840 			break;
841 
842 		case PSM_EVENT_JUMP_TO_LINE:
843 			o = e->data[0] | (e->data[1] << 8);
844 			if (o >= n_events) goto error_ev;
845 			if (o == 0) {
846 				/* whew! easy case! */
847 				sigdata->restart_position = 0;
848 				n = n_events;
849 			} else if (o == n) {
850 				/* freeze */
851 				n = n_events;
852 			} else if (o > n) {
853 				/* jump ahead, setting played event numbers to zero will prevent endless looping */
854 				n = o - 1;
855 			} else if (o >= first_pattern_line) {
856 				/* another semi-easy case */
857 				sigdata->restart_position = event[o].data[0] | (event[o].data[1] << 8);
858 				n = n_events;
859 			} else {
860 				/* crud, try to simulate rerunning all of the commands from the indicated
861 				 * line up to the first pattern, then dupe the first pattern again.
862 				 */
863 				/*
864 				PSMCHUNK * c = &chunk[first_pattern];
865 
866 				for (; o < first_pattern_line; o++) {
867 					PSMEVENT * ev = &event[o];
868 					switch (ev->type) {
869 					case PSM_EVENT_SET_SPEED:
870 						speed = ev->data[0];
871 						break;
872 					case PSM_EVENT_SET_BPM:
873 						bpm = ev->data[0];
874 						break;
875 					case PSM_EVENT_CHANGE_PAN:
876 						if (ev->data[0] > 31) goto error_ev;
877 						pan[ev->data[0] * 2] = ev->data[1];
878 						pan[ev->data[0] * 2 + 1] = ev->data[2];
879 						break;
880 					case PSM_EVENT_CHANGE_VOL:
881 						if (ev->data[0] > 31) goto error_ev;
882 						vol[ev->data[0]] = ev->data[1];
883 						break;
884 					}
885 				}
886 
887 				if (it_psm_process_pattern(&sigdata->pattern[n_patterns], c->data, c->len, speed, bpm, pan, vol, found)) goto error_ev;
888 				n_patterns++;
889 				sigdata->restart_position = 1;
890 				n = n_events;
891 
892 				Eh, what the hell? PSM has no panning commands anyway.
893 				*/
894 				sigdata->restart_position = 0;
895 				n = n_events;
896 			}
897 			e->type = PSM_EVENT_END;
898 			break;
899 
900 		case PSM_EVENT_SET_SPEED:
901 			speed = e->data[0];
902 			break;
903 
904 		case PSM_EVENT_SET_BPM:
905 			bpm = e->data[0];
906 			break;
907 
908 		case PSM_EVENT_CHANGE_PAN:
909 			o = e->data[0];
910 			if (o > 31) goto error_ev;
911 			pan[o * 2] = e->data[1];
912 			pan[o * 2 + 1] = e->data[2];
913 			break;
914 
915 		case PSM_EVENT_CHANGE_VOL:
916 			o = e->data[0];
917 			if (o > 31) goto error_ev;
918 			vol[o] = e->data[1];
919 			break;
920 
921 		case PSM_EVENT_SAMPLE_MAP_TABLE:
922 			if (e->data[0] != 0 || e->data[1] != 0xFF ||
923 				e->data[2] != 0 || e->data[3] != 0 ||
924 				e->data[4] != 1 || e->data[5] != 0)
925 				goto error_ev;
926 			break;
927 		}
928 	}
929 
930 	if (n_patterns > 256) goto error_ev;
931 
932 	sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
933 	if (!sigdata->sample) goto error_ev;
934 	for (n = 0; n < sigdata->n_samples; n++) {
935 		sigdata->sample[n].data = NULL;
936 		sigdata->sample[n].flags = 0;
937 	}
938 
939 	o = 0;
940 	for (n = 0; n < n_chunks; n++) {
941 		PSMCHUNK * c = &chunk[n];
942 		if (c->id == DUMB_ID('D','S','M','P')) {
943 			if (it_psm_process_sample(&sigdata->sample[o], c->data, c->len, o, found)) goto error_ev;
944 			o++;
945 		}
946 	}
947 
948 	sigdata->n_orders = n_patterns;
949 	sigdata->n_patterns = n_patterns;
950 
951 	sigdata->order = malloc(n_patterns);
952 
953 	for (n = 0; n < n_patterns; n++) {
954 		sigdata->order[n] = n;
955 	}
956 
957 	free(event);
958 	free(songchunk);
959 	free_chunks(chunk, n_chunks);
960 
961 	_dumb_it_fix_invalid_orders(sigdata);
962 
963 	dumb_it_optimize_orders(sigdata);
964 
965 	return sigdata;
966 
967 error_ev:
968 	free(event);
969 error_sc:
970 	if (songchunk) free(songchunk);
971 error_usd:
972 	_dumb_it_unload_sigdata(sigdata);
973 	goto error_fc;
974 error_sd:
975 	free(sigdata);
976 error_fc:
977 	free_chunks(chunk, n_chunks);
978 error:
979 	return NULL;
980 }
981 
it_order_compare(const void * e1,const void * e2)982 static int it_order_compare(const void *e1, const void *e2) {
983 	if (*((const char *)e1) < *((const char *)e2))
984 		return -1;
985 
986 	if (*((const char *)e1) > *((const char *)e2))
987 		return 1;
988 
989 	return 0;
990 }
991 
992 /*
993 static int it_optimize_compare(const void *e1, const void *e2) {
994 	if (((const IT_ENTRY *)e1)->channel < ((const IT_ENTRY *)e2)->channel)
995 		return -1;
996 
997 	if (((const IT_ENTRY *)e1)->channel > ((const IT_ENTRY *)e2)->channel)
998 		return 1;
999 
1000 	return 0;
1001 }
1002 */
1003 
it_entry_compare(const IT_ENTRY * e1,const IT_ENTRY * e2)1004 static int it_entry_compare(const IT_ENTRY * e1, const IT_ENTRY * e2) {
1005 	if (IT_IS_END_ROW(e1) && IT_IS_END_ROW(e2)) return 1;
1006 	if (e1->channel != e2->channel) return 0;
1007 	if (e1->mask != e2->mask) return 0;
1008 	if ((e1->mask & IT_ENTRY_NOTE) && (e1->note != e2->note)) return 0;
1009 	if ((e1->mask & IT_ENTRY_INSTRUMENT) && (e1->instrument != e2->instrument)) return 0;
1010 	if ((e1->mask & IT_ENTRY_VOLPAN) && (e1->volpan != e2->volpan)) return 0;
1011 	if ((e1->mask & IT_ENTRY_EFFECT) && ((e1->effect != e2->effect) || (e1->effectvalue != e2->effectvalue))) return 0;
1012 	return 1;
1013 }
1014 
1015 /*
1016 static void dumb_it_optimize_pattern(IT_PATTERN * pattern) {
1017 	IT_ENTRY * entry, * end;
1018 	IT_ENTRY * rowstart, * rowend;
1019 	IT_ENTRY * current;
1020 
1021 	if (!pattern->n_entries || !pattern->entry) return;
1022 
1023 	current = entry = pattern->entry;
1024 	end = entry + pattern->n_entries;
1025 
1026 	while (entry < end) {
1027 		rowstart = entry;
1028 		while (!IT_IS_END_ROW(entry)) entry++;
1029 		rowend = entry;
1030 		if (rowend > rowstart + 1)
1031 			qsort(rowstart, rowend - rowstart, sizeof(IT_ENTRY), &it_optimize_compare);
1032 		entry = rowstart;
1033 		while (entry < rowend) {
1034 			if (!(entry->mask)) {}
1035 			else if (it_entry_compare(entry, current)) {}
1036 			else if (!(current->mask) ||
1037 					 ((entry->channel == current->channel) &&
1038 					 ((entry->mask | current->mask) == (entry->mask ^ current->mask)))) {
1039 				current->mask |= entry->mask;
1040 				if (entry->mask & IT_ENTRY_NOTE) current->note = entry->note;
1041 				if (entry->mask & IT_ENTRY_INSTRUMENT) current->instrument = entry->instrument;
1042 				if (entry->mask & IT_ENTRY_VOLPAN) current->volpan = entry->volpan;
1043 				if (entry->mask & IT_ENTRY_EFFECT) {
1044 					current->effect = entry->effect;
1045 					current->effectvalue = entry->effectvalue;
1046 				}
1047 			} else {
1048 				if (++current < entry) *current = *entry;
1049 			}
1050 			entry++;
1051 		}
1052 		if (++current < entry) *current = *entry;
1053 		entry++;
1054 	}
1055 
1056 	current++;
1057 
1058 	if (current < end) {
1059 		IT_ENTRY * opt;
1060 		pattern->n_entries = current - pattern->entry;
1061 		opt = realloc(pattern->entry, pattern->n_entries * sizeof(*pattern->entry));
1062 		if (opt) pattern->entry = opt;
1063 	}
1064 }
1065 */
1066 
it_pattern_compare(const IT_PATTERN * p1,const IT_PATTERN * p2)1067 static int it_pattern_compare(const IT_PATTERN * p1, const IT_PATTERN * p2) {
1068 	IT_ENTRY * e1, * end;
1069 	IT_ENTRY * e2;
1070 
1071 	if (p1 == p2) return 1;
1072 	if (p1->n_entries != p2->n_entries) return 0;
1073 
1074 	e1 = p1->entry; end = e1 + p1->n_entries;
1075 	e2 = p2->entry;
1076 
1077 	while (e1 < end) {
1078 		if (!it_entry_compare(e1, e2)) return 0;
1079 		e1++; e2++;
1080 	}
1081 
1082 	return 1;
1083 }
1084 
dumb_it_optimize_orders(DUMB_IT_SIGDATA * sigdata)1085 static void dumb_it_optimize_orders(DUMB_IT_SIGDATA * sigdata) {
1086 	int n, o, p;
1087 
1088     /*int last_invalid = (sigdata->flags & IT_WAS_AN_XM) ? 255 : 253;*/
1089 
1090 	unsigned char * order_list;
1091 	int n_patterns;
1092 
1093 	IT_PATTERN * pattern;
1094 
1095 	if (!sigdata->n_orders || !sigdata->n_patterns) return;
1096 
1097 	n_patterns = 0;
1098 	order_list = malloc(sigdata->n_orders);
1099 
1100 	if (!order_list) return;
1101 
1102 	for (n = 0; n < sigdata->n_orders; n++) {
1103 		if (sigdata->order[n] < sigdata->n_patterns) {
1104 			for (o = 0; o < n_patterns; o++) {
1105 				if (sigdata->order[n] == order_list[o]) break;
1106 			}
1107 			if (o == n_patterns) {
1108 				order_list[n_patterns++] = sigdata->order[n];
1109 			}
1110 		}
1111 	}
1112 
1113 	if (!n_patterns) {
1114 		free(order_list);
1115 		return;
1116 	}
1117 
1118 	/*for (n = 0; n < n_patterns; n++) {
1119 		dumb_it_optimize_pattern(&sigdata->pattern[order_list[n]]);
1120 	}*/
1121 
1122 	for (n = 0; n < n_patterns; n++) {
1123 		for (o = n + 1; o < n_patterns; o++) {
1124 			if ((order_list[n] != order_list[o]) &&
1125 				it_pattern_compare(&sigdata->pattern[order_list[n]], &sigdata->pattern[order_list[o]])) {
1126 				for (p = 0; p < sigdata->n_orders; p++) {
1127 					if (sigdata->order[p] == order_list[o]) {
1128 						sigdata->order[p] = order_list[n];
1129 					}
1130 				}
1131 				for (p = o + 1; p < n_patterns; p++) {
1132 					if (order_list[p] == order_list[o]) {
1133 						order_list[p] = order_list[n];
1134 					}
1135 				}
1136 				order_list[o] = order_list[n];
1137 			}
1138 		}
1139 	}
1140 
1141 	qsort(order_list, n_patterns, sizeof(*order_list), &it_order_compare);
1142 
1143 	for (n = 0, o = 0; n < n_patterns; n++) {
1144 		if (order_list[n] != order_list[o]) {
1145 			if (++o < n) order_list[o] = order_list[n];
1146 		}
1147 	}
1148 
1149 	n_patterns = o + 1;
1150 
1151 	pattern = malloc(n_patterns * sizeof(*pattern));
1152 	if (!pattern) {
1153 		free(order_list);
1154 		return;
1155 	}
1156 
1157 	for (n = 0; n < n_patterns; n++) {
1158 		pattern[n] = sigdata->pattern[order_list[n]];
1159 	}
1160 
1161 	for (n = 0; n < sigdata->n_patterns; n++) {
1162 		for (o = 0; o < n_patterns; o++) {
1163 			if (order_list[o] == n) break;
1164 		}
1165 		if (o == n_patterns) {
1166 			if (sigdata->pattern[n].entry)
1167 				free(sigdata->pattern[n].entry);
1168 		}
1169 	}
1170 
1171 	free(sigdata->pattern);
1172 	sigdata->pattern = pattern;
1173 	sigdata->n_patterns = n_patterns;
1174 
1175 	for (n = 0; n < sigdata->n_orders; n++) {
1176 		for (o = 0; o < n_patterns; o++) {
1177 			if (sigdata->order[n] == order_list[o]) {
1178 				sigdata->order[n] = o;
1179 				break;
1180 			}
1181 		}
1182 	}
1183 
1184 	free(order_list);
1185 }
1186 
dumb_get_psm_subsong_count(DUMBFILE * f)1187 int dumb_get_psm_subsong_count(DUMBFILE *f) {
1188 	int length, subsongs;
1189 	long l;
1190 
1191 	if (dumbfile_mgetl(f) != DUMB_ID('P','S','M',' ')) return 0;
1192 
1193 	length = dumbfile_igetl(f);
1194 
1195 	if (dumbfile_mgetl(f) != DUMB_ID('F','I','L','E')) return 0;
1196 
1197 	subsongs = 0;
1198 
1199 	while (length >= 8 && !dumbfile_error(f)) {
1200 		if (dumbfile_mgetl(f) == DUMB_ID('S','O','N','G')) subsongs++;
1201 		l = dumbfile_igetl(f);
1202 		dumbfile_skip(f, l);
1203 		length -= l + 8;
1204 	}
1205 
1206 	if (dumbfile_error(f)) return 0;
1207 
1208 	return subsongs;
1209 }
1210 
1211 
1212 
1213 /* Eww */
pattcmp(const unsigned char * a,const unsigned char * b,size_t l)1214 int pattcmp( const unsigned char * a, const unsigned char * b, size_t l )
1215 {
1216     size_t i, j, na, nb;
1217 	char * p;
1218 
1219 	na = nb = 0;
1220 
1221 	i = memcmp( a, b, l );
1222 	if ( !i ) return i;
1223 
1224 	/* damnit */
1225 
1226 	for ( i = 0; i < l; ++i )
1227 	{
1228 		if ( a [i] >= '0' && a [i] <= '9' ) break;
1229 	}
1230 
1231 	if ( i < l )
1232 	{
1233 		na = strtoul( (const char *)a + i, &p, 10 );
1234 		if ( (const unsigned char *)p == a + i ) return 1;
1235 	}
1236 
1237 	for ( j = 0; j < l; ++j )
1238 	{
1239 		if ( b [j] >= '0' && b [j] <= '9' ) break;
1240 	}
1241 
1242 	if ( j < l )
1243 	{
1244 		nb = strtoul( (const char *)b + j, &p, 10 );
1245 		if ( (const unsigned char *)p == b + j ) return -1;
1246 	}
1247 
1248 	if ( i < j ) return -1;
1249 	else if ( i > j ) return 1;
1250 
1251 	i = memcmp( a, b, j );
1252 	if ( i ) return i;
1253 
1254 	return na - nb;
1255 }
1256 
1257 
1258 
dumb_read_psm_quick(DUMBFILE * f,int subsong)1259 DUH *dumb_read_psm_quick(DUMBFILE *f, int subsong)
1260 {
1261 	sigdata_t *sigdata;
1262 	int ver;
1263 
1264 	DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
1265 
1266 	sigdata = it_psm_load_sigdata(f, &ver, subsong);
1267 
1268 	if (!sigdata)
1269 		return NULL;
1270 
1271 	{
1272 		int n_tags = 2;
1273 		char version[16];
1274 		const char *tag[3][2];
1275 		tag[0][0] = "TITLE";
1276         tag[0][1] = (const char *)(((DUMB_IT_SIGDATA *)sigdata)->name);
1277 		tag[1][0] = "FORMAT";
1278 		tag[1][1] = "PSM";
1279 		if ( ver )
1280 		{
1281 			tag[2][0] = "FORMATVERSION";
1282             snprintf( version, 15, "%d", ver );
1283             version[15] = 0;
1284 			tag[2][1] = (const char *) &version;
1285 			++n_tags;
1286 		}
1287 		return make_duh(-1, n_tags, (const char *const (*)[2])tag, 1, &descptr, &sigdata);
1288 	}
1289 }
1290