⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qmus2mid.c

📁 DOOM游戏的源码,研究DOS下游戏设计
💻 C
📖 第 1 页 / 共 2 页
字号:
      track[i].LastEvent = 0 ;
      track[i].data = NULL ;
    }
  if( BufferSize )
    {
      TRACKBUFFERSIZE = ((int4) BufferSize) << 10 ;
      if( !nodisplay )
        printf( "Track buffer size set to %d KB.\n", BufferSize ) ;
    }

  if( !nodisplay )
    {
      printf( "Converting..." ) ;
      fflush( stdout ) ;
    }
  event = getc( file_mus ) ;
  et = event_type( event ) ;
  MUSchannel = channel( event ) ;
  while( (et != 6) && !feof( file_mus ) && (event != EOF) )
    {
      if( MUS2MIDchannel[MUSchannel] == -1 )
        {
          MIDIchannel = MUS2MIDchannel[MUSchannel ] =
            (MUSchannel == 15 ? 9 : FirstChannelAvailable( MUS2MIDchannel)) ;
          MIDItrack   = MIDIchan2track[MIDIchannel] = (unsigned char) (TrackCnt++);
          if( !(track[MIDItrack].data = (char *) malloc( TRACKBUFFERSIZE )) )
            {
              FreeTracks( track ) ;
              Close() ;
              return MEMALLOC ;
            }
        }
      else
        {
          MIDIchannel = MUS2MIDchannel[MUSchannel] ;
          MIDItrack   = MIDIchan2track [MIDIchannel] ;
        }
      TWriteVarLen( MIDItrack, track[MIDItrack].DeltaTime, track ) ;
      track[MIDItrack].DeltaTime = 0 ;
      switch( et )
        {
        case 0 :                /* release note */
          NewEvent = 0x90 | MIDIchannel ;
          if( (NewEvent != track[MIDItrack].LastEvent) || nocomp )
            {
              TWriteByte( MIDItrack, NewEvent, track ) ;
              track[MIDItrack].LastEvent = NewEvent ;
            }
          else
            n++ ;
          data = getc( file_mus ) ;
          TWriteByte( MIDItrack, data, track ) ;
          TWriteByte( MIDItrack, 0, track ) ;
          break ;
        case 1 :
          NewEvent = 0x90 | MIDIchannel ;
          if( (NewEvent != track[MIDItrack].LastEvent) || nocomp )
            {
              TWriteByte( MIDItrack, NewEvent, track ) ;
              track[MIDItrack].LastEvent = NewEvent ;
            }
          else
            n++ ;
          data = getc( file_mus ) ;
          TWriteByte( MIDItrack, data & 0x7F, track ) ;
          if( data & 0x80 )
            track[MIDItrack].vel = getc( file_mus ) ;
          TWriteByte( MIDItrack, track[MIDItrack].vel, track ) ;
          break ;
        case 2 :
          NewEvent = 0xE0 | MIDIchannel ;
          if( (NewEvent != track[MIDItrack].LastEvent) || nocomp )
            {
              TWriteByte( MIDItrack, NewEvent, track ) ;
              track[MIDItrack].LastEvent = NewEvent ;
            }
          else
            n++ ;
          data = getc( file_mus ) ;
          TWriteByte( MIDItrack, (data & 1) << 6, track ) ;
          TWriteByte( MIDItrack, data >> 1, track ) ;
          break ;
        case 3 :
          NewEvent = 0xB0 | MIDIchannel ;
          if( (NewEvent != track[MIDItrack].LastEvent) || nocomp )
            {
              TWriteByte( MIDItrack, NewEvent, track ) ;
              track[MIDItrack].LastEvent = NewEvent ;
            }
          else
            n++ ;
          data = getc( file_mus ) ;
          TWriteByte( MIDItrack, MUS2MIDcontrol[data], track ) ;
          if( data == 12 )
            TWriteByte( MIDItrack, MUSh.channels+1, track ) ;
          else
            TWriteByte( MIDItrack, 0, track ) ;
          break ;
        case 4 :
          data = getc( file_mus ) ;
          if( data )
            {
              NewEvent = 0xB0 | MIDIchannel ;
              if( (NewEvent != track[MIDItrack].LastEvent) || nocomp )
                {
                  TWriteByte( MIDItrack, NewEvent, track ) ;
                  track[MIDItrack].LastEvent = NewEvent ;
                }
              else
                n++ ;
              TWriteByte( MIDItrack, MUS2MIDcontrol[data], track ) ;
            }
          else
            {
              NewEvent = 0xC0 | MIDIchannel ;
              if( (NewEvent != track[MIDItrack].LastEvent) || nocomp )
                {
                  TWriteByte( MIDItrack, NewEvent, track ) ;
                  track[MIDItrack].LastEvent = NewEvent ;
                }
              else
                n++ ;
            }
          data = getc( file_mus ) ;
          TWriteByte( MIDItrack, data, track ) ;
          break ;
        case 5 :
        case 7 :
          FreeTracks( track ) ;
          Close() ;
          return MUSFILECOR ;
        default : break ;
        }
      if( last( event ) )
	{
          DeltaTime = ReadTime( file_mus ) ;
          TotalTime += DeltaTime ;
	  for( i = 0 ; i < (int) TrackCnt ; i++ )
	    track[i].DeltaTime += DeltaTime ;
        }
      event = getc( file_mus ) ;
      if( event != EOF )
                  {
          et = event_type( event ) ;
          MUSchannel = channel( event ) ;
        }
      else
        ouch = 1 ;
    }
  if( !nodisplay ) printf( "done !\n" ) ;
  if( ouch )
    printf( "WARNING : There are bytes missing at the end of %s.\n          "
           "The end of the MIDI file might not fit the original one.\n", mus ) ;
  if( !division )
    division = 89 ;
  else
    if( !nodisplay ) printf( "Ticks per quarter note set to %d.\n", division ) ;
  if( !nodisplay )
    {
      if( division != 89 )
        {
          time = TotalTime / 140 ;
          min = time / 60 ;
          sec = (char) (time - min*60) ;
          printf( "Playing time of the MUS file : %u'%.2u''.\n", min, sec ) ;
        }
      time = (TotalTime * 89) / (140 * division) ;
      min = time / 60 ;
      sec = (char) (time - min*60) ;
      if( division != 89 )
        printf( "                    MID file" ) ;
      else
        printf( "Playing time" ) ;
      printf( " : %u'%.2u''.\n", min, sec ) ;
    }
  if( !nodisplay )
    {
      printf( "Writing..." ) ;
      fflush( stdout ) ;
    }
  WriteMIDheader( TrackCnt+1, division, file_mid ) ;
  WriteFirstTrack( file_mid ) ;
  for( i = 0 ; i < (int) TrackCnt ; i++ )
    WriteTrack( i, file_mid, track ) ;
  if( !nodisplay )
    printf( "done !\n" ) ;
  if( !nodisplay && !nocomp )
    printf( "Compression : %u%%.\n",
           (100 * n) / (n+ (int4) ftell( file_mid )) ) ;

  FreeTracks( track ) ;
