home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / beos / PPBeDevKit.ZIP / PLAYERPR.TAR / PlayerPRO / Source / Import-Export / S3M.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-26  |  32.1 KB  |  1,268 lines

  1. /********************                        ***********************/
  2. //
  3. //    Player PRO 5.0 - DRIVER SOURCE CODE -
  4. //
  5. //    Library Version 5.0
  6. //
  7. //    To use with MAD Library for Mac: Symantec, CodeWarrior and MPW
  8. //
  9. //    Antoine ROSSET
  10. //    16 Tranchees
  11. //    1206 GENEVA
  12. //    SWITZERLAND
  13. //
  14. //    COPYRIGHT ANTOINE ROSSET 1996, 1997, 1998
  15. //
  16. //    Thank you for your interest in PlayerPRO !
  17. //
  18. //    FAX:                (+41 22) 346 11 97
  19. //    PHONE:             (+41 79) 203 74 62
  20. //    Internet:     RossetAntoine@bluewin.ch
  21. //
  22. /********************                        ***********************/
  23.  
  24. #include "RDriver.h"
  25. #include "S3M.h"
  26. #include "FileUtils.h"
  27.  
  28. #ifdef _MAC_H
  29. #if defined(powerc) || defined(__powerc)
  30. enum {
  31.         PlayerPROPlug = kCStackBased
  32.         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  33.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
  34.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( Ptr)))
  35.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( MADMusic*)))
  36.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoRec*)))
  37.         | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof( MADDriverSettings*)))
  38. };
  39.  
  40. ProcInfoType __procinfo = PlayerPROPlug;
  41. #else
  42. #include <A4Stuff.h>
  43. #endif
  44. #endif
  45.  
  46. #define LOW(para) ((para) & 15)
  47. #define HI(para) ((para) >> 4)
  48.  
  49.  
  50. Ptr MADPlugNewPtr( long size, MADDriverSettings* init)
  51. {
  52.     if( init->sysMemory) return NewPtrSys( size);
  53.     else return NewPtr( size);
  54. }
  55.  
  56. Ptr MADPlugNewPtrClear( long size, MADDriverSettings* init)
  57. {
  58.     if( init->sysMemory) return NewPtrSysClear( size);
  59.     else return NewPtrClear( size);
  60. }
  61.  
  62. #ifdef _MAC_H
  63. void strncpy( Ptr dst, Ptr str, long size)
  64. {
  65.     BlockMove( str, dst, size);
  66. }
  67. #endif
  68.  
  69. Cmd* GetMADCommand( register short PosX, register short    TrackIdX, register PatData*    tempMusicPat)
  70. {
  71.     if( PosX < 0) PosX = 0;
  72.     else if( PosX >= tempMusicPat->header.size) PosX = tempMusicPat->header.size -1;
  73.         
  74.     return( & (tempMusicPat->Cmds[ (tempMusicPat->header.size * TrackIdX) + PosX]));
  75. }
  76.  
  77. void ConvertS3MEffect( Byte B0, Byte B1, Byte *Cmd, Byte *Arg)
  78. {
  79.     Byte        LoB1 = LOW( B1);
  80.     Byte        HiB1 = HI( B1);
  81.     
  82.     switch( B0 + 0x40)
  83.     {
  84.         default:    *Cmd = 0;            *Arg = 0;        break;
  85.         // Speed
  86.         case 'A':    *Cmd = speedE;        *Arg = B1;    break;
  87.         // Tempo
  88.         case 'T':    *Cmd = speedE;        *Arg = B1;    break;
  89.  
  90.         case 'B':    *Cmd = fastskipE;        *Arg = B1;    break;
  91.  
  92.         case 'C':    *Cmd = skipE;            *Arg = B1;    break;
  93.  
  94.         case 'D':
  95.             if( LoB1 == 0 || HiB1 == 0)        // Slide volume
  96.             {
  97.                 *Cmd = slidevolE;        *Arg = B1;
  98.             }
  99.             else if( HiB1 == 0x0F)        // Fine Slide volume DOWN
  100.             {
  101.                 *Cmd = extendedE;
  102.                 *Arg = 11 << 4;
  103.                 *Arg += LoB1;
  104.             }
  105.             else if( LoB1 == 0x0F)        // Fine Slide volume UP
  106.             {
  107.                 *Cmd = extendedE;
  108.                 *Arg = 10 << 4;
  109.                 *Arg += HiB1;
  110.             }
  111.         break;
  112.         
  113.         case 'E':
  114.             if( HiB1 == 0x0F)        // FineSlide DOWN
  115.             {
  116.                 *Cmd = extendedE;
  117.                 *Arg = 2 << 4;        //not supported
  118.                 *Arg += LoB1;
  119.             }
  120.             else if( HiB1 == 0x0E)    // ExtraFineSlide DOWN
  121.             {
  122.                 *Cmd = 0;            *Arg = 0;        //not supported
  123.             }
  124.             else                    // Slide DOWN
  125.             {
  126.                 *Cmd = upslideE;        *Arg = B1;
  127.             }
  128.         break;
  129.  
  130.         case 'F':
  131.             if( HiB1 == 0x0F)        // FineSlide UP
  132.             {
  133.                 *Cmd = extendedE;
  134.                 *Arg = 1 << 4;        //not supported
  135.                 *Arg += LoB1;
  136.             }
  137.             else if( HiB1 == 0x0E)    // ExtraFineSlide UP
  138.             {
  139.                 *Cmd = 0;            *Arg = 0;        //not supported
  140.             }
  141.             else                    // Slide UP
  142.             {
  143.                 *Cmd = downslideE;        *Arg = B1;
  144.             }
  145.         break;
  146.  
  147.         case 'G':    *Cmd = portamentoE;    *Arg = B1;    break;
  148.         case 'H':    *Cmd = vibratoE;        *Arg = B1;    break;
  149.         
  150.         case 'J':    *Cmd = arpeggioE;        *Arg = B1;    break;
  151.         case 'K':    *Cmd = vibratoslideE;    *Arg = B1;    break;
  152.         case 'L':    *Cmd = portaslideE;        *Arg = B1;    break;
  153.         case 'O':    *Cmd = offsetE;        *Arg = B1;    break;
  154.  
  155.         case 'S':        // Special Effects
  156.             switch( HiB1)
  157.             {
  158.                 default:    *Cmd = 0;        *Arg = 0;                            break;
  159.                 case 2:    *Cmd = extendedE;    *Arg = 5 << 4;        *Arg += LoB1;        break;    // FineTune
  160.                 case 3:    *Cmd = extendedE;    *Arg = 4 << 4;        *Arg += LoB1;        break;    // Set Vibrato WaveForm
  161.                 case 4:    *Cmd = extendedE;    *Arg = 7 << 4;        *Arg += LoB1;        break;    // Set Tremolo WaveForm
  162.                 case 0xB:    *Cmd = extendedE;    *Arg = 6 << 4;        *Arg += LoB1;        break;    // Loop pattern
  163.                 case 0xC:    *Cmd = extendedE;    *Arg = 12 << 4;    *Arg += LoB1;        break;    // Cut sample
  164.                 case 0xD:    *Cmd = extendedE;    *Arg = 13 << 4;    *Arg += LoB1;        break;    // Delay sample
  165.                 case 0xE:    *Cmd = extendedE;    *Arg = 14 << 4;    *Arg += LoB1;        break;    // Delay pattern
  166.             }
  167.         break;
  168.     }
  169. }
  170.  
  171. void ConvertMADEffect( Byte Cmd, Byte Arg, Byte *B0, Byte *B1)
  172. {
  173.     *B0 = 0;
  174.     *B1 = 0;
  175.  
  176.     switch( Cmd)
  177.     {
  178.         case speedE:
  179.             if( Arg < 32)
  180.             {
  181.                 *B0 = 'A' - 0x40;    *B1 = Arg;
  182.             }
  183.             else
  184.             {
  185.                 *B0 = 'T' - 0x40;    *B1 = Arg;
  186.             }
  187.         break;
  188.         case fastskipE:        *B0 = 'B' - 0x40;    *B1 = Arg;    break;
  189.         case skipE:            *B0 = 'C' - 0x40;    *B1 = Arg;    break;
  190.         case slidevolE:        *B0 = 'D' - 0x40;    *B1 = Arg;    break;
  191.         case upslideE:        *B0 = 'E' - 0x40;    *B1 = Arg;    break;
  192.         case downslideE:    *B0 = 'F' - 0x40;    *B1 = Arg;    break;
  193.         case portamentoE:    *B0 = 'G' - 0x40;    *B1 = Arg;    break;
  194.         case vibratoE:        *B0 = 'H' - 0x40;    *B1 = Arg;    break;
  195.         
  196.         case arpeggioE:        *B0 = 'J' - 0x40;    *B1 = Arg;    break;
  197.         case vibratoslideE:    *B0 = 'K' - 0x40;    *B1 = Arg;    break;
  198.         case portaslideE:    *B0 = 'L' - 0x40;    *B1 = Arg;    break;
  199.         case offsetE:        *B0 = 'O' - 0x40;    *B1 = Arg;    break;
  200.         
  201.         case extendedE:
  202.             switch( (Arg & 0xF0) >> 4)
  203.             {
  204.                 case 1:    *B0 = 'F' - 0x40;    *B1 = 0xf0 + (Arg & 0x0F);        break;
  205.                 case 2:    *B0 = 'E' - 0x40;    *B1 = 0xf0 + (Arg & 0x0F);        break;
  206.                 
  207.                 case 5:    *B0 = 'S' - 0x40;    *B1 = 0x20 + (Arg & 0x0F);        break;
  208.                 
  209.                 case 4:    *B0 = 'S' - 0x40;    *B1 = 0x30 + (Arg & 0x0F);        break;
  210.                 case 7:    *B0 = 'S' - 0x40;    *B1 = 0x40 + (Arg & 0x0F);        break;
  211.                 case 6:    *B0 = 'S' - 0x40;    *B1 = 0xb0 + (Arg & 0x0F);        break;
  212.                 case 12:    *B0 = 'S' - 0x40;    *B1 = 0xc0 + (Arg & 0x0F);        break;
  213.                 case 13:    *B0 = 'S' - 0x40;    *B1 = 0xd0 + (Arg & 0x0F);        break;
  214.                 case 14:    *B0 = 'S' - 0x40;    *B1 = 0xe0 + (Arg & 0x0F);        break;
  215.                 
  216.                 case 11:    *B0 = 'D' - 0x40;    *B1 = 0xf0 + (Arg & 0x0F);        break;
  217.                 case 10:    *B0 = 'D' - 0x40;    *B1 = 0x0f + ((Arg & 0x0F)<<4);    break;
  218.             }
  219.         break;
  220.     }
  221. }
  222.  
  223. Ptr    ConvertMad2S3M( MADMusic *theMAD, MADDriverSettings *init, long *sndSize)
  224. {
  225.     long                 i, x, z;
  226.     Ptr                    finalS3M, finalS3MCopy, maxfinalS3M;
  227.     long                InstruSize;
  228.     long                NoIns;
  229.     s3minsform        *ins[ 64];
  230.     Cmd                    *aCmd;
  231.     long                PatternSize;
  232.     
  233.     s3mform            *s3minfo;
  234.     
  235.     unsigned short        *parapins;
  236.     unsigned short        *parappat;
  237.     
  238.     /********************************/
  239.     /*             MAD INFORMATIONS               */
  240.     /********************************/
  241.     InstruSize = 0;
  242.     PatternSize = 0;
  243.     NoIns = 0;
  244.     for( i = 0; i < 64 ; i++)
  245.     {
  246.         if( theMAD->fid[ i].numSamples > 0)
  247.         {
  248.             InstruSize            += 16 + theMAD->sample[ i*MAXSAMPLE + 0]->size;
  249.             //NoIns++;
  250.             
  251.             NoIns = i+1;
  252.         }
  253.     }
  254.     
  255.     for( i = 0; i < theMAD->header->numPat;i++)
  256.     {
  257.         PatternSize += 6L * theMAD->header->numChn * theMAD->partition[ i]->header.size;
  258.         PatternSize += theMAD->partition[ i]->header.size;        // byte 0 de fin de ligne
  259.         PatternSize += 16;
  260.     }
  261.     /********************************/
  262.     
  263.     *sndSize =                 sizeof( s3mform) +
  264.                                         theMAD->header->numPointers +
  265.                                         NoIns*2 +
  266.                                         theMAD->header->numPat*2 +
  267.                                         sizeof(s3minsform) * NoIns +
  268.                                         InstruSize +
  269.                                         PatternSize;
  270.     
  271.     finalS3MCopy = finalS3M = MADPlugNewPtr( *sndSize, init);
  272.     maxfinalS3M = finalS3M + *sndSize;
  273.     if( finalS3M == 0L) return 0L;
  274.     
  275.     
  276.     
  277.     
  278.     /********************************/
  279.     /* s3minfo -- s3minfo -- s3minfo -- s3minfo -- */
  280.     /********************************/
  281.     {
  282.         s3minfo = (s3mform*) finalS3MCopy;
  283.     
  284.         strncpy( s3minfo->name, theMAD->header->name, 28);
  285.         s3minfo->sig1             = 26;
  286.         s3minfo->type            = 16;
  287.         s3minfo->sig2[ 0] = s3minfo->sig2[ 1] = 0;
  288.         
  289.         s3minfo->ordernum        =    theMAD->header->numPointers;        INT16(  &s3minfo->ordernum);
  290.         s3minfo->insnum        =     NoIns;                                                    INT16(  &s3minfo->insnum);
  291.         s3minfo->patnum        =    theMAD->header->numPat;                        INT16(  &s3minfo->patnum);
  292.         
  293.         s3minfo->flags            =    0;
  294.         s3minfo->cwtv            =    0x2013;
  295.         s3minfo->ffv            =    2;                                                                INT16(  &s3minfo->ffv);
  296.         
  297.         
  298.         strncpy( s3minfo->s3msig, "SCRM", 4);
  299.         
  300.         s3minfo->mastervol        =     64;
  301.         s3minfo->initialspeed    =    theMAD->header->speed;
  302.         s3minfo->initialtempo    =    theMAD->header->tempo;
  303.         s3minfo->mastermul        =    0x30;
  304.         
  305.         for( i = 0; i < 12; i++) s3minfo->sig3[ i] = 0;
  306.         
  307.         for( i = 0; i < 32; i++) s3minfo->chanset[ i] = 255;
  308.         
  309.         if( theMAD->header->numChn < 32) for( i = 0; i < theMAD->header->numChn; i++) s3minfo->chanset[ i] = i;
  310.         else for( i = 0; i < 32; i++) s3minfo->chanset[ i] = i;
  311.         
  312.         finalS3MCopy += 96;
  313.     }
  314.     
  315.     /********************************/
  316.     /*     orders -- orders -- orders -- orders      */
  317.     /********************************/
  318.     {
  319.         unsigned char    *orders;
  320.         
  321.         orders = (unsigned char *) finalS3MCopy;
  322.         for( i = 0; i < theMAD->header->numPointers; i++)
  323.         {
  324.             orders[ i] = theMAD->header->oPointers[ i];
  325.             
  326.         //    INT16(  &orders[ i]);
  327.         }
  328.         finalS3MCopy += theMAD->header->numPointers;
  329.     }
  330.     
  331.     /********************************/
  332.     /*     Ins Num -- Ins Num -- Ins Num -- Ins Num      */
  333.     /********************************/
  334.     {
  335.         parapins = (unsigned short *) finalS3MCopy;
  336.         
  337.         for( i = 0; i < NoIns; i++) parapins[ i] = 0;
  338.         finalS3MCopy += NoIns*2L;
  339.     }
  340.     
  341.     /********************************/
  342.     /*     Pat Num -- Pat Num -- Pat Num -- Pat Num */
  343.     /********************************/
  344.     {
  345.         parappat = (unsigned short *) finalS3MCopy;
  346.         
  347.         for( i = 0; i < theMAD->header->numPat; i++) parappat[ i] = 0;
  348.         finalS3MCopy += theMAD->header->numPat*2L;
  349.     }
  350.     
  351.     /*********************************/
  352.     /*     Ins Form -- Ins Form -- Ins Form -- Ins Form */
  353.     /*********************************/
  354.     for (i = 0; i < NoIns; i++)
  355.     {
  356.         if( theMAD->fid[ i].numSamples > 0)
  357.         {
  358.             sData        *curData = theMAD->sample[ i*MAXSAMPLE + 0];
  359.             
  360.             parapins[ i] =  (16L + finalS3MCopy - finalS3M) / 16L;
  361.             finalS3MCopy = finalS3M + parapins[ i]*16L;
  362.             INT16(  ¶pins[ i]);
  363.             
  364.             /**/
  365.             
  366.             ins[ i] = (s3minsform*) finalS3MCopy;
  367.             
  368.             ins[ i]->instype                =    1;
  369.             strncpy( (Ptr) ins[ i]->insdosname, theMAD->fid[i].name, 12);
  370.             ins[ i]->memsegh            =    0;
  371.             ins[ i]->memsegl            =    0;
  372.             ins[ i]->inslength            =    curData->size;                            
  373.             ins[ i]->insloopbeg            =    curData->loopBeg;                        
  374.             ins[ i]->insloopend            =    curData->loopBeg + curData->loopSize;    
  375.             
  376.             if( curData->amp == 16)
  377.             {
  378.                 ins[ i]->inslength /= 2;
  379.                 ins[ i]->insloopbeg /= 2;
  380.                 ins[ i]->insloopend /= 2;
  381.             }
  382.             
  383.             if( curData->stereo)
  384.             {
  385.                 ins[ i]->inslength /= 2;
  386.                 ins[ i]->insloopbeg /= 2;
  387.                 ins[ i]->insloopend /= 2;
  388.             }
  389.             
  390.             INT32( &ins[ i]->inslength);
  391.             INT32( &ins[ i]->insloopbeg);
  392.             INT32( &ins[ i]->insloopend);
  393.             
  394.             ins[ i]->insvol                =    curData->vol;
  395.             ins[ i]->insdsk                =    0;
  396.             ins[ i]->inspack            =    0;
  397.             
  398.             ins[ i]->insflags            =     0;
  399.             if( curData->loopSize != 0)     ins[ i]->insflags += 1;
  400.             if( curData->amp == 16)         ins[ i]->insflags += 4;
  401.             
  402.             ins[ i]->c2spd                =    curData->c2spd;                        INT32(  &ins[ i]->c2spd);
  403.             for( x = 0; x < 4; x++)        ins[ i]->inssig2[ x] = 0;
  404.             ins[ i]->insgvspos            =    256;                                INT16(  &ins[ i]->insgvspos);
  405.             ins[ i]->insint512            =    0;                                    INT16(  &ins[ i]->insint512);
  406.             ins[ i]->insintlastused        =    0;
  407.             strncpy( (Ptr) ins[ i]->insname, theMAD->fid[i].name, 28);
  408.             ins[ i]->inssig[ 0]                =    'S';
  409.             ins[ i]->inssig[ 1]                =    'C';
  410.             ins[ i]->inssig[ 2]                =    'R';
  411.             ins[ i]->inssig[ 3]                =    'S';
  412.         }
  413.         else
  414.         {
  415.             parapins[ i] =  (16L + finalS3MCopy - finalS3M) / 16L;
  416.             finalS3MCopy = finalS3M + parapins[ i]*16L;
  417.             INT16(  ¶pins[ i]);
  418.             
  419.             /**/
  420.             
  421.             ins[ i] = (s3minsform*) finalS3MCopy;
  422.             
  423.             ins[ i]->instype                =    0;
  424.             strncpy( (Ptr) ins[ i]->insdosname, theMAD->fid[i].name, 12);
  425.             ins[ i]->memsegh            =    0;
  426.             ins[ i]->memsegl            =    0;
  427.             ins[ i]->inslength            =    0;
  428.             ins[ i]->insloopbeg            =    0;
  429.             ins[ i]->insloopend            =    0;
  430.             ins[ i]->insvol                =    0;
  431.             ins[ i]->insdsk                =    0;
  432.             ins[ i]->inspack                =    0;
  433.             
  434.             ins[ i]->insflags            =     0;
  435.             
  436.             ins[ i]->c2spd                =    NOFINETUNE;                        INT32(  &ins[ i]->c2spd);
  437.             for( x = 0; x < 4; x++)        ins[ i]->inssig2[ x] = 0;
  438.             ins[ i]->insgvspos            =    256;    
  439.             ins[ i]->insint512            =    0;
  440.             ins[ i]->insintlastused        =    0;
  441.             strncpy( (Ptr) ins[ i]->insname, theMAD->fid[i].name, 28);
  442.         }
  443.         /**/
  444.         
  445.         finalS3MCopy += sizeof(s3minsform);
  446.     }
  447.     
  448.     /*********************************/
  449.     /*     Sample Data -- Sample Data -- Sample Data   */
  450.     /*********************************/
  451.     
  452.     for (i = 0; i < NoIns; i++)
  453.     {
  454.         if( theMAD->fid[ i].numSamples > 0)
  455.         {
  456.             sData            *curData = theMAD->sample[ i*MAXSAMPLE + 0];
  457.             long            tempL, dstSize;
  458.             
  459.             tempL = (16L + finalS3MCopy - finalS3M) / 16L;
  460.             
  461.             ins[ i]->memsegl = tempL & 0x0000FFFF;
  462.             INT16(  &ins[ i]->memsegl);
  463.             
  464.             ins[ i]->memsegh = (long) (tempL &0x00FF0000)>>16L;
  465.             
  466.             finalS3MCopy = finalS3M + tempL*16L;
  467.             
  468.         //    if( finalS3MCopy + curData->size >= maxfinalS3M) Debugger();
  469.             
  470.             BlockMove( curData->data, finalS3MCopy, curData->size);
  471.             
  472.             dstSize = curData->size;
  473.             
  474.             if( curData->stereo == true)
  475.             {
  476.                 if( curData->amp == 8)
  477.                 {
  478.                     for( x = 0 ; x < dstSize; x+=2)
  479.                     {
  480.                         finalS3MCopy[ x / 2] = ((long) finalS3MCopy[ x] + (long) finalS3MCopy[ x + 1]) / 2L;
  481.                     }
  482.                 }
  483.                 else
  484.                 {
  485.                     short *short16out = (short*) finalS3MCopy, *short16in = (short*) finalS3MCopy;
  486.                     
  487.                     for( x = 0 ; x < dstSize/2; x+=2)
  488.                     {
  489.                         short16out[ x / 2] = ((long) short16in[ x] + (long) short16in[ x + 1]) / 2L;
  490.                     }
  491.                 }
  492.                 dstSize /= 2;
  493.             }
  494.             
  495.             if( curData->amp == 8)
  496.             {
  497.                 for( tempL = 0; tempL < dstSize; tempL++) *(finalS3MCopy + tempL) += 0x80;
  498.             }
  499.             else
  500.             {
  501.                 short *b16 = (short*) finalS3MCopy;
  502.                 long temp;
  503.                 
  504.                 for( temp = 0; temp < dstSize/2; temp++)
  505.                 {
  506.                     *(b16 + temp) += 0x8000;
  507.                     INT16( (b16 + temp));
  508.                 }
  509.             }
  510.             finalS3MCopy += dstSize;
  511.         }
  512.     }
  513.     
  514.     /*********************************/
  515.     /*     Pattern Data -- Pattern Data -- Pattern Data */
  516.     /*********************************/
  517.     
  518.     for (i = 0; i < theMAD->header->numPat; i++)
  519.     {
  520.         long        Row = 0, maxtrackp;
  521.         short        *sizePtr;
  522.         Cmd            nullCmd;
  523.         
  524.         nullCmd.ins        = 0;
  525.         nullCmd.note    = 0xFF;
  526.         nullCmd.cmd        = 0;
  527.         nullCmd.arg        = 0;
  528.         nullCmd.vol        = 0xFF;
  529.         nullCmd.unused    = 0;
  530.         
  531.         parappat[ i] = (16L + finalS3MCopy - finalS3M) / 16L;
  532.         finalS3MCopy = finalS3M + ((long) parappat[ i])*16L;
  533.         INT16(  ¶ppat[ i]);
  534.         
  535.         sizePtr = (short*) finalS3MCopy;
  536.         
  537.         finalS3MCopy++;
  538.         finalS3MCopy++;        // A short is 2 bytes...
  539.         
  540.         while( Row < 64)
  541.         {
  542.             maxtrackp = theMAD->header->numChn;
  543.             if( maxtrackp > 16) maxtrackp = 16;
  544.         
  545.             for( z = 0; z < maxtrackp; z++)
  546.             {
  547.                 Byte        *tempChar = (Byte*) finalS3MCopy;
  548.                 
  549.                 if( Row < theMAD->partition[ i]->header.size)
  550.                 {
  551.                     aCmd = GetMADCommand( Row, z, theMAD->partition[ i]);
  552.                 }
  553.                 else aCmd = &nullCmd;
  554.                 
  555.                 if(            aCmd->note            != 0xFF ||
  556.                             aCmd->ins            != 0 ||
  557.                             aCmd->cmd            != 0 ||
  558.                             aCmd->arg            != 0 ||
  559.                             aCmd->vol            != 0xFF)
  560.                     {
  561.                 //        *tempChar = 0;
  562.                         
  563.                         finalS3MCopy++;
  564.                         
  565.                         // Channel
  566.                         
  567.                         *tempChar    = z;
  568.                         
  569.                         // PERIOD
  570.                         
  571.                         if( aCmd->note != 0xFF || aCmd->ins != 0)
  572.                         {
  573.                             short Octave, Note;
  574.                         
  575.                             *tempChar += 32;
  576.                             
  577.                             if( aCmd->note == 0xFF)
  578.                             {
  579.                                 finalS3MCopy[ 0] = 0xFF;
  580.                             }
  581.                             else
  582.                             {
  583.                                 short curNote;
  584.                                 
  585.                                 if( aCmd->ins != 0)
  586.                                 {
  587.                                     if( theMAD->fid[ aCmd->ins-1].numSamples > 0)
  588.                                                 curNote = aCmd->note + theMAD->sample[ (aCmd->ins-1)*MAXSAMPLE + 0]->relNote;
  589.                                     else     curNote = aCmd->note;
  590.                                 }
  591.                                 else curNote = aCmd->note;
  592.                                 
  593.                                 Octave = curNote / 12;
  594.                                 Note = curNote - Octave*12;
  595.                                 
  596.                                 finalS3MCopy[ 0] = Octave << 4;
  597.                                 finalS3MCopy[ 0] += Note;
  598.                             }
  599.                             
  600.                             finalS3MCopy[ 1] = aCmd->ins;
  601.                             finalS3MCopy += 2L;
  602.                         }
  603.                         
  604.                         // VOLUME
  605.                         
  606.                         if( aCmd->vol != 0xFF || aCmd->cmd == volumeE)
  607.                         {
  608.                             *tempChar += 64;
  609.                             
  610.                             if( aCmd->cmd == volumeE) finalS3MCopy[ 0] = aCmd->arg;
  611.                             else finalS3MCopy[ 0] = aCmd->vol - 0x10;
  612.                             
  613.                             finalS3MCopy += 1L;
  614.                         }
  615.                         
  616.                         // PARAMETER
  617.                         
  618.                         if( aCmd->cmd != 0 || aCmd->arg != 0)
  619.                         {
  620.                             *tempChar += 128;
  621.                             
  622.                             ConvertMADEffect( aCmd->cmd, aCmd->arg, (Byte*) &finalS3MCopy[ 0], (Byte*) &finalS3MCopy[ 1]);
  623.                             
  624.                             finalS3MCopy += 2L;
  625.                         }
  626.                     }
  627.             }
  628.             
  629.             *finalS3MCopy = 0;    // end of row
  630.             finalS3MCopy++;
  631.             Row++;
  632.         }
  633.         
  634.         *sizePtr = finalS3MCopy - (Ptr) sizePtr;
  635.         *sizePtr -= 2;
  636.         INT16(  sizePtr);
  637.     }
  638.     
  639. //    SetPtrSize( finalS3M, finalS3MCopy - finalS3M);
  640.     
  641. //    if( finalS3MCopy > maxfinalS3M) Debugger();
  642.     
  643.     *sndSize = finalS3MCopy - finalS3M;
  644.     
  645.     return( (Ptr) finalS3M);
  646. }
  647.  
  648. OSErr ConvertS3M2Mad( Ptr    theS3M, long size, MADMusic *theMAD, MADDriverSettings *init)
  649. {
  650.     long                     i, x, z, channel, Row;
  651.     long                     starting;
  652.     Ptr                        MaxPtr;
  653.     Ptr                        theInstrument[ MAXINSTRU];
  654.     Byte                    tempChar, *theS3MCopy;
  655.     short                    Note, Octave, maxTrack;
  656.     short                    S3Mperiod[ 12] = {1712,1616,1524,1440,1356,1280,1208,1140,1076,1016, 960, 907};
  657.     
  658.     /**** Variables pour le MAD ****/
  659.     Cmd                *aCmd;
  660.  
  661.     /**** Variables pour le S3M ****/
  662.     
  663.     s3mform            s3minfo;
  664.     /********************************/
  665.  
  666.     for( i = 0 ; i < MAXINSTRU; i ++)
  667.     {
  668.         theInstrument[ i] = 0L;
  669.     }
  670.  
  671.     /**** Header principal *****/
  672.     theS3MCopy = (Byte*) theS3M;
  673.     
  674.     //if( sizeof( s3minfo) < 96) Debugger();        // Just a test..
  675.     
  676.     BlockMove( theS3MCopy, &s3minfo, 96);
  677.     theS3MCopy += 96;
  678.     
  679.     INT16(  &s3minfo.ordernum);
  680.     INT16(  &s3minfo.insnum);
  681.     INT16(  &s3minfo.patnum);
  682.     INT16(  &s3minfo.flags);
  683.     INT16(  &s3minfo.cwtv);
  684.     INT16(  &s3minfo.ffv);
  685.  
  686.     /**** Order Num *****/
  687.     s3minfo.orders = (unsigned char *) MADPlugNewPtr( s3minfo.ordernum, init);
  688.     if( s3minfo.orders == 0L) return MADNeedMemory;
  689.     BlockMove( theS3MCopy, s3minfo.orders, s3minfo.ordernum);
  690.     theS3MCopy += s3minfo.ordernum;
  691.     
  692.     /**** Ins Num *****/
  693.     s3minfo.parapins = (unsigned short *) MADPlugNewPtr( s3minfo.insnum * 2L, init);
  694.     if( s3minfo.parapins == 0L) return MADNeedMemory;
  695.     BlockMove( theS3MCopy, s3minfo.parapins, s3minfo.insnum * 2L);
  696.     theS3MCopy += s3minfo.insnum * 2L;
  697.     for( i = 0; i < s3minfo.insnum; i++)
  698.     {
  699.         INT16(  &s3minfo.parapins[ i]);
  700.     }
  701.     
  702.     
  703.     /**** Pat Num *****/
  704.     s3minfo.parappat = (unsigned short *) MADPlugNewPtr( s3minfo.patnum * 2L, init);
  705.     if( s3minfo.parappat == 0L) return MADNeedMemory;
  706.     BlockMove( theS3MCopy, s3minfo.parappat, s3minfo.patnum * 2L);
  707.     theS3MCopy += s3minfo.patnum * 2L;
  708.     for( i = 0; i < s3minfo.patnum; i++)
  709.     {
  710.         INT16(  &s3minfo.parappat[ i]);
  711.     }
  712.  
  713.     /**** Ins Data ****/
  714.     if( s3minfo.insnum > MAXINSTRU) s3minfo.insnum = MAXINSTRU;
  715.     s3minfo.insdata = (s3minsform *) MADPlugNewPtr( sizeof(s3minsform) * s3minfo.insnum, init);
  716.     if( s3minfo.insdata == 0L) return MADNeedMemory;
  717.     for (i = 0; i < s3minfo.insnum; i++)
  718.     {
  719.         theInstrument[ i] = 0L;
  720.     
  721.         theS3MCopy = (Byte*) theS3M;
  722.         theS3MCopy += s3minfo.parapins[i]*16L;
  723.         
  724.         BlockMove( theS3MCopy, &s3minfo.insdata[i], sizeof(s3minsform));
  725.         
  726.         INT16( &s3minfo.insdata[i].memsegl);
  727.         INT32( &s3minfo.insdata[i].inslength);
  728.         
  729.         if( s3minfo.insdata[i].insflags&1)
  730.         {
  731.             INT32( &s3minfo.insdata[i].insloopbeg);
  732.             INT32( &s3minfo.insdata[i].insloopend);
  733.         }
  734.         else
  735.         {
  736.             s3minfo.insdata[i].insloopbeg        = 0;
  737.             s3minfo.insdata[i].insloopend        = 0;
  738.         }
  739.         
  740.         INT32(  &s3minfo.insdata[i].c2spd);
  741.         INT16(  &s3minfo.insdata[i].insgvspos);
  742.         INT16(  &s3minfo.insdata[i].insint512);
  743.         INT32(  &s3minfo.insdata[i].insintlastused);
  744.         
  745.         if (s3minfo.insdata[i].instype == 1 && s3minfo.insdata[i].inspack == 0 &&
  746.                 s3minfo.insdata[i].inssig[ 0] == 'S' &&
  747.                 s3minfo.insdata[i].inssig[ 1] == 'C' &&
  748.                 s3minfo.insdata[i].inssig[ 2] == 'R' &&
  749.                 s3minfo.insdata[i].inssig[ 3] == 'S')
  750.         {
  751.             long tempL;
  752.  
  753.             theS3MCopy = (Byte*) theS3M;
  754.             
  755.                 tempL = (((long)s3minfo.insdata[i].memsegh)<<16|s3minfo.insdata[i].memsegl)<<4;
  756.             
  757.             theS3MCopy += tempL;
  758.             
  759.             theInstrument[ i] = (Ptr) theS3MCopy;
  760.         }
  761.         else
  762.         {
  763.             theInstrument[ i] = 0L;
  764.         }
  765.     }
  766.  
  767.     /******** Le S3M a ÄtÄ lu et analysÄ ***********/
  768.     /******** Copie des informations dans le MAD ***/
  769.     
  770.     theMAD->header = (MADSpec*) MADPlugNewPtrClear( sizeof( MADSpec), init);
  771.     if( theMAD->header == 0L) return MADNeedMemory;
  772.         
  773.     theMAD->header->MAD = 'MADI';
  774.     for(i=0; i<32; i++) theMAD->header->name[i] = 0;
  775.     for(i=0; i<28; i++) theMAD->header->name[i] = s3minfo.name[i];
  776.     
  777.     MADstrcpy( theMAD->header->infos, (Ptr) "Converted by PlayerPRO S3M Plug (⌐Antoine ROSSET <rossetantoine@bluewin.ch>)");
  778.     
  779.     theMAD->header->numPat        = s3minfo.patnum;
  780.     theMAD->header->numPointers    = s3minfo.ordernum;
  781.     theMAD->header->speed        = s3minfo.initialspeed;
  782.     theMAD->header->tempo        = s3minfo.initialtempo;
  783.     
  784.     for(i=0; i<128; i++) theMAD->header->oPointers[ i] = 0;
  785.     for(i=0; i<s3minfo.ordernum; i++)
  786.     {
  787.         theMAD->header->oPointers[ i] = s3minfo.orders[i];
  788.         
  789.         if( theMAD->header->oPointers[ i] < 0 || theMAD->header->oPointers[ i] >= s3minfo.patnum) theMAD->header->oPointers[ i] = 0;
  790.     }
  791.     
  792.     x = 1;
  793.     for( i = 0; i < MAXTRACK; i++)
  794.     {
  795.         if( x > 0) theMAD->header->chanPan[ i] = MAX_PANNING/4;
  796.         else theMAD->header->chanPan[ i] = MAX_PANNING - MAX_PANNING/4;
  797.         x--;
  798.         
  799.         if( x == -2) x = 2;
  800.         
  801.         theMAD->header->chanVol[ i] = MAX_VOLUME;
  802.     }
  803.     theMAD->header->generalVol        = 64;
  804.     theMAD->header->generalSpeed    = 80;
  805.     theMAD->header->generalPitch    = 80;
  806.  
  807.     /************************/
  808.     /***** INSTRUMENTS  *****/
  809.     /************************/
  810.     
  811.     theMAD->fid = ( InstrData*) MADPlugNewPtrClear( sizeof( InstrData) * (long) MAXINSTRU, init);
  812.     if( !theMAD->fid) return MADNeedMemory;
  813.     
  814.     theMAD->sample = ( sData**) MADPlugNewPtrClear( sizeof( sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, init);
  815.     if( !theMAD->sample) return MADNeedMemory;
  816.     
  817.     for(i  = 0 ; i < MAXINSTRU; i++)
  818.     {
  819.         for( x = 0; x < MAXSAMPLE; x++) theMAD->sample[ i*MAXSAMPLE + x] = 0L;
  820.  
  821.         theMAD->fid[i].numSamples    = 0;
  822.     }
  823.  
  824.     for(i=0; i<s3minfo.insnum; i++)
  825.     {
  826.         InstrData        *curIns = &theMAD->fid[ i];
  827.         
  828.         curIns->type    = 0;
  829.         
  830.         for( x = 0; x < 28; x++) theMAD->fid[i].name[x] = s3minfo.insdata[i].insname[x];
  831.         
  832.         if( theInstrument[ i] != 0L)
  833.         {
  834.             sData    *curData;
  835.  
  836.             curIns->numSamples = 1;
  837.             curIns->volFade = DEFAULT_VOLFADE;
  838.  
  839.             curData = theMAD->sample[ i*MAXSAMPLE + 0] = (sData*) MADPlugNewPtrClear( sizeof( sData), init);
  840.             if( curData == 0L) return MADNeedMemory;
  841.             
  842.             curData->size        = s3minfo.insdata[i].inslength;
  843.             curData->loopBeg     = s3minfo.insdata[i].insloopbeg;
  844.             curData->loopSize     = s3minfo.insdata[i].insloopend - s3minfo.insdata[i].insloopbeg;
  845.             curData->vol        = s3minfo.insdata[i].insvol;
  846.             curData->c2spd        = s3minfo.insdata[i].c2spd;
  847.             curData->loopType    = 0;
  848.             curData->amp        = 8;        if( s3minfo.insdata[i].insflags&4)    curData->amp        = 16;
  849.             
  850.             curData->relNote    = 0;
  851.         //    for( x = 0; x < 28; x++) theMAD->fid[i].name[x] = s3minfo.insdata[i].insname[x];
  852.             
  853.             if( curData->amp == 16)
  854.             {
  855.                 curData->size *= 2;
  856.                 curData->loopBeg *= 2;
  857.                 curData->loopSize *= 2;
  858.             }
  859.             
  860.             curData->data         = MADPlugNewPtr( curData->size, init);
  861.             if( curData->data == 0L) return MADNeedMemory;
  862.             
  863.             if( curData->data != 0L)
  864.             {
  865.                 BlockMove( theInstrument [i], curData->data, curData->size);
  866.                 
  867.                 switch( curData->amp)
  868.                 {
  869.                     case 16:
  870.                     {
  871.                         short *b16 = (short*) curData->data;
  872.                         long temp;
  873.                         
  874.                         for( temp = 0; temp < curData->size/2; temp++)
  875.                         {
  876.                             INT16( (b16 + temp));
  877.                             
  878.                             if( s3minfo.ffv != 1) *(b16 + temp) -= 0x8000;
  879.                         }
  880.                     }
  881.                     break;
  882.                     
  883.                     case 8:
  884.                         if( s3minfo.ffv != 1)
  885.                         {
  886.                             long temp;
  887.                             
  888.                             for( temp = 0; temp < curData->size; temp++) *(curData->data + temp) -= 0x80;
  889.                         }
  890.                     break;
  891.                 }
  892.             }
  893.         }
  894.         else curIns->numSamples = 0;
  895.     }
  896.     
  897.     for( i = 0; i < MAXINSTRU; i++) theMAD->fid[ i].firstSample = i * MAXSAMPLE;
  898.     /********************/
  899.     
  900.     /*********************/
  901.     /*           Check MaxTrack         */
  902.     /*********************/
  903.     
  904.     maxTrack = 0;
  905.     for(i=0;i<32;i++)
  906.     {
  907.         if(s3minfo.chanset[ i] < 32) maxTrack++;
  908.     }
  909.     maxTrack++;
  910.     maxTrack /= 2;
  911.     maxTrack *= 2;
  912.     
  913. /*    maxTrack = 0;
  914.     for( i = 0; i < theMAD->header->numPat ; i++)
  915.     {
  916.         Row = 0;
  917.         
  918.         if( s3minfo.parappat[ i] > 0)
  919.         {
  920.             theS3MCopy = (Byte*) theS3M;
  921.             theS3MCopy += ( (long) s3minfo.parappat[i] )*16L;
  922.             theS3MCopy++;
  923.             
  924.             while( Row < 64)
  925.             {
  926.                 tempChar = *theS3MCopy;
  927.                 theS3MCopy++;
  928.                 
  929.                 if( tempChar == 0) Row++;
  930.                 else
  931.                 {    // Channel
  932.                     channel = tempChar;
  933.                     channel &= 31;
  934.                     
  935.                     if( channel > maxTrack) maxTrack = channel;
  936.                     if( (tempChar & 32) != 0) theS3MCopy += 2L;
  937.                     if( (tempChar & 64) != 0) theS3MCopy += 1L;
  938.                     if( (tempChar & 128) != 0) theS3MCopy += 2L;
  939.                 }
  940.             }
  941.         }
  942.     }
  943.     maxTrack ++;
  944.     
  945.     
  946.     // ** Pair **
  947.     maxTrack++;
  948.     maxTrack /= 2;
  949.     maxTrack *= 2;*/
  950.     /********************/
  951.     /***** TEMPORAIRE ******/
  952.     /********************/
  953.     
  954.     theMAD->header->numChn = maxTrack;
  955.     
  956.     starting = 0;
  957.  
  958.     for( i = 0; i < MAXPATTERN; i++) theMAD->partition[ i] = 0L;
  959.     for( i = 0; i < theMAD->header->numPat ; i++)
  960.     {
  961.         theMAD->partition[ i] = (PatData*) MADPlugNewPtrClear( sizeof( PatHeader) + theMAD->header->numChn * 64L * sizeof( Cmd), init);
  962.         if( theMAD->partition[ i] == 0L) return MADNeedMemory;
  963.         
  964.         theMAD->partition[ i]->header.size = 64L;
  965.         theMAD->partition[ i]->header.compMode = 'NONE';
  966.         
  967.         for( x = 0; x < 20; x++) theMAD->partition[ i]->header.name[ x] = 0;
  968.     
  969.         theMAD->partition[ i]->header.patBytes = 0L;
  970.         theMAD->partition[ i]->header.unused2 = 0L;
  971.     
  972.         MaxPtr = (Ptr) theMAD->partition[ i];
  973.         MaxPtr += sizeof( PatHeader) + theMAD->header->numChn * 64L * sizeof( Cmd);
  974.         
  975.         for( Row = 0; Row < 64; Row++)
  976.         {
  977.             for(z = 0; z < theMAD->header->numChn; z++)
  978.             {
  979.                 aCmd = GetMADCommand( Row, z, theMAD->partition[ i]);
  980.                 
  981.                 aCmd->note        = 0xFF;
  982.                 aCmd->ins            = 0;
  983.                 aCmd->cmd        = 0;
  984.                 aCmd->arg        = 0;
  985.                 aCmd->vol        = 0xFF;
  986.             }
  987.         }
  988.         
  989.         if( s3minfo.parappat[ i] > 0)
  990.         {
  991.             theS3MCopy = (Byte*) theS3M;
  992.             theS3MCopy += ( (long) s3minfo.parappat[i] )*16L;
  993.             theS3MCopy++;
  994.             theS3MCopy++;
  995.             
  996.             Row = 0;
  997.             while( Row < 64)
  998.             {
  999.                 /*
  1000.                     BYTE:flag,     0        =    end of row
  1001.                                 &31        =    channel
  1002.                                 &32        =    follows;  BYTE:note, BYTE:instrument
  1003.                                 &64        =    follows;  BYTE:volume
  1004.                                 &128    =    follows; BYTE:command, BYTE:info
  1005.                 */
  1006.                     
  1007.                     tempChar = *theS3MCopy;
  1008.                     theS3MCopy++;
  1009.     
  1010.                     if( tempChar == 0) Row++;
  1011.                     else
  1012.                     {
  1013.                         // Channel
  1014.                         
  1015.                         channel = tempChar;
  1016.                         channel &= 31;
  1017.                         if( channel >= 0 && channel < theMAD->header->numChn) aCmd = GetMADCommand( Row, channel, theMAD->partition[ i]);
  1018.                         else aCmd = 0L;
  1019.                         
  1020.                         // PERIOD
  1021.                         
  1022.                         if( (tempChar & 32) != 0)
  1023.                         {
  1024.                             if( aCmd != 0L)
  1025.                             {
  1026.                                 aCmd->note = theS3MCopy[ 0];
  1027.                                 
  1028.                                 Octave = (aCmd->note & 0xF0) >> 4;
  1029.                                 Note = (aCmd->note & 0x0F);
  1030.                                     
  1031.                                 aCmd->note = Octave*12 + Note;
  1032.                                 if( aCmd->note < 0 || aCmd->note >= NUMBER_NOTES) aCmd->note = 0xFF;
  1033.                                 
  1034.                                 aCmd->ins = theS3MCopy[ 1];
  1035.                             }
  1036.                             theS3MCopy += 2L;
  1037.                         }
  1038.                         
  1039.                         // VOLUME
  1040.                         
  1041.                         if( (tempChar & 64) != 0)
  1042.                         {
  1043.                             if( aCmd != 0L)
  1044.                             {
  1045.                                 aCmd->vol = theS3MCopy[ 0];
  1046.                                 if( aCmd->vol > 64) aCmd->vol = 64;
  1047.                                 aCmd->vol += 0x10;
  1048.                             }
  1049.                             theS3MCopy += 1L;
  1050.                         }
  1051.                         else aCmd->vol = 255;
  1052.                         
  1053.                         // PARAMETER
  1054.                         
  1055.                         if( (tempChar & 128) != 0)
  1056.                         {
  1057.                             if( aCmd != 0L)
  1058.                             {
  1059.                                 if( theS3MCopy[ 0] != 255)
  1060.                                 {
  1061.                                     ConvertS3MEffect( theS3MCopy[ 0], theS3MCopy[ 1], &aCmd->cmd, &aCmd->arg);
  1062.                                 }
  1063.                             }
  1064.                             theS3MCopy += 2L;
  1065.                         }
  1066.                     }
  1067.             }
  1068.         }
  1069.     }
  1070.     
  1071.     DisposePtr( (Ptr) s3minfo.orders);            DisposePtr( (Ptr) s3minfo.parapins);
  1072.     DisposePtr( (Ptr) s3minfo.parappat);        DisposePtr( (Ptr) s3minfo.insdata);
  1073.  
  1074.     return noErr;
  1075. }
  1076.  
  1077. OSErr ExtractS3MInfo( PPInfoRec *info, Ptr AlienFile)
  1078. {
  1079.     s3mform        *myS3M = ( s3mform*) AlienFile;
  1080.     s3mform        s3minfo;
  1081.     /********************************/
  1082.  
  1083.     /**** Header principal *****/
  1084.     BlockMove( AlienFile, &s3minfo, 96);
  1085.     
  1086.     /*** Signature ***/
  1087.     
  1088.     info->signature = 'S3M ';
  1089.     
  1090.     /*** Internal name ***/
  1091.     
  1092.     myS3M->name[ 27] = '\0';
  1093.     MADstrcpy( info->internalFileName, myS3M->name);
  1094.  
  1095.     /*** Total Patterns ***/
  1096.     
  1097.     INT16(  &s3minfo.patnum);
  1098.     info->totalPatterns = s3minfo.patnum;
  1099.     
  1100.     /*** Partition Length ***/
  1101.     
  1102.     INT16( &s3minfo.ordernum);
  1103.     info->partitionLength = s3minfo.ordernum;
  1104.     
  1105.     /*** Total Instruments ***/
  1106.     
  1107.     INT16(  &s3minfo.insnum);
  1108.     info->totalInstruments = s3minfo.insnum;
  1109.     
  1110.     MADstrcpy( info->formatDescription, "S3M Plug");
  1111.  
  1112.     return noErr;
  1113. }
  1114.  
  1115. OSErr TestS3MFile( Ptr AlienFile)
  1116. {
  1117. s3mform    *myS3M = ( s3mform*) AlienFile;
  1118.  
  1119. if(    myS3M->s3msig[ 0] == 'S' &&
  1120.     myS3M->s3msig[ 1] == 'C' &&
  1121.     myS3M->s3msig[ 2] == 'R' &&
  1122.     myS3M->s3msig[ 3] == 'M') return   noErr;
  1123.     else return  MADFileNotSupportedByThisPlug;
  1124. }
  1125.  
  1126. #ifndef _MAC_H
  1127.  
  1128. extern "C" EXP OSErr FillPlug( PlugInfo *p);
  1129. extern "C" EXP OSErr mainPLUG( OSType order, Ptr AlienFileName, MADMusic *MadFile, PPInfoRec *info, MADDriverSettings *init);
  1130.  
  1131. EXP OSErr FillPlug( PlugInfo *p)
  1132. {
  1133.     MADstrcpy( p->type, ".S3M");
  1134.     MADstrcpy( p->MenuName, "S3M Files");
  1135.     p->mode    =    'EXIM';
  1136.     
  1137.     return noErr;
  1138. }
  1139. #endif
  1140.  
  1141. #ifdef _MAC_H
  1142. EXP OSErr main( OSType order, Ptr AlienFileName, MADMusic *MadFile, PPInfoRec *info, MADDriverSettings *init)
  1143. #else
  1144. OSErr mainPLUG( OSType order, Ptr AlienFileName, MADMusic *MadFile, PPInfoRec *info, MADDriverSettings *init)
  1145. #endif
  1146. {
  1147.     OSErr        myErr;
  1148.     Ptr            AlienFile;
  1149.     long        sndSize;
  1150.     UNFILE    iFileRefI;
  1151.     
  1152.     #ifdef _MAC_H
  1153.     #ifndef powerc
  1154.         long    oldA4 = SetCurrentA4();             //this call is necessary for strings in 68k code resources
  1155.     #endif
  1156.     #endif
  1157.     
  1158.     myErr = noErr;
  1159.  
  1160.     switch( order)
  1161.     {
  1162.         case 'EXPL':
  1163.             AlienFile = ConvertMad2S3M( MadFile, init, &sndSize);
  1164.             
  1165.             if( AlienFile != 0L)
  1166.             {
  1167.                 iFileCreate( AlienFileName, 'S3M ');
  1168.                 iFileRefI = iFileOpen( AlienFileName);
  1169.                 if( iFileRefI)
  1170.                 {
  1171.                     iWrite( sndSize, AlienFile, iFileRefI);
  1172.                     iClose( iFileRefI);
  1173.                 }
  1174.                 DisposePtr( AlienFile);    AlienFile = 0L;
  1175.             }
  1176.             else myErr = MADNeedMemory;
  1177.         break;
  1178.         
  1179.         case 'IMPL':
  1180.             iFileRefI = iFileOpen( AlienFileName);
  1181.             if( iFileRefI)
  1182.             {
  1183.                 sndSize = iGetEOF( iFileRefI);
  1184.                 
  1185.                 // ** MEMORY Test Start
  1186.                 AlienFile = MADPlugNewPtr( sndSize * 2L, init);
  1187.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  1188.                 // ** MEMORY Test End
  1189.                 
  1190.                 else
  1191.                 {
  1192.                     DisposePtr( AlienFile);
  1193.                     
  1194.                     AlienFile = MADPlugNewPtr( sndSize, init);
  1195.                     if( AlienFile == 0L) myErr = MADNeedMemory;
  1196.                     else
  1197.                     {
  1198.                         iRead( sndSize, AlienFile, iFileRefI);
  1199.                         
  1200.                         myErr = TestS3MFile( AlienFile);
  1201.                         if( myErr == noErr)
  1202.                         {
  1203.                             myErr = ConvertS3M2Mad( AlienFile,  sndSize, MadFile, init);
  1204.                         }
  1205.                     }
  1206.                     DisposePtr( AlienFile);    AlienFile = 0L;
  1207.                 }
  1208.                 iClose( iFileRefI);
  1209.             }
  1210.         break;
  1211.         
  1212.         case 'TEST':
  1213.             iFileRefI = iFileOpen( AlienFileName);
  1214.             if( iFileRefI)
  1215.             {
  1216.                 sndSize = 1024L;
  1217.                 
  1218.                 AlienFile = MADPlugNewPtr( sndSize, init);
  1219.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  1220.                 else
  1221.                 {
  1222.                     myErr = iRead( sndSize, AlienFile, iFileRefI);
  1223.                     
  1224.                     myErr = TestS3MFile( AlienFile);
  1225.                     
  1226.                     DisposePtr( AlienFile);    AlienFile = 0L;
  1227.                 }
  1228.                 iClose( iFileRefI);
  1229.             }
  1230.         break;
  1231.  
  1232.         case 'INFO':
  1233.             iFileRefI = iFileOpen( AlienFileName);
  1234.             if( iFileRefI)
  1235.             {
  1236.                 info->fileSize = iGetEOF( iFileRefI);
  1237.             
  1238.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  1239.                 
  1240.                 AlienFile = MADPlugNewPtr( sndSize, init);
  1241.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  1242.                 else
  1243.                 {
  1244.                     myErr = iRead( sndSize, AlienFile, iFileRefI);
  1245.                     if( myErr == noErr)
  1246.                     {
  1247.                         myErr = TestS3MFile( AlienFile);
  1248.                         if( !myErr) myErr = ExtractS3MInfo( info, AlienFile);
  1249.                     }
  1250.                     DisposePtr( AlienFile);    AlienFile = 0L;
  1251.                 }
  1252.                 iClose( iFileRefI);
  1253.             }
  1254.         break;
  1255.         
  1256.         default:
  1257.             myErr = MADOrderNotImplemented;
  1258.         break;
  1259.     }
  1260.  
  1261.     #ifdef _MAC_H
  1262.     #ifndef powerc
  1263.         SetA4( oldA4);
  1264.     #endif
  1265.     #endif
  1266.     
  1267.     return myErr;
  1268. }