dropped aas, moved to maxmod
[gbajam21] / tools / mmutil / it.c
diff --git a/tools/mmutil/it.c b/tools/mmutil/it.c
new file mode 100644 (file)
index 0000000..76c9ce7
--- /dev/null
@@ -0,0 +1,900 @@
+/****************************************************************************
+ *                                                          __              *
+ *                ____ ___  ____ __  ______ ___  ____  ____/ /              *
+ *               / __ `__ \/ __ `/ |/ / __ `__ \/ __ \/ __  /               *
+ *              / / / / / / /_/ />  </ / / / / / /_/ / /_/ /                *
+ *             /_/ /_/ /_/\__,_/_/|_/_/ /_/ /_/\____/\__,_/                 *
+ *                                                                          *
+ *         Copyright (c) 2008, Mukunda Johnson (mukunda@maxmod.org)         *
+ *                                                                          *
+ * Permission to use, copy, modify, and/or distribute this software for any *
+ * purpose with or without fee is hereby granted, provided that the above   *
+ * copyright notice and this permission notice appear in all copies.        *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         *
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  *
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   *
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    *
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  *
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           *
+ ****************************************************************************/
+
+// information from ITTECH.TXT
+
+#include <stdlib.h>
+#include <string.h>
+#include "defs.h"
+#include "mas.h"
+#include "it.h"
+#include "files.h"
+#include "simple.h"
+#include "errors.h"
+#include "samplefix.h"
+
+#ifdef SUPER_ASCII
+#define vstr_it_div "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n"
+#define vstr_it_instr_top   "ÚÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n"
+#define vstr_it_instr_head  "³INDEX³VOLUME³ NNA ³ ENV ³            NAME           ³\n"
+#define vstr_it_instr_slice "ÃÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n"
+#define vstr_it_instr          "³%3i  ³ %3i%% ³ %3s ³ %s%s%s ³ %-26s³\n"
+#define vstr_it_instr_bottom "ÀÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n"
+
+#define vstr_it_samp_top    "ÚÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n"
+#define vstr_it_samp_head   "³INDEX³VOLUME³DVOLUME³ LOOP ³  MID-C  ³            NAME           ³\n"
+#define vstr_it_samp_slice  "ÃÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n"
+#define vstr_it_samp           "³%3i  ³ %3i%% ³ %3i%%  ³ %4s ³%6ihz ³ %-26s³\n"
+#define vstr_it_samp_bottom "ÀÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n"
+
+#define vstr_it_pattern " \x0e %2i"
+#else
+#define vstr_it_div "--------------------------------------------\n"
+#define vstr_it_instr_top   vstr_it_div
+#define vstr_it_instr_head  " INDEX VOLUME  NNA   ENV   NAME\n"
+//#define vstr_it_instr_slice ""
+#define vstr_it_instr          " %-3i   %3i%%    %3s   %s%s%s   %-26s \n"
+#define vstr_it_instr_bottom vstr_it_div
+
+#define vstr_it_samp_top    vstr_it_div
+#define vstr_it_samp_head   " INDEX VOLUME DVOLUME LOOP   MID-C     NAME            \n"
+//#define vstr_it_samp_slice  ""
+#define vstr_it_samp           " %-3i   %3i%%   %3i%%    %4s  %6ihz   %-26s \n"
+#define vstr_it_samp_bottom vstr_it_div
+
+#define vstr_it_pattern " * %2i"
+#endif
+
+bool Load_IT_Envelope( Instrument_Envelope* env, bool unsign )
+{
+       // read envelopes
+       u8 a;
+       u8 node_count;
+       int x;
+       
+       bool env_loop=false;
+       bool env_sus=false;
+       bool env_enabled=false;
+       bool env_filter=false;
+
+       memset( env, 0, sizeof( Instrument_Envelope ) );
+
+       a=read8();
+       
+       if( a & 1 )
+               env_enabled = true;
+       if( !(a & 2) )
+       {
+               env->loop_start=255;
+               env->loop_end  =255;
+       }
+       else
+               env_loop=true;
+       if( !(a & 4) )
+       {
+               env->sus_start=255;
+               env->sus_end=255;
+       }
+       else
+               env_sus=true;
+
+       if( a & 128 )
+       {
+               unsign=false;
+               env_filter=true;
+               env->env_filter=env_filter;
+       }
+       
+       node_count=read8();
+       if( node_count != 0 )
+               env->env_valid=true;
+       
+       env->node_count = node_count;
+       if( env_loop )
+       {
+               env->loop_start=read8();
+               env->loop_end=read8();
+       }
+       else
+       {
+               skip8( 2 );
+       }
+       if( env_sus )
+       {
+               env->sus_start=read8();
+               env->sus_end=read8();
+       }
+       else
+       {
+               skip8( 2 );
+       }
+       for( x = 0; x < 25; x++ )
+       {
+               env->node_y[x] = read8();
+               if( unsign )
+                       env->node_y[x] += 32;
+               env->node_x[x] = read16();
+               
+       }
+       read8(); // unused byte
+       env->env_enabled = env_enabled;
+       return env_enabled;
+}
+
+int Load_IT_Instrument( Instrument* inst, bool verbose, int index )
+{
+       u16 a;
+       int x;
+
+       memset( inst, 0, sizeof( Instrument ) );
+
+       skip8( 17 );
+       inst->nna               =read8();
+       inst->dct               =read8();
+       inst->dca               =read8();
+       a=read16(); if( a > 255 ) a = 255;
+       inst->fadeout   =(u8)a;
+       skip8( 2 );
+       inst->global_volume             =read8();
+       a= read8();
+       a = (a&128) | ((a&127)*2 > 127 ? 127 : (a&127)*2);
+       inst->setpan                    =a^128;
+       inst->random_volume             =read8();
+       skip8( 5 );
+       for( x = 0; x < 26; x++ )
+               inst->name[x] = read8();
+       skip8( 6 );
+       
+       for( x = 0; x < 120; x++ )
+               inst->notemap[x] = read16();
+       
+       inst->env_flags=0;
+       
+       Load_IT_Envelope( &inst->envelope_volume, false );
+       inst->env_flags |= inst->envelope_volume.env_valid ? 1 : 0;
+       inst->env_flags |= inst->envelope_volume.env_enabled ? 8 : 0;
+
+       Load_IT_Envelope( &inst->envelope_pan, true );
+       inst->env_flags |= inst->envelope_pan.env_enabled ? 2 : 0;
+
+       Load_IT_Envelope( &inst->envelope_pitch, true );
+       inst->env_flags |= inst->envelope_pitch.env_enabled ? 4 : 0;
+
+       if( verbose )
+       {
+               printf( vstr_it_instr, \
+                               index+1, \
+                               (inst->global_volume*100)/128, \
+                               ((inst->nna==0)?"CUT":((inst->nna==1)?"CON":((inst->nna==2)?"OFF":((inst->nna==3)?"FAD":"???")))), \
+                               (inst->env_flags&8)?"V":"-", \
+                               (inst->env_flags&2)?"P":"-", \
+                               (inst->env_flags&4)?"T":"-", \
+                               inst->name );
+
+       /*      printf( "%i%%   ", (inst->global_volume*100) / 128 );
+               switch( inst->nna )
+               {
+               case 0:
+                       printf( "%s     ", "CUT" ); break;
+               case 1:
+                       printf( "%s     ", "OFF" ); break;
+               case 2:
+                       printf( "%s     ", "CONT" ); break;
+               case 3:
+                       printf( "%s     ", "FADE" ); break;
+               }
+               if( (!(inst->env_flags & 2)) && (!(inst->env_flags & 4)) && (!(inst->env_flags & 8)) )
+               {
+                       printf( "-      " );
+               }
+               else
+               {
+                       if( inst->env_flags & 8)
+                               printf( "V" );
+                       if( inst->env_flags & 2)
+                               printf( "P" );
+                       if( inst->env_flags & 4)
+                               printf( "S" );
+                       printf( "       " );
+               }
+               printf( "%s\n", inst->name );*/
+       }
+
+       skip8( 7 );
+       return 0;
+}
+
+void Create_IT_Instrument( Instrument* inst, int sample )
+{
+       int x;
+
+       memset( inst, 0, sizeof( Instrument ) );
+
+       inst->global_volume             =128;
+       
+       for( x = 0; x < 120; x++ )
+               inst->notemap[x] = x+sample*256;
+}
+
+int Load_IT_Sample( Sample* samp )
+{
+       bool bit16;
+       bool hasloop;
+       bool pingpong;
+       bool samp_unsigned=false;
+       u8 a;
+       u32 samp_length;
+       u32 loop_start;
+       u32 loop_end;
+       u32 c5spd;
+       u32 data_address;
+       int x;
+       
+       memset( samp, 0, sizeof( Sample ) );
+       samp->msl_index = 0xFFFF;
+
+       if( read32() != 'SPMI' )
+               return ERR_UNKNOWNSAMPLE;
+       for( x = 0; x < 12; x++ )       // dos filename
+               samp->filename[x] = read8();
+       if( read8() != 0 )
+               return ERR_UNKNOWNSAMPLE;
+       samp->global_volume = read8();
+       a = read8();
+       samp->it_compression = a & 8 ? 1 : 0;
+       bit16 = a & 2;
+       hasloop = a & 16;
+       pingpong = a & 64;
+       samp->default_volume = read8();
+       for( x = 0; x < 26; x++ )
+               samp->name[x] = read8();
+       a=read8();
+       samp->default_panning = read8();
+       samp->default_panning = (((samp->default_panning&127) == 64) ? 127 : (samp->default_panning<<1)) | (samp->default_panning&128);
+       if( !(a & 1) )
+               samp_unsigned=true;
+       samp_length = read32();
+       loop_start=read32();
+       loop_end=read32();
+       c5spd=read32();
+       
+       samp->frequency                 = c5spd;
+       samp->sample_length             = samp_length;
+       samp->loop_start                = loop_start;
+       samp->loop_end                  = loop_end;
+       
+       skip8( 8 ); // susloop start/end
+       data_address = read32();
+       samp->vibspeed = read8();
+       samp->vibdepth = read8();
+       samp->vibrate = read8();
+       samp->vibtype = read8();
+       samp->datapointer = data_address;
+       if( hasloop )
+       {
+               if( pingpong )
+                       samp->loop_type = 2;
+               else
+                       samp->loop_type = 1;
+               samp->loop_start = loop_start;
+               samp->loop_end = loop_end;
+       }
+       else
+       {
+               samp->loop_type = 0;
+       }
+       samp->format = (bit16 ? SAMPF_16BIT : 0) | (samp_unsigned ? 0 : SAMPF_SIGNED );
+       if( samp->sample_length == 0 ) samp->loop_type = 0;
+       return 0;
+}
+
+int Load_IT_Sample_CMP( u8 *p_dest_buffer, int samp_len, u16 cmwt, bool bit16 );
+int Load_IT_SampleData( Sample* samp, u16 cwmt )
+{
+       u32 x;
+       int a;
+       if( samp->sample_length == 0 ) return 0;
+       if( samp->format & SAMPF_16BIT )
+               samp->data = (u16*)malloc( (u32)(samp->sample_length)*2 );
+       else
+               samp->data = (u8*)malloc( (u32)(samp->sample_length) );
+
+       if( !samp->it_compression )
+       {
+       
+               for( x = 0; x < samp->sample_length; x++ )
+               {
+                       if( samp->format & SAMPF_16BIT )
+                       {
+                               if( !(samp->format & SAMPF_SIGNED) )
+                               {
+                                       a = (unsigned short)read16();
+                               }
+                               else
+                               {
+                                       a = (signed short)read16();
+                                       a += 32768;
+                               }
+                               ((u16*)samp->data)[x] = (u16)a;
+                       }
+                       else
+                       {
+                               if( !(samp->format & SAMPF_SIGNED) )
+                               {
+                                       a = (unsigned char)read8();
+                               }
+                               else
+                               {
+                                       a = (signed char)read8();
+                                       a += 128;
+                               }
+                               ((u8*)samp->data)[x] = (u8)a;
+                       }
+                       
+               }
+       }
+       else
+       {
+               Load_IT_Sample_CMP( samp->data, samp->sample_length, cwmt, (bool)(samp->format & SAMPF_16BIT) );
+       }
+       FixSample( samp );
+       return 0;
+}
+
+int Empty_IT_Pattern( Pattern *patt ) {
+
+       int x;
+       memset( patt, 0, sizeof( Pattern ) );
+       patt->nrows = 64;
+       for( x = 0; x < patt->nrows*MAX_CHANNELS; x++ ) {
+               patt->data[x].note = 250; // special clears for vol&note
+               patt->data[x].vol = 255;
+       }
+       return ERR_NONE;
+}
+
+int Load_IT_Pattern( Pattern* patt )
+{
+       int x;
+       int clength;
+       u8 chanvar;
+       u8 chan;
+       u8 maskvar;
+
+       u8 old_maskvar[MAX_CHANNELS];
+       u8 old_note[MAX_CHANNELS];
+       u8 old_inst[MAX_CHANNELS];
+       u8 old_vol[MAX_CHANNELS];
+       u8 old_fx[MAX_CHANNELS];
+       u8 old_param[MAX_CHANNELS];
+       
+       memset( patt, 0, sizeof( Pattern ) );
+       
+       clength = read16();
+       patt->nrows = read16();
+       skip8(4);
+
+       patt->clength = clength;
+
+       for( x = 0; x < patt->nrows*MAX_CHANNELS; x++ )
+       {
+               patt->data[x].note = 250; // special clears for vol&note
+               patt->data[x].vol = 255;
+       }
+       
+       
+       // DECOMPRESS IT PATTERN
+       
+       for( x = 0; x < patt->nrows; x++ )
+       {
+GetNextChannelMarker:
+               chanvar = read8();                                      // Read byte into channelvariable.
+               if( chanvar == 0 )                                      // if(channelvariable = 0) then end of row
+                       continue;                                       
+               
+               chan = (chanvar-1) & 63;                        // Channel = (channelvariable-1) & 63
+               if( chan >= MAX_CHANNELS )
+                       return ERR_MANYCHANNELS;
+               
+               if( chanvar & 128 )                                     // if(channelvariable & 128) then read byte into maskvariable
+                       old_maskvar[chan] = read8();
+               
+               maskvar = old_maskvar[chan];
+               
+               if( maskvar & 1 )                                       // if(maskvariable & 1), then read note. (byte value)
+               {
+                       old_note[chan] = read8();
+                       patt->data[x*MAX_CHANNELS+chan].note = old_note[chan];
+               }
+               
+               if( maskvar & 2 )                                       // if(maskvariable & 2), then read instrument (byte value)
+               {
+                       old_inst[chan] = read8();
+                       patt->data[x*MAX_CHANNELS+chan].inst = old_inst[chan];
+               }
+               
+               if( maskvar & 4 )                                       // if(maskvariable & 4), then read volume/panning (byte value)
+               {
+                       old_vol[chan] = read8();
+                       patt->data[x*MAX_CHANNELS+chan].vol = old_vol[chan];
+               }
+
+               if( maskvar & 8 )                                       // if(maskvariable & 8), then read command (byte value) and commandvalue
+               {
+                       old_fx[chan] = read8();
+                       patt->data[x*MAX_CHANNELS+chan].fx = old_fx[chan];
+                       old_param[chan] = read8();
+                       patt->data[x*MAX_CHANNELS+chan].param = old_param[chan];
+               }
+
+               if( maskvar & 16 )                                                                                      // if(maskvariable & 16), then note = lastnote for channel
+                       patt->data[x*MAX_CHANNELS+chan].note = old_note[chan];
+               if( maskvar & 32 )                                                                                      // if(maskvariable & 32), then instrument = lastinstrument for channel
+                       patt->data[x*MAX_CHANNELS+chan].inst = old_inst[chan];
+               if( maskvar & 64 )                                                                                      // if(maskvariable & 64), then volume/pan = lastvolume/pan for channel
+                       patt->data[x*MAX_CHANNELS+chan].vol = old_vol[chan];
+               if( maskvar & 128 )                                                                                     // if(maskvariable & 128), then {
+               {
+                       patt->data[x*MAX_CHANNELS+chan].fx = old_fx[chan];              // command = lastcommand for channel and
+                       patt->data[x*MAX_CHANNELS+chan].param = old_param[chan];// commandvalue = lastcommandvalue for channel
+               }
+               goto GetNextChannelMarker;
+       }
+       
+       return ERR_NONE;
+}
+
+int Load_IT( MAS_Module* itm, bool verbose )
+{
+       u8 b;
+       u16 w;
+       int x;
+       int cc;
+
+       u16 cwt;
+       u16 cmwt;
+       
+       u32* parap_inst;
+       u32* parap_samp;
+       u32* parap_patt;
+
+       bool instr_mode;
+       
+       memset( itm, 0, sizeof( MAS_Module ) );
+
+       if( read32() != 'MPMI' )
+               return ERR_INVALID_MODULE;
+       for( x = 0; x < 28; x++ )
+               itm->title[x] = read8();
+       itm->order_count        = (u16)read16();
+       itm->inst_count         = (u8)read16();
+       itm->samp_count         = (u8)read16();
+       itm->patt_count         = (u8)read16();
+       cwt = read16();
+       cmwt = read16(); // upward compatible
+       //skip8( 4 );   // created with tracker / upward compatible
+       w = read16(); // flags
+       itm->stereo = w & 1;
+       itm->inst_mode = instr_mode = w & 4;
+       itm->freq_mode = w & 8;
+       itm->old_effects = w & 16;
+       itm->link_gxx = w & 32;
+       skip8( 2 ); // special
+       itm->global_volume = read8();
+       skip8( 1 ); // mix volume
+       itm->initial_speed = read8();
+       itm->initial_tempo = read8();
+
+       if( verbose )
+       {
+               printf( vstr_it_div );
+               printf( "Loading IT, \"%s\"\n", itm->title );
+               printf( vstr_it_div );
+               printf( "#Orders......%i\n", itm->order_count );
+               printf( "#Instr.......%i\n", itm->inst_count );
+               printf( "#Samples.....%i\n", itm->samp_count );
+               printf( "#Patterns....%i\n", itm->patt_count );
+               printf( "Stereo.......%s\n", itm->stereo ? "Yes" : "No" );
+               printf( "Slides.......%s\n", itm->freq_mode ? "Linear" : "Amiga" );
+               printf( "Old Effects..%s\n", itm->old_effects ? "Yes" : "No" );
+               printf( "Global Vol...%i%%\n", (itm->global_volume*100)/128 );
+               printf( "Speed........%i\n", itm->initial_speed );
+               printf( "Tempo........%i\n", itm->initial_tempo );
+               printf( "Instruments..%s\n", instr_mode ? "Yes" : "Will be supplied" );
+               printf( vstr_it_div );
+       }
+       skip8( 12 ); // SEP, PWD, MSGLENGTH, MESSAGE OFFSET, [RESERVED]
+       for( x = 0; x < 64; x++ )
+       {
+               b = read8();
+               if( x < MAX_CHANNELS )
+                       itm->channel_panning[x] = b*4 > 255 ? 255 : b*4;        // map 0->64 to 0->255
+       }
+       for( x = 0; x < 64; x++ )
+       {
+               b = read8();
+               if( x < MAX_CHANNELS )
+                       itm->channel_volume[x] = b;
+       }
+       for( x = 0; x < itm->order_count; x++ )
+               itm->orders[x] = read8();
+       
+       parap_inst = (u32*)malloc( itm->inst_count * sizeof( u32 ) );
+       parap_samp = (u32*)malloc( itm->samp_count * sizeof( u32 ) );
+       parap_patt = (u32*)malloc( itm->patt_count * sizeof( u32 ) );
+       
+       for( x = 0; x < itm->inst_count; x++ )
+               parap_inst[x] = read32();
+       for( x = 0; x < itm->samp_count; x++ )
+               parap_samp[x] = read32();
+       for( x = 0; x < itm->patt_count; x++ )
+               parap_patt[x] = read32();
+       
+       itm->samples = (Sample*)malloc( itm->samp_count * sizeof( Sample ) );
+       itm->patterns = (Pattern*)malloc( itm->patt_count * sizeof( Pattern ) );
+
+       if( instr_mode )
+       {
+               itm->instruments = (Instrument*)malloc( itm->inst_count * sizeof( Instrument ) );
+               if( verbose )
+               {
+                       printf( "Loading Instruments...\n" );
+                       printf( vstr_it_instr_top );
+                       printf( vstr_it_instr_head );
+#ifdef vstr_it_instr_slice
+                       printf( vstr_it_instr_slice );
+#endif
+                       //printf( "INDEX        VOLUME  NNA     ENV     NAME\n" );
+               }
+               
+               // read instruments
+               for( x = 0; x < itm->inst_count; x++ )
+               {
+               //      if( verbose )
+               //              printf( "%i     ", x+1 );
+                       file_seek_read( parap_inst[x], SEEK_SET );
+                       Load_IT_Instrument( &itm->instruments[x], verbose, x );
+               }
+
+               if( verbose )
+               {
+                       printf( vstr_it_instr_bottom );
+               }
+       }
+
+       if( verbose )
+       {
+               printf( "Loading Samples...\n" );
+               printf( vstr_it_samp_top );
+               printf( vstr_it_samp_head );
+#ifdef vstr_it_samp_slice
+               printf( vstr_it_samp_slice );
+#endif
+               //printf( "INDEX        VOLUME  DVOLUME LOOP    MID-C   NAME\n" );
+       }
+       
+       // read samples
+       for( x = 0; x < itm->samp_count; x++ )
+       {
+               file_seek_read( parap_samp[x], SEEK_SET );
+               Load_IT_Sample( &itm->samples[x] );
+               if( verbose )
+               {
+                       printf( vstr_it_samp, x+1, (itm->samples[x].global_volume * 100) / 64, (itm->samples[x].default_volume * 100) / 64, itm->samples[x].loop_type == 0 ? "None" : (itm->samples[x].loop_type == 1 ? "Forw" : "BIDI"), itm->samples[x].frequency, itm->samples[x].name );
+                       //printf( "%i   %i%%    %i%%    %s      %ihz    %s\n", x+1, (itm->samples[x].global_volume*100) / 64, (itm->samples[x].default_volume*100) / 64, itm->samples[x].loop_type == 0 ? "None" : (itm->samples[x].loop_type == 1 ? "Yes" : "BIDI"), itm->samples[x].frequency, itm->samples[x].name );
+               }
+       }
+
+       if( verbose )
+       {
+               printf( vstr_it_samp_bottom );
+       }
+
+       if( !instr_mode )
+       {
+               if( verbose )
+               {
+                       printf( "Adding Instrument Templates...\n" );
+                       printf( vstr_it_div );
+               }
+               itm->inst_count = itm->samp_count;
+               itm->instruments = (Instrument*)malloc( itm->inst_count * sizeof( Instrument ) );
+               cc=0;
+               for( x = 0; x < itm->samp_count; x++ )
+               {
+                       if( verbose )
+                       {
+                               printf( " * %2i", x+1 );
+                               cc++;
+                               if( cc == 15)
+                               {
+                                       cc=0;
+                                       printf("\n");
+                               }
+                       }
+                       Create_IT_Instrument( &itm->instruments[x], x+1 );
+               }
+               if( verbose )
+               {
+                       if( cc != 0 )
+                               printf( (((x+1)%15)==0)?"":"\n" );
+                       printf( vstr_it_div );
+               }
+       }
+
+       if(verbose)
+       {
+               printf( "Reading Patterns...\n" );
+               printf( vstr_it_div );
+       }
+
+       // read patterns
+       cc=0;
+       for( x = 0; x < itm->patt_count; x++ )
+       {
+               file_seek_read( parap_patt[x], SEEK_SET );
+               if( parap_patt[x] != 0 )
+               {
+                       if( verbose )
+                       {
+                               printf( vstr_it_pattern, x+1 );
+                               cc++;
+                               if( cc == 15 )
+                               {
+                                       cc=0;
+                                       printf("\n");
+                               }
+                       }
+                       Load_IT_Pattern( &itm->patterns[x] );
+                       
+               }
+               else
+               {
+                       Empty_IT_Pattern( &itm->patterns[x] );
+                       //memset( &itm->patterns[x], 0, sizeof( Pattern ) );
+               }
+       }
+       
+       
+       if( verbose )
+       {
+               if( cc != 0 )
+                       printf( "\n" );
+               printf( vstr_it_div );
+               printf( "Loading Sample Data...\n" );
+       }
+       // read sample data
+       for( x = 0; x < itm->samp_count; x++ )
+       {
+               file_seek_read( itm->samples[x].datapointer, SEEK_SET );
+               Load_IT_SampleData( &itm->samples[x], cmwt );
+       }
+
+       if( verbose )
+       {
+               printf( vstr_it_div );
+       }
+
+       free( parap_inst );
+       free( parap_samp );
+       free( parap_patt );
+       
+       return ERR_NONE;
+}
+
+/* * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE
+
+ -The following sample decompression code is based on CHIBITRACKER's code (http://chibitracker.berlios.de) which is based on xmp's code.(http://xmp.helllabs.org) which is based in openCP code.
+
+* NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE */
+
+int Load_IT_CompressedSampleBlock( u8** buffer )
+{
+       u32 size;
+       u32 x;
+       size = read16();
+       (*buffer) = (u8*)malloc( size+4 );
+       (*buffer)[size+0]=0;
+       (*buffer)[size+1]=0;
+       (*buffer)[size+2]=0;
+       (*buffer)[size+3]=0;
+       for( x = 0; x < size; x++ )
+               (*buffer)[x] = read8();
+       return ERR_NONE;
+}
+
+int Load_IT_Sample_CMP( u8 *p_dest_buffer, int samp_len, u16 cmwt, bool bit16 )
+{
+       u8*     c_buffer=NULL;
+       u16 block_length;               // length of compressed data block in samples
+       u16 block_position;             // position in block 
+       u8 bit_width;                   // actual "bit width" 
+       u32 aux_value;                  // value read from file to be processed 
+       s16 d1, d2;             // integrator buffers (d2 for it2.15) 
+       s8 d18, d28;
+       s8 v8;                  // sample value 
+       s16 v16;                // sample value 16 bit
+       bool it215; // is this an it215 module?
+       u16 border;
+       u8 tmp_shift;
+       u32 bit_readpos=0;
+       int i;
+       
+       u32 nbits, dsize;
+
+       u8 *dest8_write = (u8 *)p_dest_buffer;
+       u16 *dest16_write = (u16 *)p_dest_buffer;
+
+       nbits = bit16 ? 16 : 8;
+       dsize = bit16 ? 4 : 3;
+       for (i=0;i<samp_len;i++)
+               p_dest_buffer[i]=128;
+       
+
+
+       it215=(cmwt==0x215);
+
+       // now unpack data till the dest buffer is full 
+
+       while( samp_len )
+       {
+       // read a new block of compressed data and reset variables 
+               Load_IT_CompressedSampleBlock( &c_buffer );
+               bit_readpos=0;
+               if( bit16 )
+                       block_length = (samp_len < 0x4000) ? samp_len : 0x4000;
+               else
+                       block_length = (samp_len < 0x8000) ? samp_len : 0x8000;
+               block_position = 0;
+               bit_width = nbits+1;            // start with width of 9 bits 
+               d1 = d2 = d18=d28=0;            // reset integrator buffers 
+               
+
+               // now uncompress the data block 
+               while ( block_position < block_length ) {
+
+                       aux_value = readbits( c_buffer, bit_readpos, bit_width );                       // read bits 
+                       bit_readpos+=bit_width;
+                       
+                       if ( bit_width < 7 ) { // method 1 (1-6 bits) 
+
+                               if( bit16 )
+                               {
+                                       if ( (signed)aux_value == (1 << (bit_width - 1)) ) { // check for "100..." 
+
+                                               aux_value = readbits( c_buffer, bit_readpos, dsize )+1; //read_n_bits_from_IT_compressed_block(3) + 1; // yes -> read new width; 
+                                               bit_readpos += dsize;
+                                       bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
+                                                               // and expand it 
+                                               continue; // ... next value 
+                                       }
+                               }
+                               else
+                               {
+                                       if ( aux_value == ((u32)1 << ((u32)bit_width - 1)) ) { // check for "100..." 
+
+                                               aux_value = readbits( c_buffer, bit_readpos, dsize )+1; //read_n_bits_from_IT_compressed_block(3) + 1; // yes -> read new width; 
+                                               bit_readpos += dsize;
+                                       bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
+                                                               // and expand it 
+                                               continue; // ... next value 
+                                       }
+                               }
+
+                       } else if ( bit_width < nbits + 1 ) { // method 2 (7-8 bits) 
+
+                               if( bit16 )
+                               {
+                                       border = (0xFFFF >> ((nbits+1) - bit_width)) - (nbits/2);
+                                                               // lower border for width chg 
+
+                                       if ( (int)aux_value > (int)border && (int)aux_value <= ((int)border + nbits) ) {
+
+                                               aux_value -= border; // convert width to 1-8 
+                                               bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
+                                                               // and expand it 
+                                               continue; // ... next value 
+                                       }       
+                               }
+                               else
+                               {
+                                       border = (0xFF >> ((nbits+1) - bit_width)) - (nbits/2);
+                                                               // lower border for width chg 
+
+                                       if ( aux_value > border && aux_value <= (border + nbits) ) {
+
+                                               aux_value -= border; // convert width to 1-8 
+                                               bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
+                                                               // and expand it 
+                                               continue; // ... next value 
+                                       }       
+                               }
+
+                       } else if ( bit_width == nbits+1 ) { // method 3 (9 bits) 
+
+                               if ( aux_value & (1<<nbits) ) {                 // bit 8 set? 
+
+                                       bit_width = (aux_value + 1) & 0xff;             // new width... 
+                                       continue;                               // ... and next value 
+                               }
+
+                       } else { // illegal width, abort 
+
+                               if( c_buffer ) {
+                                       free( c_buffer ); c_buffer=NULL; }
+                               return ERR_UNKNOWNSAMPLE;
+                       }
+
+                       // now expand value to signed byte 
+                       if ( bit_width < nbits ) {
+
+                               tmp_shift = nbits - bit_width;
+                               if( bit16 )
+                               {
+                                       v16=(aux_value << tmp_shift);
+                                       v16>>=tmp_shift;
+                               }
+                               else
+                               {
+                                       v8=(aux_value << tmp_shift);
+                                       v8>>=tmp_shift;
+                               }
+
+                       }
+                       else
+                       {
+                               if( bit16 )
+                                       v16 = (s16) aux_value;
+                               else
+                                       v8 = (s8) aux_value;
+                       }
+                       
+                       if( bit16 )
+                       {
+                               // integrate upon the sample values 
+                               d1 += v16;
+                       d2 += d1;
+
+                               // ... and store it into the buffer
+                               *(dest16_write++) = (it215 ? d2+32768 : d1+32768);
+                       }
+                       else
+                       {
+                               // integrate upon the sample values 
+                               d18 += v8;
+                       d28 += d18;
+                               
+                               // ... and store it into the buffer
+                               *(dest8_write)++ = (it215 ? (int)d28+128 : (int)d18+128);
+                       }
+                               block_position++;
+
+               }
+
+               // now subtract block lenght from total length and go on 
+               if( c_buffer ) {
+                       free( c_buffer ); c_buffer=NULL; }
+               samp_len -= block_length;
+       }
+       
+       return ERR_NONE;
+}