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 "loader.h"
24 #include "iff.h"
25 #include "period.h"
26 
27 /* Galaxy Music System 5.0 module file loader
28  *
29  * Based on the format description by Dr.Eggman
30  * (http://www.jazz2online.com/J2Ov2/articles/view.php?articleID=288)
31  * and Jazz Jackrabbit modules by Alexander Brandon from Lori Central
32  * (http://www.loricentral.com/jj2music.html)
33  */
34 
35 static int gal5_test(HIO_HANDLE *, char *, const int);
36 static int gal5_load(struct module_data *, HIO_HANDLE *, const int);
37 
38 const struct format_loader libxmp_loader_gal5 = {
39 	"Galaxy Music System 5.0 (J2B)",
40 	gal5_test,
41 	gal5_load
42 };
43 
44 
45 struct local_data {
46     uint8 chn_pan[64];
47 };
48 
gal5_test(HIO_HANDLE * f,char * t,const int start)49 static int gal5_test(HIO_HANDLE *f, char *t, const int start)
50 {
51         if (hio_read32b(f) != MAGIC4('R', 'I', 'F', 'F'))
52 		return -1;
53 
54 	hio_read32b(f);
55 
56 	if (hio_read32b(f) != MAGIC4('A', 'M', ' ', ' '))
57 		return -1;
58 
59 	if (hio_read32b(f) != MAGIC4('I', 'N', 'I', 'T'))
60 		return -1;
61 
62 	hio_read32b(f);		/* skip size */
63 	libxmp_read_title(f, t, 64);
64 
65 	return 0;
66 }
67 
get_init(struct module_data * m,int size,HIO_HANDLE * f,void * parm)68 static int get_init(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
69 {
70 	struct xmp_module *mod = &m->mod;
71 	struct local_data *data = (struct local_data *)parm;
72 	char buf[64];
73 	int flags;
74 
75 	hio_read(buf, 1, 64, f);
76 	strncpy(mod->name, buf, 63);	/* ensure string terminator */
77 	mod->name[63] = '\0';
78 	libxmp_set_type(m, "Galaxy Music System 5.0");
79 	flags = hio_read8(f);	/* bit 0: Amiga period */
80 	if (~flags & 0x01)
81 		m->period_type = PERIOD_LINEAR;
82 	mod->chn = hio_read8(f);
83 	mod->spd = hio_read8(f);
84 	mod->bpm = hio_read8(f);
85 	hio_read16l(f);		/* unknown - 0x01c5 */
86 	hio_read16l(f);		/* unknown - 0xff00 */
87 	hio_read8(f);		/* unknown - 0x80 */
88 	hio_read(data->chn_pan, 1, 64, f);
89 
90 	/* Sanity check */
91 	if (mod->chn > XMP_MAX_CHANNELS)
92 		return -1;
93 
94 	return 0;
95 }
96 
get_ordr(struct module_data * m,int size,HIO_HANDLE * f,void * parm)97 static int get_ordr(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
98 {
99 	struct xmp_module *mod = &m->mod;
100 	int i;
101 
102 	mod->len = hio_read8(f) + 1;
103 	/* Don't follow Dr.Eggman's specs here */
104 
105 	for (i = 0; i < mod->len; i++)
106 		mod->xxo[i] = hio_read8(f);
107 
108 	return 0;
109 }
110 
get_patt_cnt(struct module_data * m,int size,HIO_HANDLE * f,void * parm)111 static int get_patt_cnt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
112 {
113 	struct xmp_module *mod = &m->mod;
114 	int i;
115 
116 	i = hio_read8(f) + 1;	/* pattern number */
117 
118 	if (i > mod->pat)
119 		mod->pat = i;
120 
121 	return 0;
122 }
123 
get_inst_cnt(struct module_data * m,int size,HIO_HANDLE * f,void * parm)124 static int get_inst_cnt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
125 {
126 	struct xmp_module *mod = &m->mod;
127 	int i;
128 
129 	hio_read32b(f);		/* 42 01 00 00 */
130 	hio_read8(f);		/* 00 */
131 	i = hio_read8(f) + 1;	/* instrument number */
132 
133 	/* Sanity check */
134 	if (i > MAX_INSTRUMENTS)
135 		return -1;
136 
137 	if (i > mod->ins)
138 		mod->ins = i;
139 
140 	return 0;
141 }
142 
get_patt(struct module_data * m,int size,HIO_HANDLE * f,void * parm)143 static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
144 {
145 	struct xmp_module *mod = &m->mod;
146 	struct xmp_event *event, dummy;
147 	int i, len, chan;
148 	int rows, r;
149 	uint8 flag;
150 
151 	i = hio_read8(f);	/* pattern number */
152 	len = hio_read32l(f);
153 
154 	rows = hio_read8(f) + 1;
155 
156 	/* Sanity check - don't allow duplicate patterns. */
157 	if (len < 0 || mod->xxp[i] != NULL)
158 		return -1;
159 
160 	if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
161 		return -1;
162 
163 	for (r = 0; r < rows; ) {
164 		if ((flag = hio_read8(f)) == 0) {
165 			r++;
166 			continue;
167 		}
168 		if (hio_error(f)) {
169 			return -1;
170 		}
171 
172 		chan = flag & 0x1f;
173 
174 		event = chan < mod->chn ? &EVENT(i, chan, r) : &dummy;
175 
176 		if (flag & 0x80) {
177 			uint8 fxp = hio_read8(f);
178 			uint8 fxt = hio_read8(f);
179 
180 			switch (fxt) {
181 			case 0x14:		/* speed */
182 				fxt = FX_S3M_SPEED;
183 				break;
184 			default:
185 				if (fxt > 0x0f) {
186 					D_(D_CRIT "p%d r%d c%d unknown effect %02x %02x", i, r, chan, fxt, fxp);
187 					fxt = fxp = 0;
188 				}
189 			}
190 
191 			event->fxt = fxt;
192 			event->fxp = fxp;
193 		}
194 
195 		if (flag & 0x40) {
196 			event->ins = hio_read8(f);
197 			event->note = hio_read8(f);
198 
199 			if (event->note == 128) {
200 				event->note = XMP_KEY_OFF;
201 			}
202 		}
203 
204 		if (flag & 0x20) {
205 			event->vol = 1 + hio_read8(f) / 2;
206 		}
207 	}
208 
209 	return 0;
210 }
211 
get_inst(struct module_data * m,int size,HIO_HANDLE * f,void * parm)212 static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
213 {
214 	struct xmp_module *mod = &m->mod;
215 	int i, srate, finetune, flags;
216 	int has_unsigned_sample;
217 
218 	hio_read32b(f);		/* 42 01 00 00 */
219 	hio_read8(f);		/* 00 */
220 	i = hio_read8(f);		/* instrument number */
221 
222 	/* Sanity check - don't allow duplicate instruments. */
223 	if (mod->xxi[i].nsm != 0)
224 		return -1;
225 
226 	hio_read(mod->xxi[i].name, 1, 28, f);
227 	hio_seek(f, 290, SEEK_CUR);	/* Sample/note map, envelopes */
228 	mod->xxi[i].nsm = hio_read16l(f);
229 
230 	D_(D_INFO "[%2X] %-28.28s  %2d ", i, mod->xxi[i].name, mod->xxi[i].nsm);
231 
232 	if (mod->xxi[i].nsm == 0)
233 		return 0;
234 
235 	if (libxmp_alloc_subinstrument(mod, i, mod->xxi[i].nsm) < 0)
236 		return -1;
237 
238 	/* FIXME: Currently reading only the first sample */
239 
240 	hio_read32b(f);	/* RIFF */
241 	hio_read32b(f);	/* size */
242 	hio_read32b(f);	/* AS   */
243 	hio_read32b(f);	/* SAMP */
244 	hio_read32b(f);	/* size */
245 	hio_read32b(f);	/* unknown - usually 0x40000000 */
246 
247 	hio_read(mod->xxs[i].name, 1, 28, f);
248 
249 	hio_read32b(f);	/* unknown - 0x0000 */
250 	hio_read8(f);	/* unknown - 0x00 */
251 
252 	mod->xxi[i].sub[0].sid = i;
253 	mod->xxi[i].vol = hio_read8(f);
254 	mod->xxi[i].sub[0].pan = 0x80;
255 	mod->xxi[i].sub[0].vol = (hio_read16l(f) + 1) / 512;
256 	flags = hio_read16l(f);
257 	hio_read16l(f);			/* unknown - 0x0080 */
258 	mod->xxs[i].len = hio_read32l(f);
259 	mod->xxs[i].lps = hio_read32l(f);
260 	mod->xxs[i].lpe = hio_read32l(f);
261 
262 	mod->xxs[i].flg = 0;
263 	has_unsigned_sample = 0;
264 	if (flags & 0x04)
265 		mod->xxs[i].flg |= XMP_SAMPLE_16BIT;
266 	if (flags & 0x08)
267 		mod->xxs[i].flg |= XMP_SAMPLE_LOOP;
268 	if (flags & 0x10)
269 		mod->xxs[i].flg |= XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR;
270 	if (~flags & 0x80)
271 		has_unsigned_sample = 1;
272 
273 	srate = hio_read32l(f);
274 	finetune = 0;
275 	libxmp_c2spd_to_note(srate, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
276 	mod->xxi[i].sub[0].fin += finetune;
277 
278 	hio_read32l(f);			/* 0x00000000 */
279 	hio_read32l(f);			/* unknown */
280 
281 	D_(D_INFO "  %x: %05x%c%05x %05x %c V%02x %04x %5d",
282 		0, mod->xxs[i].len,
283 		mod->xxs[i].flg & XMP_SAMPLE_16BIT ? '+' : ' ',
284 		mod->xxs[i].lps,
285 		mod->xxs[i].lpe,
286 		mod->xxs[i].flg & XMP_SAMPLE_LOOP_BIDIR ? 'B' :
287 			mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
288 		mod->xxi[i].sub[0].vol, flags, srate);
289 
290 	if (mod->xxs[i].len > 1) {
291 		if (libxmp_load_sample(m, f, has_unsigned_sample ?
292 				SAMPLE_FLAG_UNS : 0, &mod->xxs[i], NULL) < 0)
293 			return -1;
294 	}
295 
296 	return 0;
297 }
298 
gal5_load(struct module_data * m,HIO_HANDLE * f,const int start)299 static int gal5_load(struct module_data *m, HIO_HANDLE *f, const int start)
300 {
301 	struct xmp_module *mod = &m->mod;
302 	iff_handle handle;
303 	int i, ret, offset;
304 	struct local_data data;
305 
306 	LOAD_INIT();
307 
308 	hio_read32b(f);	/* Skip RIFF */
309 	hio_read32b(f);	/* Skip size */
310 	hio_read32b(f);	/* Skip AM   */
311 
312 	offset = hio_tell(f);
313 
314 	mod->smp = mod->ins = 0;
315 
316 	handle = libxmp_iff_new();
317 	if (handle == NULL)
318 		return -1;
319 
320 	m->c4rate = C4_NTSC_RATE;
321 
322 	/* IFF chunk IDs */
323 	ret = libxmp_iff_register(handle, "INIT", get_init);		/* Galaxy 5.0 */
324 	ret |= libxmp_iff_register(handle, "ORDR", get_ordr);
325 	ret |= libxmp_iff_register(handle, "PATT", get_patt_cnt);
326 	ret |= libxmp_iff_register(handle, "INST", get_inst_cnt);
327 
328 	if (ret != 0)
329 		return -1;
330 
331 	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
332 	libxmp_iff_set_quirk(handle, IFF_SKIP_EMBEDDED);
333 	libxmp_iff_set_quirk(handle, IFF_CHUNK_ALIGN2);
334 
335 	/* Load IFF chunks */
336 	if (libxmp_iff_load(handle, m, f, &data) < 0) {
337 		libxmp_iff_release(handle);
338 		return -1;
339 	}
340 
341 	libxmp_iff_release(handle);
342 
343 	mod->trk = mod->pat * mod->chn;
344 	mod->smp = mod->ins;
345 
346 	MODULE_INFO();
347 
348 	if (libxmp_init_instrument(m) < 0)
349 		return -1;
350 
351 	if (libxmp_init_pattern(mod) < 0)
352 		return -1;
353 
354 	D_(D_INFO "Stored patterns: %d", mod->pat);
355 	D_(D_INFO "Stored samples: %d ", mod->smp);
356 
357 	hio_seek(f, start + offset, SEEK_SET);
358 
359 	handle = libxmp_iff_new();
360 	if (handle == NULL)
361 		return -1;
362 
363 	/* IFF chunk IDs */
364 	ret = libxmp_iff_register(handle, "PATT", get_patt);
365 	ret |= libxmp_iff_register(handle, "INST", get_inst);
366 
367 	if (ret != 0)
368 		return -1;
369 
370 	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
371 	libxmp_iff_set_quirk(handle, IFF_SKIP_EMBEDDED);
372 	libxmp_iff_set_quirk(handle, IFF_CHUNK_ALIGN2);
373 
374 	/* Load IFF chunks */
375 	if (libxmp_iff_load(handle, m, f, &data) < 0) {
376 		libxmp_iff_release(handle);
377 		return -1;
378 	}
379 
380 	libxmp_iff_release(handle);
381 
382 	/* Alloc missing patterns */
383 	for (i = 0; i < mod->pat; i++) {
384 		if (mod->xxp[i] == NULL) {
385 			if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0) {
386 				return -1;
387 			}
388 		}
389 	}
390 
391 	for (i = 0; i < mod->chn; i++) {
392 		mod->xxc[i].pan = data.chn_pan[i] * 2;
393 	}
394 
395 	m->quirk |= QUIRKS_FT2;
396 	m->read_event_type = READ_EVENT_FT2;
397 
398 	return 0;
399 }
400