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 #include <limits.h>
24 #include "loader.h"
25 #include "period.h"
26 
27 #define STM_TYPE_SONG	0x01
28 #define STM_TYPE_MODULE	0x02
29 
30 struct stm_instrument_header {
31 	uint8 name[12];		/* ASCIIZ instrument name */
32 	uint8 id;		/* Id=0 */
33 	uint8 idisk;		/* Instrument disk */
34 	uint16 rsvd1;		/* Reserved */
35 	uint16 length;		/* Sample length */
36 	uint16 loopbeg;		/* Loop begin */
37 	uint16 loopend;		/* Loop end */
38 	uint8 volume;		/* Playback volume */
39 	uint8 rsvd2;		/* Reserved */
40 	uint16 c2spd;		/* C4 speed */
41 	uint32 rsvd3;		/* Reserved */
42 	uint16 paralen;		/* Length in paragraphs */
43 };
44 
45 /* v1 format header based on disassembled ST2 */
46 struct stm_file_subheader_v1 {
47 	uint16 insnum;		/* Number of instruments */
48 	uint16 ordnum;		/* Number of orders */
49 	uint16 patnum;		/* Number of patterns */
50 	uint16 srate;		/* Sample rate? */
51 	uint8 tempo;		/* Playback tempo */
52 	uint8 channels;		/* Number of channels */
53 	uint16 psize;		/* Pattern size */
54 	uint16 rsvd2;		/* Reserved */
55 	uint16 skip;		/* Bytes to skip */
56 };
57 
58 struct stm_file_subheader_v2 {
59 	uint8 tempo;		/* Playback tempo */
60 	uint8 patterns;		/* Number of patterns */
61 	uint8 gvol;		/* Global volume */
62 	uint8 rsvd2[13];	/* Reserved */
63 };
64 
65 struct stm_file_header {
66 	uint8 name[20];		/* ASCIIZ song name */
67 	uint8 magic[8];		/* '!Scream!' */
68 	uint8 rsvd1;		/* '\x1a' */
69 	uint8 type;		/* 1=song, 2=module */
70 	uint8 vermaj;		/* Major version number */
71 	uint8 vermin;		/* Minor version number */
72 	union {
73 		struct stm_file_subheader_v1 v1;
74 		struct stm_file_subheader_v2 v2;
75 	} sub;
76 	struct stm_instrument_header ins[32];
77 };
78 
79 static int stm_test(HIO_HANDLE *, char *, const int);
80 static int stm_load(struct module_data *, HIO_HANDLE *, const int);
81 
82 const struct format_loader libxmp_loader_stm = {
83 	"Scream Tracker 2",
84 	stm_test,
85 	stm_load
86 };
87 
stm_test(HIO_HANDLE * f,char * t,const int start)88 static int stm_test(HIO_HANDLE * f, char *t, const int start)
89 {
90 	uint8 buf[8];
91 
92 	hio_seek(f, start + 20, SEEK_SET);
93 	if (hio_read(buf, 1, 8, f) < 8)
94 		return -1;
95 
96 	if (libxmp_test_name(buf, 8))	/* Tracker name should be ASCII */
97 		return -1;
98 
99 	if (hio_read8(f) != 0x1a)
100 		return -1;
101 
102 	if (hio_read8(f) > STM_TYPE_MODULE)
103 		return -1;
104 
105 	hio_seek(f, start + 60, SEEK_SET);
106 	if (hio_read(buf, 1, 4, f) < 4)
107 		return -1;
108 	if (!memcmp(buf, "SCRM", 4))	/* We don't want STX files */
109 		return -1;
110 
111 	hio_seek(f, start + 0, SEEK_SET);
112 	libxmp_read_title(f, t, 20);
113 
114 	return 0;
115 }
116 
117 #define FX_NONE		0xff
118 
119 /*
120  * Skaven's note from http://www.futurecrew.com/skaven/oldies_music.html
121  *
122  * FYI for the tech-heads: In the old Scream Tracker 2 the Arpeggio command
123  * (Jxx), if used in a single row with a 0x value, caused the note to skip
124  * the specified amount of halftones upwards halfway through the row. I used
125  * this in some songs to give the lead some character. However, when played
126  * in ModPlug Tracker, this effect doesn't work the way it did back then.
127  */
128 static const uint8 fx[16] = {
129 	FX_NONE,
130 	FX_SPEED,	/* A - Set tempo to [INFO]. 60 normal. */
131 	FX_JUMP,	/* B - Break pattern and jmp to order [INFO] */
132 	FX_BREAK,	/* C - Break pattern */
133 	FX_VOLSLIDE,	/* D - Slide volume; Hi-nibble=up, Lo-nibble=down */
134 	FX_PORTA_DN,	/* E - Slide down at speed [INFO] */
135 	FX_PORTA_UP,	/* F - Slide up at speed [INFO] */
136 	FX_TONEPORTA,	/* G - Slide to the note specified at speed [INFO] */
137 	FX_VIBRATO,	/* H - Vibrato; Hi-nibble, speed. Lo-nibble, size */
138 	FX_TREMOR,	/* I - Tremor; Hi-nibble, ontime. Lo-nibble, offtime */
139 	FX_ARPEGGIO,	/* J - Arpeggio */
140 	FX_NONE,
141 	FX_NONE,
142 	FX_NONE,
143 	FX_NONE,
144 	FX_NONE
145 };
146 
stm_load(struct module_data * m,HIO_HANDLE * f,const int start)147 static int stm_load(struct module_data *m, HIO_HANDLE * f, const int start)
148 {
149 	struct xmp_module *mod = &m->mod;
150 	struct xmp_event *event;
151 	struct stm_file_header sfh;
152 	uint8 b;
153 	uint16 version;
154 	int i, j;
155 
156 	LOAD_INIT();
157 
158 	hio_read(sfh.name, 20, 1, f);	/* ASCIIZ song name */
159 	hio_read(sfh.magic, 8, 1, f);	/* '!Scream!' */
160 	sfh.rsvd1 = hio_read8(f);	/* '\x1a' */
161 	sfh.type = hio_read8(f);	/* 1=song, 2=module */
162 	sfh.vermaj = hio_read8(f);	/* Major version number */
163 	sfh.vermin = hio_read8(f);	/* Minor version number */
164 	version = (100 * sfh.vermaj) + sfh.vermin;
165 
166 	if (version != 110 &&
167 	    version != 200 && version != 210 &&
168 	    version != 220 && version != 221) {
169 		D_(D_CRIT "Unknown version: %d", version);
170 		return -1;
171 	}
172 
173 	// TODO: improve robustness of the loader against bad parameters
174 
175 	if (version >= 200) {
176 		sfh.sub.v2.tempo = hio_read8(f);	/* Playback tempo */
177 		sfh.sub.v2.patterns = hio_read8(f);	/* Number of patterns */
178 		sfh.sub.v2.gvol = hio_read8(f);		/* Global volume */
179 		hio_read(sfh.sub.v2.rsvd2, 13, 1, f);	/* Reserved */
180 		mod->chn = 4;
181 		mod->pat = sfh.sub.v2.patterns;
182 		mod->spd = (version < 221) ? LSN(sfh.sub.v2.tempo / 10) : MSN(sfh.sub.v2.tempo);
183 		mod->ins = 31;
184 		mod->len = (version == 200) ? 64 : 128;
185 	} else {
186 		if ((sfh.sub.v1.insnum = hio_read16l(f)) > 32) {	/* Number of instruments */
187 			D_(D_CRIT "Wrong number of instruments: %d (max 32)", sfh.sub.v1.insnum);
188 			return -1;
189 		}
190 		if ((sfh.sub.v1.ordnum = hio_read16l(f)) > XMP_MAX_MOD_LENGTH) {	/* Number of orders */
191 			D_(D_CRIT "Wrong number of orders: %d (max %d)", sfh.sub.v1.ordnum, XMP_MAX_MOD_LENGTH);
192 			return -1;
193 		}
194 		if ((sfh.sub.v1.patnum = hio_read16l(f)) > XMP_MAX_MOD_LENGTH) {	/* Number of patterns */
195 			D_(D_CRIT "Wrong number of patterns: %d (max %d)", sfh.sub.v1.patnum, XMP_MAX_MOD_LENGTH);
196 			return -1;
197 		}
198 		sfh.sub.v1.srate = hio_read16l(f);	/* Sample rate? */
199 		sfh.sub.v1.tempo = hio_read8(f);	/* Playback tempo */
200 		if ((sfh.sub.v1.channels = hio_read8(f)) != 4) {	/* Number of channels */
201 			D_(D_CRIT "Wrong number of sound channels: %d", sfh.sub.v1.channels);
202 			return -1;
203 		}
204 		if ((sfh.sub.v1.psize = hio_read16l(f)) != 64) {	/* Pattern size */
205 			D_(D_CRIT "Wrong number of rows per pattern: %d", sfh.sub.v1.psize);
206 			return -1;
207 		}
208 		sfh.sub.v1.rsvd2 = hio_read16l(f);	/* Reserved */
209 		sfh.sub.v1.skip = hio_read16l(f);	/* Bytes to skip */
210 		hio_seek(f, sfh.sub.v1.skip, SEEK_CUR);	/* Skip bytes */
211 		mod->chn = sfh.sub.v1.channels;
212 		mod->pat = sfh.sub.v1.patnum;
213 		mod->spd = (version != 100) ? LSN(sfh.sub.v1.tempo / 10) : LSN(sfh.sub.v1.tempo);
214 		mod->ins = sfh.sub.v1.insnum;
215 		mod->len = sfh.sub.v1.ordnum;
216 	}
217 
218 	for (i = 0; i < mod->ins; i++) {
219 		hio_read(sfh.ins[i].name, 12, 1, f);	/* Instrument name */
220 		sfh.ins[i].id = hio_read8(f);		/* Id=0 */
221 		sfh.ins[i].idisk = hio_read8(f);	/* Instrument disk */
222 		sfh.ins[i].rsvd1 = hio_read16l(f);	/* Reserved */
223 		sfh.ins[i].length = hio_read16l(f);	/* Sample length */
224 		sfh.ins[i].loopbeg = hio_read16l(f);	/* Loop begin */
225 		sfh.ins[i].loopend = hio_read16l(f);	/* Loop end */
226 		sfh.ins[i].volume = hio_read8(f);	/* Playback volume */
227 		sfh.ins[i].rsvd2 = hio_read8(f);	/* Reserved */
228 		sfh.ins[i].c2spd = hio_read16l(f);	/* C4 speed */
229 		sfh.ins[i].rsvd3 = hio_read32l(f);	/* Reserved */
230 		sfh.ins[i].paralen = hio_read16l(f);	/* Length in paragraphs */
231 	}
232 
233 	if (hio_error(f)) {
234 		return -1;
235 	}
236 
237 	mod->trk = mod->pat * mod->chn;
238 	mod->smp = mod->ins;
239 	m->c4rate = C4_NTSC_RATE;
240 
241 	libxmp_copy_adjust(mod->name, sfh.name, 20);
242 
243 	if (!sfh.magic[0] || !strncmp((char *)sfh.magic, "PCSTV", 5) || !strncmp((char *)sfh.magic, "!Scream!", 8))
244 		libxmp_set_type(m, "Scream Tracker %d.%02d", sfh.vermaj, sfh.vermin);
245 	else if (!strncmp((char *)sfh.magic, "SWavePro", 8))
246 		libxmp_set_type(m, "SoundWave Pro %d.%02d", sfh.vermaj, sfh.vermin);
247 	else
248 		libxmp_copy_adjust(mod->type, sfh.magic, 8);
249 
250 	MODULE_INFO();
251 
252 	if (libxmp_init_instrument(m) < 0)
253 		return -1;
254 
255 	/* Read and convert instruments and samples */
256 	for (i = 0; i < mod->ins; i++) {
257 		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
258 			return -1;
259 
260 		mod->xxs[i].len = sfh.ins[i].length;
261 		mod->xxs[i].lps = sfh.ins[i].loopbeg;
262 		mod->xxs[i].lpe = sfh.ins[i].loopend;
263 		if (mod->xxs[i].lpe == 0xffff)
264 			mod->xxs[i].lpe = 0;
265 		mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
266 		mod->xxi[i].sub[0].vol = sfh.ins[i].volume;
267 		mod->xxi[i].sub[0].pan = 0x80;
268 		mod->xxi[i].sub[0].sid = i;
269 
270 		if (mod->xxs[i].len > 0)
271 			mod->xxi[i].nsm = 1;
272 
273 		libxmp_instrument_name(mod, i, sfh.ins[i].name, 12);
274 
275 		D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d", i,
276 		   mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
277 		   mod->xxs[i].lpe,
278 		   mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
279 		   mod->xxi[i].sub[0].vol, sfh.ins[i].c2spd);
280 
281 		libxmp_c2spd_to_note(sfh.ins[i].c2spd, &mod->xxi[i].sub[0].xpo,
282 			      &mod->xxi[i].sub[0].fin);
283 	}
284 
285 	if (hio_read(mod->xxo, 1, mod->len, f) < mod->len)
286 		return -1;
287 
288 	for (i = 0; i < mod->len; i++)
289 		if (mod->xxo[i] >= mod->pat)
290 			break;
291 
292 	mod->len = i;
293 
294 	D_(D_INFO "Module length: %d", mod->len);
295 
296 	if (libxmp_init_pattern(mod) < 0)
297 		return -1;
298 
299 	/* Read and convert patterns */
300 	D_(D_INFO "Stored patterns: %d", mod->pat);
301 
302 	for (i = 0; i < mod->pat; i++) {
303 		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
304 			return -1;
305 
306 		if (hio_error(f))
307 			return -1;
308 
309 		for (j = 0; j < 64 * mod->chn; j++) {
310 			event = &EVENT(i, j % mod->chn, j / mod->chn);
311 			b = hio_read8(f);
312 			memset(event, 0, sizeof(struct xmp_event));
313 			switch (b) {
314 			case 251:
315 			case 252:
316 				break; /* Empty note */
317 			case 253:
318 				event->note = XMP_KEY_OFF;
319 				break; /* Key off */
320 			default:
321 				if (b == 254)
322 					event->note = XMP_KEY_OFF;
323 				else if (b == 255)
324 					event->note = 0;
325 				else
326 					event->note = 1 + LSN(b) + 12 * (3 + MSN(b));
327 
328 				b = hio_read8(f);
329 				event->vol = b & 0x07;
330 				event->ins = (b & 0xf8) >> 3;
331 
332 				b = hio_read8(f);
333 				event->vol += (b & 0xf0) >> 1;
334 				if (version >= 200) {
335 					event->vol = (event->vol > 0x40) ? 0 : event->vol + 1;
336 				} else {
337 					if (event->vol > 0) {
338 						event->vol = (event->vol > 0x40) ? 1 : event->vol + 1;
339 					}
340 				}
341 
342 				event->fxt = fx[LSN(b)];
343 				event->fxp = hio_read8(f);
344 				switch (event->fxt) {
345 				case FX_SPEED:
346 					event->fxp = (version < 221) ? LSN(event->fxp / 10) : MSN(event->fxp);
347 					break;
348 				case FX_NONE:
349 					event->fxp = event->fxt = 0;
350 					break;
351 				}
352 			}
353 		}
354 	}
355 
356 	/* Read samples */
357 	D_(D_INFO "Stored samples: %d", mod->smp);
358 
359 	for (i = 0; i < mod->ins; i++) {
360 		if (!sfh.ins[i].volume || !sfh.ins[i].length) {
361 			mod->xxi[i].nsm = 0;
362 			continue;
363 		}
364 
365 		if (sfh.type == STM_TYPE_SONG) {
366 			HIO_HANDLE *s;
367 			char sn[PATH_MAX];
368 			char tmpname[32];
369 			const char *instname = mod->xxi[i].name;
370 
371 			if (!instname[0] || !m->dirname)
372 				continue;
373 
374 			if (libxmp_copy_name_for_fopen(tmpname, instname, 32))
375 				continue;
376 
377 			snprintf(sn, PATH_MAX, "%s%s", m->dirname, tmpname);
378 
379 			if ((s = hio_open(sn, "rb"))) {
380 				if (libxmp_load_sample(m, s, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0) {
381 					hio_close(s);
382 					return -1;
383 				}
384 				hio_close(s);
385 			}
386 		} else {
387 			hio_seek(f, start + (sfh.ins[i].rsvd1 << 4), SEEK_SET);
388 			if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
389 				return -1;
390 		}
391 	}
392 
393 	m->quirk |= QUIRK_VSALL | QUIRKS_ST3;
394 	m->read_event_type = READ_EVENT_ST3;
395 
396 	return 0;
397 }
398