test sprite scaling
[gbajam21] / tools / mmutil / xm.c
1 /****************************************************************************
2  *                                                          __              *
3  *                ____ ___  ____ __  ______ ___  ____  ____/ /              *
4  *               / __ `__ \/ __ `/ |/ / __ `__ \/ __ \/ __  /               *
5  *              / / / / / / /_/ />  </ / / / / / /_/ / /_/ /                *
6  *             /_/ /_/ /_/\__,_/_/|_/_/ /_/ /_/\____/\__,_/                 *
7  *                                                                          *
8  *         Copyright (c) 2008, Mukunda Johnson (mukunda@maxmod.org)         *
9  *                                                                          *
10  * Permission to use, copy, modify, and/or distribute this software for any *
11  * purpose with or without fee is hereby granted, provided that the above   *
12  * copyright notice and this permission notice appear in all copies.        *
13  *                                                                          *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         *
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  *
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   *
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    *
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  *
20  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           *
21  ****************************************************************************/
22
23 // information from XM.TXT by Mr.H of Triton
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include "defs.h"
28 #include "mas.h"
29 #include "xm.h"
30 #include "files.h"
31 #include "simple.h"
32 #include "errors.h"
33 #include "math.h"
34 #include "samplefix.h"
35
36 #define cho 64
37
38 #ifdef SUPER_ASCII
39 #define vstr_xm_samp "  %2i   ³   %s%s   ³ %-22s ³\n"
40 #define vstr_xm_nosamp  "  --   ³   --   ³ %-22s ³\n"
41 #define vstr_xm_div "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n"
42 #define vstr_xm_patt " \x0e %2i "
43 #define vstr_xm_samp_top "ÚÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n"
44 #define vstr_xm_samp_header "³INDEX³SAMPLES³ENVELOPE³          NAME          ³\n"
45 #define vstr_xm_samp_prefix "³%3i  ³"
46 #define vstr_xm_samp_slice "ÃÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n"
47 #define vstr_xm_samp_bottom "ÀÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n"
48 #else
49 #define vstr_xm_samp "  %2i   |   %s%s   | %-22s |\n"
50 #define vstr_xm_nosamp "  --   |   --   | %-22s |\n"
51 #define vstr_xm_div "--------------------------------------------\n"
52 #define vstr_xm_patt " Pattern %2i "
53 #define vstr_xm_samp_top ".-----------------------------------------------.\n"
54 #define vstr_xm_samp_header "|INDEX|SAMPLES|ENVELOPE|          NAME          |\n"
55 #define vstr_xm_samp_prefix "|%3i  |"
56 #define vstr_xm_samp_slice "|-----+-------+--------+------------------------|\n"
57 #define vstr_xm_samp_bottom "`-----------------------------------------------'\n"
58 #endif
59
60 int Get_XM_Frequency( s8 relnote, s8 finetune )
61 {
62         double rn=relnote;
63         double ft=finetune;
64         double middle_c;
65         double freq;
66         middle_c = 8363.0f;
67         freq = middle_c * pow( 2.0, (1.0/12.0)*rn + (1.0/(12.0*128.0))*ft );
68         return (int)freq;
69 }
70
71 int Load_XM_Instrument( Instrument* inst, MAS_Module* mas, u8* p_nextsample, bool verbose )
72 {
73         
74         int inst_size;
75         int nsamples;
76         
77         int ns;
78
79         int samp_headstart;
80         int samp_headsize;
81         int inst_headstart;
82
83         int sample_old;
84
85         int x,y;
86         u32 t;
87
88         u8 vibtype;
89         u8 vibsweep;
90         u8 vibdepth;
91         u8 vibrate;
92
93         s8 finetune;
94         s8 relnote;
95         u8 loopbits;
96
97         u8 volbits;
98         u8 panbits;
99
100         Sample* samp;
101
102         ns = *p_nextsample;
103         
104         memset( inst, 0, sizeof( Instrument ) );
105
106         inst_headstart = file_tell_read();
107         inst_size = read32();
108         
109         for( x = 0; x < 22; x++ )
110                 inst->name[x] = read8(); // instrument name
111 //      if( verbose )
112 //              printf( "  Name=\"%s\"\n", inst->name );
113 //      if( read8() != 0 )
114 //              return ERR_UNKNOWNINST;
115         read8(); // instrument type, SUPPOSED TO ALWAYS BE 0...
116         nsamples = read16();
117         if( nsamples > 0 )
118         {
119                 samp_headsize = read32();
120                 // read sample map
121                 for( x = 0; x < 96; x++ )
122                 {
123                         inst->notemap[x+12] = ((read8()+ns+1)*256) | (x+12);
124                 }
125                 for( x=0; x < 12; x++ )
126                         inst->notemap[x] =( inst->notemap[12]&0xFF00) | x;
127                 for( x=96;x<120;x++)
128                         inst->notemap[x] =( inst->notemap[12]&0xFF00) | x;
129                 for( x = 0; x < 12; x++ )
130                 {
131                         inst->envelope_volume.node_x[x] = read16();
132                         inst->envelope_volume.node_y[x] = (u8)read16();
133                 }
134                 for( x = 0; x < 12; x++ )
135                 {
136                         inst->envelope_pan.node_x[x] = read16();
137                         inst->envelope_pan.node_y[x] = (u8)read16();
138                 }
139                 inst->global_volume = 128;
140                 inst->envelope_volume.node_count = read8();
141                 inst->envelope_pan.node_count = read8();
142                 inst->envelope_volume.sus_start = inst->envelope_volume.sus_end = read8();
143                 inst->envelope_volume.loop_start = read8();
144                 inst->envelope_volume.loop_end = read8();
145                 inst->envelope_pan.sus_start = inst->envelope_pan.sus_end = read8();
146                 inst->envelope_pan.loop_start = read8();
147                 inst->envelope_pan.loop_end = read8();
148                 volbits = read8();
149                 panbits = read8();
150                 inst->env_flags = 0;
151                 if( volbits & 1 )
152                         inst->env_flags |= 1|8;
153                 if( panbits & 1 )
154                         inst->env_flags |= 2;
155                 
156                 if( !(volbits & 2) )
157                         inst->envelope_volume.sus_start=inst->envelope_volume.sus_end=255;
158                 if( !(panbits & 2) )
159                         inst->envelope_pan.sus_start=inst->envelope_pan.sus_end=255;
160                 
161                 if( !(volbits & 4) )
162                         inst->envelope_volume.loop_start=inst->envelope_volume.loop_end=255;
163                 if( !(panbits & 4) )
164                         inst->envelope_pan.loop_start=inst->envelope_pan.loop_end=255;
165                 
166                 vibtype=read8();
167                 vibsweep=32768/(read8()+1);
168                 vibdepth=read8();
169                 vibrate=read8();
170                 inst->fadeout = read16()/32;                    // apply scalar!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
171                 file_seek_read( inst_headstart+inst_size, SEEK_SET );
172                         
173 /*              if( verbose )
174                 {
175                         if( volbits & 1 )
176                                 printf( "  Has Volume Envelope\n" );
177                         if( panbits & 1 )
178                                 printf( "  Has Panning Envelope\n" );
179                         if( nsamples != 1 )
180                                 printf( "  Contains %i samples...\n", nsamples );
181                         else
182                                 printf( "  Loading sample\n" );
183                 }
184 */              
185                 // read sample headers
186                 for( x = 0; x < nsamples; x++ )
187                 {
188                         if( ns+x >= 256 )
189                                 return ERR_TOOMANYSAMPLES;
190                         samp_headstart = file_tell_read();
191                         samp = &mas->samples[ns+x];
192 //                      if( verbose && nsamples != 1 )
193 //                              printf( "  Loading sample %i...\n", x+1 );
194                         memset( samp, 0, sizeof( Sample ) );
195                         samp->msl_index = 0xFFFF;
196                         samp->sample_length = read32();
197                         samp->loop_start = read32();
198                         samp->loop_end = read32()+samp->loop_start;
199                         samp->default_volume = read8();
200                         samp->global_volume = 64;
201
202                         samp->vibtype = vibtype;
203                         samp->vibdepth = vibdepth;
204                         samp->vibspeed = vibrate;
205                         samp->vibrate = vibsweep;
206
207                         finetune = (s8)read8();
208                         loopbits = read8();
209                         samp->default_panning = (read8()>>1) | 128;
210                         relnote = (s8)read8();
211                         read8();                // reserved
212
213                         for( y =0; y <22; y ++)
214                         {
215                                 samp->name[y] = read8();
216                                 if( y < 12 )
217                                         samp->filename[y] = samp->name[y];
218                         }
219                         
220                         samp->frequency = Get_XM_Frequency( relnote, finetune );
221                         
222 //                      samp->bit16 = loopbits & 16 ? true : false;
223                         samp->format = loopbits & 16 ? SAMP_FORMAT_U16 : SAMP_FORMAT_U8;
224                         if( samp->format & SAMPF_16BIT )
225                         {
226                                 samp->sample_length /= 2;
227                                 samp->loop_start /= 2;
228                                 samp->loop_end /= 2;
229                         }
230                         samp->loop_type = loopbits & 3;
231                         file_seek_read( samp_headstart + samp_headsize, SEEK_SET );
232 /*
233                         if( verbose )
234                         {
235                                 printf( "    Length........%i\n", samp->sample_length );
236                                 if( samp->loop_type == 0 )
237                                         printf( "    Loop..........Disabled\n" );
238                                 else if( samp->loop_type == 1 )
239                                         printf( "    Loop..........Forward %i->%i\n", samp->loop_start, samp->loop_end );
240                                 else if( samp->loop_type == 2 )
241                                         printf( "    Loop..........BIDI %i->%i\n", samp->loop_start, samp->loop_end );
242                                 printf( "    Volume........%i\n", samp->default_volume );
243                                 printf( "    Panning.......%i\n", samp->default_panning & 127 );
244                                 printf( "    Middle C......%ihz\n", samp->frequency );
245                                 printf( "    16 bit........%s\n", (samp->format & SAMPF_16BIT) ? "yes (will be converted)" : "no" );
246                         }*/
247                 }
248                 
249                 // read sample
250                 for( x = 0; x < nsamples; x++ )
251                 {
252                         samp = &mas->samples[ns+x];
253                         if( samp->sample_length == 0 )
254                                 continue;
255                         
256                         sample_old = 0;
257                         if( samp->format & SAMPF_16BIT )
258                         {
259                                 samp->data = (u16*)malloc( samp->sample_length*2 );
260                                 for( t = 0; t < samp->sample_length; t++ )
261                                 {
262                                         sample_old = (s16)((s16)read16() + sample_old);
263                                         ((u16*)samp->data)[t] = sample_old + 32768;
264                                 }
265                         }
266                         else
267                         {
268                                 samp->data = (u8*)malloc( samp->sample_length );
269                                 for( t = 0; t < samp->sample_length; t++ )
270                                 {
271                                         sample_old = (s8)((s8)read8() + sample_old);
272                                         ((u8*)samp->data)[t] = sample_old + 128;
273                                 }
274                         }
275                         FixSample( samp );
276                 }
277                 *p_nextsample = ns+nsamples;
278
279
280                 if( verbose )
281                 {
282                         printf( vstr_xm_samp, nsamples, (volbits&1)?"V":"-", (panbits&1)?"P":"-", inst->name );
283                 }
284         }
285         else
286         {
287                 file_seek_read( inst_headstart+inst_size, SEEK_SET );
288                 if( verbose )
289                         printf( vstr_xm_nosamp, inst->name );
290         }
291         
292         return ERR_NONE;
293 }
294
295 void CONV_XM_EFFECT( u8* fx, u8* param )
296 {
297         int wfx, wpm;
298         wfx=*fx;
299         wpm=*param;
300
301         switch( wfx )
302         {
303         case 0: //   0xy arpeggio
304                 if( wpm != 0)
305                         wfx = 'J'-cho;
306                 else
307                         wfx=wpm=0;
308                 break;
309         
310         case 1: //   1xx porta up
311                 wfx = 'F'-cho;
312                 if( wpm >= 0xE0 )
313                         wpm = 0xDF;
314                 break;
315         
316         case 2: //   2xx porta down
317                 wfx = 'E'-cho;
318                 if( wpm >= 0xE0 )
319                         wpm = 0xDF;
320                 break;
321         
322         case 3: //   3xx porta to note
323                 wfx = 'G'-cho;
324                 break;
325         
326         case 4: //   4xy vibrato
327                 wfx = 'H'-cho;
328                 break;
329         
330         case 5: //   5xy volslide+glissando
331                 wfx = 'L'-cho;
332                 break;
333         
334         case 6: //   6xy volslide+vibrato
335                 wfx = 'K'-cho;
336                 break;
337         
338         case 7: //   7xy tremolo
339                 wfx = 'R'-cho;
340                 break;
341         
342         case 8: //   8xx set panning
343                 wfx = 'X'-cho;
344                 break;
345         
346         case 9: //   9xx set offset
347                 wfx = 'O'-cho;
348                 break;
349         
350         case 0xA: // Axy volume slide
351                 wfx = 'D'-cho;
352                 break;
353         
354         case 0xB: // Bxx position jump
355                 wfx = 'B'-cho;
356                 break;
357         
358         case 0xC: // Cxx set volume
359                 wfx = 27;       // compatibility effect
360                 break;
361         
362         case 0xD: // Dxx pattern break
363                 wfx = 'C'-cho;
364                 wpm = (wpm&0xF) + (wpm>>4) * 10;
365                 /*if( wpm >= 0xF0 )               what the fuck is this
366                 {
367                         wpm = 0xE0 | (wpm&0xF);
368                 }
369                 if( wpm & 0xF == 0xF )
370                 {
371                         wpm = 0x0F | (wpm&0xF0);
372                 }*/
373                 break;
374         
375         case 0xE: // Exy extended
376 //              if( (wpm & 0xF0) != 0xC0 )
377 //              {int foo = 1;}
378                 switch( wpm >> 4 )
379                 {
380                 case 1:                                         // fine porta up
381                         wfx = 'F'-cho;
382                         wpm = 0xF0 | (wpm&0xF);
383                         break;
384
385                 case 2:                                         // fine porta down
386                         wfx = 'E'-cho;
387                         wpm = 0xF0 | (wpm&0xF);
388                         break;
389
390                 case 3:                                         // glissando control
391                 case 5:                                         // set finetune
392                         // UNSUPPORTED :(
393                         wfx=0;
394                         wpm=0;
395                         break;
396                         
397                 case 4:                                         // vibrato control
398                         wfx = 'S'-cho;
399                         wpm = 0x30 | (wpm&0xF);
400                         break;
401
402                 case 6:                                         // pattern loop
403                         wfx = 'S'-cho;
404                         wpm = 0xB0 | (wpm&0xF);
405                         break;
406                 
407                 case 7:                                         // tremolo control
408                         wfx = 'S'-cho;
409                         wpm = 0x40 | (wpm&0xF);
410                         break;
411
412                 case 8:                                         // set panning
413                         wfx = 'X'-cho;
414                         wpm = (wpm&0xF) * 16;
415                         break;
416                         
417                 case 9:                                         // old retrig
418                         wfx = 'S'-cho;
419                         wpm = 0x20 | (wpm&0xF);
420                         break;
421
422                 case 10:                                        // fine volslide up
423                         wfx = 'S'-cho;
424                         wpm = 0x00 | (wpm&0xF);
425                         break;
426
427                 case 11:                                        // fine volslide down
428                         wfx = 'S'-cho;
429                         wpm = 0x10 | (wpm&0xF);
430                         break;
431
432                 case 12:                                        // note cut
433                         wfx = 'S'-cho;
434                         wpm = 0xC0 | (wpm&0xF);
435                         break;
436                         
437                 case 13:                                        // note delay
438                         wfx = 'S'-cho;
439                         wpm = 0xD0 | (wpm&0xF);
440                         break;
441
442                 case 14:                                        // pattern delay
443                         wfx = 'S'-cho;
444                         wpm = 0xE0 | (wpm&0xF);
445                         break;
446                 case 15:                                        // event
447                         wfx = 'S'-cho;
448                         wpm = wpm;
449                         break;
450                 case 0:                                         // set filter
451                         wfx=0;
452                         wpm=0;
453
454                 }
455                 break;
456         
457         case 0xF: // Fxx set speed
458                 if( wpm >= 32 )
459                         wfx = 'T'-cho;
460                 else
461                         wfx = 'A'-cho;
462                 break;
463         
464         case 16: // Gxx set global volume
465                 wfx = 'V'-cho;
466                 wpm=wpm;
467                 break;
468         
469         case 17: // Hxx global volume slide
470                 wfx = 'W'-cho;
471                 break;
472
473         case 18: // Ixx unused
474         case 19: // Jxx unused
475         case 22: // Mxx unused
476         case 23: // Nxx unused
477         case 24: // Oxx unused
478         case 26: // Qxx unused
479         case 28: // Sxx unused
480         case 30: // Uxx unused
481         case 31: // Vxx unused
482         case 32: // Wxx unused
483         case 34: // Yxx unused
484         case 35: // Zxx unused
485                 wfx = 0;
486                 wpm = 0;
487                 break;
488                 
489         case 20: // Kxx key off
490                 wfx = 28;
491                 break;
492         
493         case 21: // Lxx set envelope position
494                 wfx = 29;
495                 break;
496         
497         case 25: // Pxx panning slide
498                 wfx = 'P'-cho;
499                 break;
500
501         
502         
503         case 27: // Rxx retrigger note
504                 wfx = 'Q'-cho;
505                 break;
506                 
507         case 29: // Txx tremor
508                 wfx = 30;
509                 break;
510                 
511         case 33: // Xxx extra fine slide
512                 if( (wpm>>4) == 1 )
513                 {
514                         wfx = 'F'-cho;
515                         wpm = 0xE0 | (wpm & 0xF);
516                 }
517                 else if( (wpm>>4) == 2 )
518                 {
519                         wfx = 'E'-cho;
520                         wpm = 0xE0 | (wpm & 0xF);
521                 }
522                 else
523                 {
524                         wfx=0;
525                         wpm=0;
526                 }
527                 break;
528         }
529         *fx = wfx;
530         *param = wpm;
531 }
532
533 int Load_XM_Pattern( Pattern* patt, u32 nchannels, bool verbose )
534 {
535         u32 headsize;
536         u32 headstart;
537         u16     clength;
538         u16 row, col;
539         u8      b;
540         u32 e;
541         u8 fx,param;
542
543         headstart = file_tell_read();
544         headsize = read32();
545         
546         if( read8() != 0 )
547                 return ERR_UNKNOWNPATTERN;
548
549         memset( patt, 0, sizeof( Pattern ) );
550         
551         patt->nrows = read16();
552         clength = read16();
553         
554         if( verbose )
555                 printf( "- %i rows, %.2f KB\n", patt->nrows, (float)(clength)/1000 );
556
557
558         for( row = 0; row < patt->nrows*MAX_CHANNELS; row++ )
559         {
560                 patt->data[row].note = 250;
561                 patt->data[row].vol = 0;
562         }
563
564         file_seek_read( headstart+headsize, SEEK_SET );
565         
566         if( clength == 0 )
567         {
568                 // pattern is empty
569                 return ERR_NONE;
570         }
571         
572         // read pattern data
573         for( row = 0; row < patt->nrows; row++ )
574         {
575                 for( col = 0; col < nchannels; col++ )
576                 {
577                         e = row*MAX_CHANNELS+col;
578                         b = read8();
579                         if( b & 128 )   // packed
580                         {
581                                 if( b & 1 )                     // bit 0 set: Note follows
582                                 {
583                                         patt->data[e].note = read8();                   // (byte) Note (1-96, 1 = C-0)
584                                         if( patt->data[e].note == 97 )
585                                                 patt->data[e].note = 255;
586                                         else
587                                                 patt->data[e].note += 12-1;
588                                 }
589                                 if( b & 2 )                     // 1 set: Instrument follows
590                                 {
591                                         patt->data[e].inst = read8();                   // (byte) Instrument (1-128)
592                                 }
593                                 if( b & 4 )                     // 2 set: Volume column byte follows
594                                 {
595                                         patt->data[e].vol = read8();    // (byte) Volume column byte
596                                 }
597                                 if( b & 8 )                     // 3 set: Effect type follows
598                                         fx = read8();                                                           // (byte) Effect type
599                                 else
600                                         fx=0;
601                                 if( b & 16 )            // 4 set: Guess what!
602                                         param=read8();                                                          // (byte) Effect parameter
603                                 else
604                                         param=0;
605
606                                 if( fx != 0 || param != 0 )
607                                 {
608                                         CONV_XM_EFFECT( &fx, &param );          // convert effect
609                                         patt->data[e].fx = fx;
610                                         patt->data[e].param = param;
611                                 }
612                         }
613                         else                    // unpacked
614                         {
615                                 patt->data[e].note = b;                                 // (byte) Note (1-96, 1 = C-0)
616                                 if( patt->data[e].note == 97 )
617                                         patt->data[e].note = 255;
618                                 else
619                                         patt->data[e].note += 12-1;
620                                 patt->data[e].inst = read8();                   // (byte) Instrument (1-128)
621                                 patt->data[e].vol = read8();                            // (byte) Volume column byte (see below)
622                                 fx = read8();                                                           // (byte) Effect type
623                                 param=read8();                                                          // (byte) Effect parameter
624                                 CONV_XM_EFFECT( &fx, &param );                          // convert effect
625                                 patt->data[e].fx = fx;
626                                 patt->data[e].param = param;
627                         }
628                 }
629         }
630         return ERR_NONE;
631 }
632
633 int Load_XM( MAS_Module* mod, bool verbose )
634 {
635         int x;
636         u16 xm_version;
637         u32 xm_headsize;
638         u16 xm_nchannels;
639         u8 next_sample;
640         
641         memset( mod, 0, sizeof( MAS_Module ) );
642         
643         mod->old_effects=true;
644         mod->xm_mode=true;
645         mod->global_volume=64;
646         mod->old_mode=false;
647
648         if( read32() != 'etxE' || read32() != 'dedn' || read32() != 'doM ' || read32() != ':elu' || read8() != ' ' )
649                 return ERR_INVALID_MODULE;
650         for( x = 0; x < 20; x++ )
651                 mod->title[x] = read8();
652         if( verbose )
653         {
654                 printf(  vstr_xm_div  );
655                 printf( "Loading XM, \"%s\"\n", mod->title );
656         }
657         if( read8() != 0x1a )
658                 return ERR_INVALID_MODULE;
659         skip8( 20 ); // tracker name
660         xm_version = read16();
661         xm_headsize = read32();
662         mod->order_count        = (u8)read16();
663         mod->restart_pos        = (u8)read16();
664         xm_nchannels            = read16();
665         mod->patt_count         = (u8)read16();
666         mod->inst_count         = (u8)read16();
667         mod->freq_mode          = read16() & 1 ? true : false;          // flags
668         mod->initial_speed      = (u8)read16();
669         mod->initial_tempo      = (u8)read16();
670
671         if( verbose )
672         {
673                 printf( "Version....%i.%i\n", xm_version>>8 & 0xFF, xm_version & 0xFF );
674                 printf( "Length.....%i\n", mod->order_count );
675                 printf( "Restart....%i\n", mod->restart_pos );
676                 printf( "Channels...%i\n", xm_nchannels );
677                 printf( "#Patterns..%i\n", mod->patt_count );
678                 printf( "#Instr.....%i\n", mod->inst_count );
679                 printf( "Freq Mode..%s\n", mod->freq_mode ? "Linear" : "Amiga" );
680                 printf( "Speed......%i\n", mod->initial_speed );
681                 printf( "Tempo......%i\n", mod->initial_tempo );
682         }
683         
684         for( x = 0; x < 32; x++ )
685         {
686                 mod->channel_volume[x] = 64;
687                 mod->channel_panning[x] = 128;
688         }
689         if( verbose )
690         {
691                 printf( vstr_xm_div );
692                 printf( "Reading sequence...\n" );
693         }
694         for( x = 0; x < 200; x++ )              // read order table
695         {
696                 if( x < mod->order_count )
697                         mod->orders[x] = read8();
698                 else
699                 {
700                         read8();
701                         mod->orders[x] = 255;
702                 }
703         }
704         
705         for( ; x < 256; x++ )                   // skip 200->255
706                 read8();
707         file_seek_read( 60+xm_headsize, SEEK_SET );     // or maybe 60..
708
709         if( verbose )
710         {
711                 printf( vstr_xm_div );
712                 printf( "Loading patterns...\n" );
713                 printf( vstr_xm_div );
714         }
715         
716         mod->patterns = (Pattern*)malloc( mod->patt_count * sizeof( Pattern ) );
717         for( x = 0; x < mod->patt_count; x++ )
718         {
719                 if( verbose )
720                         printf( vstr_xm_patt, x+1 );
721                 Load_XM_Pattern( &mod->patterns[x], xm_nchannels, verbose );
722         }
723         
724         mod->instruments = (Instrument*)malloc( mod->inst_count * sizeof( Instrument ) );
725         mod->samples = (Sample*)malloc( 256 * sizeof( Sample ) );
726         next_sample=0;
727
728         
729         if( verbose )
730         {
731                 printf( vstr_xm_div );
732                 printf( "Loading instruments...\n" );
733                 printf( vstr_xm_samp_top );
734                 printf( vstr_xm_samp_header );
735                 printf( vstr_xm_samp_slice );
736         }
737         
738         for( x = 0; x < mod->inst_count; x++ )
739         {
740         //      if( verbose )
741         //              printf( "Reading Instrument %i...\n", x+1 );
742                 if( verbose )
743                         printf( vstr_xm_samp_prefix, x+1 );
744                 Load_XM_Instrument( &mod->instruments[x], mod, &next_sample, verbose );
745         }
746         
747         if( verbose )
748         {
749                 printf( vstr_xm_samp_bottom );
750         }
751         
752         mod->samp_count = next_sample;
753         return ERR_NONE;
754 }