software tunnel rotation / lower framerate
[gbajam21] / tools / mmutil / s3m.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 ST3's TECH.DOC
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include "defs.h"
28 #include "mas.h"
29 #include "s3m.h"
30 #include "files.h"
31 #include "simple.h"
32 #include "errors.h"
33 #include "samplefix.h"
34
35 #define S3M_NOTE(a) (((a&15)+(a>>4)*12)+12)
36
37 #ifdef SUPER_ASCII
38 #define vstr_s3m_samp " %5i ³ %-4s³ %3i%% ³%5ihz³ %-28s³\n"
39 #define vstr_s3m_sampe " ----- ³ --- ³ ---- ³ ----- ³ %-28s³\n"
40 #define vstr_s3m_div "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n"
41 #define vstr_s3m_sampt_top   "ÚÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n"
42 #define vstr_s3m_sampt_mid   "³INDEX³LENGTH ³LOOP ³VOLUME³ MID-C ³             NAME            ³\n"
43 #define vstr_s3m_sampt_slice "ÃÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n"
44 #define vstr_s3m_sampt_index "³ %2i  ³"
45 #define vstr_s3m_sampt_bottom "ÀÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n"
46 #define vstr_s3m_pattern " \x0e %2i%s"
47 #else
48 #define vstr_s3m_samp "%-5i   %-3s   %3i%%   %5ihz  %-28s \n"
49 #define vstr_s3m_sampe   "-----   ---   ----   -------  %-28s\n"
50 #define vstr_s3m_div "--------------------------------------------\n"
51 #define vstr_s3m_sampt_top  vstr_s3m_div
52 #define vstr_s3m_sampt_mid   " INDEX LENGTH  LOOP  VOLUME  MID-C   NAME\n"
53 //#define vstr_s3m_sampt_slice "" 
54 #define vstr_s3m_sampt_index " %-2i    "
55 #define vstr_s3m_sampt_bottom vstr_s3m_div
56 #define vstr_s3m_pattern " * %2i%s"
57 #endif
58
59 int Load_S3M_SampleData( Sample* samp, u8 ffi )
60 {
61         u32 x;
62         int a;
63         if( samp->sample_length == 0 )
64                 return ERR_NONE;
65         if( samp->format & SAMPF_16BIT )
66                 samp->data = (u16*)malloc( samp->sample_length*2 );
67         else
68                 samp->data = (u8*)malloc( samp->sample_length );
69         if( ffi == 1 )
70         {
71                 // signed samples [VERY OLD]
72                 for( x = 0; x < samp->sample_length; x++ )
73                 {
74                         if( samp->format & SAMPF_16BIT )
75                         {
76                                 a = read16();
77                                 a += 32768;
78                                 ((u16*)samp->data)[x] = (u16)a;
79                         }
80                         else
81                         {
82                                 a = read8();
83                                 a += 128;
84                                 ((u8*)samp->data)[x] = (u8)a;
85                         }
86                 }
87         }
88         else if( ffi == 2 )
89         {
90                 // unsigned samples
91                 for( x = 0; x < samp->sample_length; x++ )
92                 {
93                         if( samp->format & SAMPF_16BIT )
94                         {
95                                 a = read16();
96                                 ((u16*)samp->data)[x] = (u16)a;
97                         }
98                         else
99                         {
100                                 a = read8();
101                                 ((u8*)samp->data)[x] = (u8)a;
102                         }
103                 }
104         }
105         else
106         {
107                 return ERR_UNKNOWNSAMPLE;
108         }
109         FixSample( samp );
110         return ERR_NONE;
111 }
112
113 int Load_S3M_Sample( Sample* samp, bool verbose )
114 {
115         u8 flags;
116         u32 x;
117         memset( samp, 0, sizeof( Sample ) );
118         samp->msl_index = 0xFFFF;
119         if( read8() == 1 )                      // type, 1 = sample
120         {
121                 for( x = 0; x < 12; x++ )
122                         samp->filename[x] = read8();
123                 samp->datapointer = (read8()*65536+read16())*16;//read24();
124                 samp->sample_length = read32();
125                 samp->loop_start = read32();
126                 samp->loop_end = read32();
127                 samp->default_volume = read8();
128                 samp->global_volume = 64;
129                 read8(); // reserved
130                 if( read8() != 0 )                      // packing, 0 = unpacked
131                         return ERR_UNKNOWNSAMPLE;
132                 flags = read8();
133                 samp->loop_type = flags&1 ? 1 : 0;
134                 if( flags & 2 )
135                         return ERR_UNKNOWNSAMPLE;
136                 //samp->bit16 = flags&4 ? true : false;
137                 samp->format = flags&4 ? SAMP_FORMAT_U16 : SAMP_FORMAT_U8;
138                 samp->frequency = read32();
139                 read32(); // reserved
140                 skip8( 8 ); // internal variables
141                 for( x =0 ; x < 28; x++ )
142                         samp->name[x] = read8();
143                 if( read32() != 'SRCS' )
144                         return ERR_UNKNOWNSAMPLE;
145
146                 if( verbose )
147                 {
148         //              printf( "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n" );
149         //              printf( "Loading Samples...\n" );
150         //              printf( "ÚÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n" );
151         //              printf( "³LENGTH³LOOP³VOLUME³ MID-C ³             NAME            ³\n");
152         //              printf( "ÅÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n" );
153                         printf( vstr_s3m_samp, samp->sample_length, samp->loop_type ? "Yes" : "No", (samp->default_volume*100) / 64, samp->frequency, samp->name );
154                         /*printf( "  Name......%s\n", samp->name );
155                         printf( "  Length....%i\n", samp->sample_length );
156                         if( samp->loop_type )
157                                 printf( "        Loop......%i->%i\n", samp->loop_start, samp->loop_end );
158                         else
159                                 printf( "  Loop......Disabled\n" );
160                         printf( "  Volume....%i\n", samp->default_volume );
161                         printf( "  Middle C..%ihz\n", samp->frequency );
162                         if( samp->bit16 )
163                                 printf( "  16 bit....yes\n" );*/
164                 }
165         }
166         else
167         {
168                 if( verbose )
169                 {
170                         printf( vstr_s3m_sampe, samp->name );
171                 }
172         }
173         return ERR_NONE;
174 }
175
176 int Load_S3M_Pattern( Pattern* patt  )
177 {
178         int clength;
179         int row, col;
180         u8 what;
181         int z;
182         
183         clength = read16();
184         // unpack s3m data
185         
186         memset( patt, 0, sizeof( Pattern ) );
187         
188         patt->clength = clength;
189         patt->nrows = 64;
190         
191         for( row = 0; row < 64*MAX_CHANNELS; row++ )
192         {
193                 patt->data[row].note = 250;
194                 patt->data[row].vol = 255;
195         }
196         
197         for( row = 0; row < 64; row++ )
198         {
199                 while( (what = read8()) != 0 )  // BYTE:what / 0=end of row
200                 {
201                         col = what & 31;        // &31=channel
202
203                         z = row*MAX_CHANNELS+col;
204
205                         if( what & 32 )         // &32=follows;  BYTE:note, BYTE:instrument
206                         {
207                                 patt->data[z].note = read8();
208                                 if( patt->data[z].note == 255 )
209                                         patt->data[z].note = 250;
210                                 else if( patt->data[z].note == 254 )
211                                         patt->data[z].note = 254;
212                                 else
213                                         patt->data[z].note = S3M_NOTE( patt->data[z].note );
214                                 patt->data[z].inst = read8();
215                         }
216
217                         if( what & 64 )         // &64=follows;  BYTE:volume
218                         {
219                                 patt->data[z].vol = read8();
220                         }
221
222                         if( what & 128 )        // &128=follows; BYTE:command, BYTE:info
223                         {
224                                 patt->data[z].fx = read8();
225                                 patt->data[z].param = read8();
226                                 if( patt->data[z].fx == 3 )             // convert pattern break to hexadecimal
227                                 {
228                                         patt->data[z].param = (patt->data[z].param&0xF) + (patt->data[z].param/16)*10;
229                                 }
230                                 if( patt->data[z].fx == 'X'-64 )
231                                 {
232                                         patt->data[z].param *= 2; // multiply volume scale by 2
233                                 }
234                                 if( patt->data[z].fx == 'V'-64 )
235                                 {
236                                         patt->data[z].param *= 2; // multiply volume scale by 2
237                                 }
238                         }
239                         if( patt->data[z].fx   == 255 )
240                         {
241                                 patt->data[z].fx = 0;
242                                 patt->data[z].param = 0;
243                         }
244                 }
245         }
246         return ERR_NONE;
247 }
248
249 int Load_S3M( MAS_Module* mod, bool verbose )
250 {
251         u16 s3m_flags;
252         u16 cwt;
253         u16 ffi;
254         u8 dp;
255         
256         bool stereo;
257
258         u8 a;
259         bool chan_enabled[32];
260
261         int x,y;
262
263         u16* parap_inst;
264         u16* parap_patt;
265
266         
267
268         memset( mod, 0, sizeof( MAS_Module ) );
269         for( x = 0; x < 28; x++ )
270                 mod->title[x] = read8();        // read song name
271
272         if( read8() != 0x1A );
273 //              return ERR_INVALID_MODULE;
274         if( read8() != 16 )
275                 return ERR_INVALID_MODULE;
276         if( verbose )
277         {
278                 printf( vstr_s3m_div );
279         }
280         if( verbose )
281                 printf( "Loading S3M, \"%s\"\n", mod->title );
282
283         skip8( 2 ); // reserved space
284         mod->order_count = (u8)read16();
285         mod->inst_count = (u8)read16();
286         mod->samp_count = mod->inst_count;
287         mod->patt_count = (u8)read16();
288
289         for( x = 0; x < 32; x++ )
290                 mod->channel_volume[x] = 64;
291
292         mod->freq_mode = 0;             // amiga frequencies
293         mod->old_effects=true;  // old effects (maybe not?)
294         mod->link_gxx=false;    // dont link gxx memory
295         mod->restart_pos = 0;   // restart from beginning
296         mod->old_mode=true;
297         
298         s3m_flags = read16();
299         cwt = read16();
300         ffi = read16();
301         if( read32() != 'MRCS' ) // "SCRM" mark
302                 return ERR_INVALID_MODULE;
303         mod->global_volume = read8()*2;
304         mod->initial_speed = read8();
305         mod->initial_tempo = read8();
306         stereo = read8() >> 7; // master volume
307         read8(); // ultra click removal
308         dp = read8(); // default pan positions (when 252)
309         skip8( 8+2 ); // reserved space + special pointer
310         for( x = 0; x < 32; x++ )
311         {
312                 u8 chn = read8();
313                 chan_enabled[x] = chn >> 7;
314                 if( stereo )
315                 {
316                         if( (chn&127) < 8 )     // left channel
317                                 mod->channel_panning[x] = clamp_u8( 128 - (PANNING_SEP/2) );
318                         else // right channel
319                                 mod->channel_panning[x] = clamp_u8( 128 + (PANNING_SEP/2) );
320                 }
321                 else
322                 {
323                         mod->channel_panning[x] = 128;
324                 }
325         }
326         for( x = 0; x < mod->order_count; x++ )
327         {
328                 mod->orders[x] = read8();
329         }
330         parap_inst = (u16*)malloc( mod->inst_count * sizeof( u16 ) );
331         parap_patt = (u16*)malloc( mod->patt_count * sizeof( u16 ) );
332         
333         for( x = 0; x < mod->inst_count; x++ )
334                 parap_inst[x] = read16();
335         for( x = 0; x < mod->patt_count; x++ )
336                 parap_patt[x] = read16();
337         
338         if( dp == 252 )
339         {
340                 for( x = 0; x < 32; x++ )
341                 {
342                         a = read8();
343                         if( a & 32 )
344                         {
345                                 mod->channel_panning[x] = (a&15)*16 > 255 ? 255 : (a&15)*16;
346                         }
347                         else
348                         {/*
349                                 if( stereo )
350                                 {
351                                         switch( x & 3 ) {
352                                         case 0:
353                                         case 3:
354                                                 mod->channel_panning[x] = clamp_u8( 128 - (PANNING_SEP/2) );
355                                                 break;
356                                         case 1:
357                                         case 2:
358                                                 mod->channel_panning[x] = clamp_u8( 128 + (PANNING_SEP/2) );
359                                         }
360                                 }
361                                 else
362                                 {
363                                         mod->channel_panning[x] = 128;
364                                 }*/
365                         }
366                 }
367         }
368         else
369         {
370                 for( x = 0; x < 32; x++ )
371                 {
372                         if( stereo )
373                                 mod->channel_panning[x] = x & 1 ? clamp_u8( 128 - (PANNING_SEP/2) ) : clamp_u8( 128 + (PANNING_SEP/2) );
374                         else
375                                 mod->channel_panning[x] = 128;
376                 }
377         }
378         
379         mod->instruments = (Instrument*)malloc( mod->inst_count * sizeof( Instrument ) );
380         mod->samples = (Sample*)malloc( mod->samp_count * sizeof( Sample ) );
381         mod->patterns = (Pattern*)malloc( mod->patt_count * sizeof( Pattern ) );
382         
383         if( verbose )
384         {
385                 printf( vstr_s3m_div );
386                 printf( "Loading Samples...\n" );
387                 printf( vstr_s3m_sampt_top );
388                 printf( vstr_s3m_sampt_mid );
389 #ifdef vstr_s3m_sampt_slice
390                 printf( vstr_s3m_sampt_slice );
391 #endif
392         }
393         // load instruments
394         for( x = 0; x < mod->inst_count; x++ )
395         {
396                 if( verbose )
397                 {
398                         printf( vstr_s3m_sampt_index, x+1 );
399                         //printf( "Sample %i\n", x+1 );
400                 }
401                 // create instrument for sample
402                 memset( &mod->instruments[x], 0, sizeof( Instrument ) );
403                 mod->instruments[x].global_volume = 128;
404                 // make notemap
405                 for( y = 0; y < 120; y++ )
406                         mod->instruments[x].notemap[y] = y | ((x+1) << 8);
407                 
408                 // load sample
409                 file_seek_read( parap_inst[x]*16, SEEK_SET );
410                 if( Load_S3M_Sample( &mod->samples[x], verbose ) )
411                 {
412                         printf( "Error loading sample!\n" );
413                         return ERR_UNKNOWNSAMPLE;
414                 }
415         }
416         
417         // load patterns
418         if( verbose )
419         {
420                 printf( vstr_s3m_sampt_bottom );
421                 printf( "Loading Patterns...\n" );
422                 printf( vstr_s3m_div );
423         }
424         for( x = 0; x < mod->patt_count; x++ )
425         {
426                 if( verbose )
427                 {
428                         printf( vstr_s3m_pattern, x+1, ((x+1)%15)?"":"\n" );
429                 }
430                         //printf( "%i...", x+1 );
431                 file_seek_read( parap_patt[x]*16, SEEK_SET );
432                 Load_S3M_Pattern( &mod->patterns[x] );
433         }
434         
435         if( verbose )
436         {
437                 printf( "\n" );
438                 printf( vstr_s3m_div );
439                 printf( "Loading Sample Data...\n" );
440         }
441         for( x = 0; x < mod->samp_count; x++ )
442         {
443                 file_seek_read( mod->samples[x].datapointer, SEEK_SET );
444                 Load_S3M_SampleData( &mod->samples[x], (u8)ffi );
445         }
446         if( verbose )
447         {
448                 printf( vstr_s3m_div );
449         }
450         return ERR_NONE;
451 }