#ifdef MSDOG
  fclose(file_mus);
  fclose(file_mid);
  if( !access( mid, 0 ) )
    if( unlink( mid ) )
      return( CWMIDFILE ) ;

  if( rename( tmp, mid ) )
    return( CWMIDFILE ) ;

#else
  fclose(file_mus);
  fclose(file_mid);
#endif

  return 0 ;
}


int convert( const char *mus, const char *mid, int nodisplay, int div,
            int size, int nocomp, int *ow )
{
  FILE *file ;
  int error;
#ifdef MSDOG
  int n ;
#endif
  struct stat file_data ;
  char buffer[30] ;


  /* we don't need _all_ that checking, do we ? */
  /* Answer : it's more user-friendly */
#ifdef MSDOG

  if( access( mus, 0 ) )
    {
      printf( "ERROR : %s does not exist.\n", mus ) ;
      return 1 ;
    }

#else
  if ( !*ow ) {
    file = fopen(mid, "r");
    if ( file ) {
      fclose(file);
      printf( "qmus2mid: file %s exists, not removed.\n", mid ) ;
      return 2 ;
    }
  }
#endif

  error = qmus2mid( mus, mid, nodisplay, div, size, nocomp ) ;

  if( error )
    {
      printf( "ERROR : " ) ;
      switch( error )
        {
        case NOTMUSFILE :
          printf( "%s is not a MUS file.\n", mus ) ; break ;
        case COMUSFILE :
          printf( "Can't open %s for read.\n", mus ) ; break ;
        case COTMPFILE :
          printf( "Can't open temp file.\n" ) ; break  ;
        case CWMIDFILE :
          printf( "Can't write %s (?).\n", mid ) ; break ;
        case MUSFILECOR :
          printf( "%s is corrupted.\n", mus ) ; break ;
        case TOOMCHAN :
          printf( "%s contains more than 16 channels.\n", mus ) ; break ;
        case MEMALLOC :
          printf( "Not enough memory.\n" ) ; break ;
        default : break ;
        }
      return 4 ;
    }

  if( !nodisplay )
    {
      printf( "%s converted successfully.\n", mus ) ;
      if( (file = fopen( mid, "rb" )) != NULL )
        {
          stat( mid, &file_data ) ;
          fclose( file ) ;
          sprintf( buffer, " : %lu bytes", (unsigned long) file_data.st_size ) ;
        }
      printf( "%s (%scompressed) written%s.\n", mid, nocomp ? "NOT " : "",
             file ? buffer : ""  ) ;
    }

  return 0 ;
}


int CheckParm( char *check, int argc, char *argv[] )
{
  int i;

  for ( i = 1 ; i<argc ; i++ )
#ifdef MSDOG
    if( !stricmp( check, argv[i] ) )
#else
    if( !strcmp( check, argv[i] ) )
#endif
      return i ;

  return 0;
}


void PrintHeader( void )
{
/*  Print( "===============================================================================\n"
         "              Quick MUS->MID v2.0 ! (C) 1995,96 Sebastien Bacquet\n"
         "                        E-mail : bacquet@iie.cnam.fr\n"
         "===============================================================================\n" ) ;*/
}


void PrintSyntax( void )
{
  PrintHeader() ;
  printf(
#ifdef MSDOG
         "\nSyntax : QMUS2MID musfile1[.mus] {musfile2[.mus] ... | "
         "midifile.mid} [options]\n"
         "   Wildcards are accepted.\n"
         "   Options are :\n"
         "     -query    : Query before processing\n"
         "     -ow       : OK, overwrite (without query)\n"
#else
         "\nSyntax : QMUS2MID musfile midifile [options]\n"
         "   Options are :\n"
#endif
         "     -noow     : Don't overwrite !\n"
         "     -nodisp   : Display nothing ! (except errors)\n"
         "     -nocomp   : Don't compress !\n"
         "     -size ### : Set the track buffer size to ### (in KB). "
         "Default = 64 KB\n"
         "     -t ###    : Ticks per quarter note. Default = 89\n"
         ) ;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -