示例#1
0
int songs_play_song( int songnum, int repeat )
{
    songs_init();
    if (!Songs_initialized)
        return 0;

    switch (GameCfg.MusicType)
    {
    case MUSIC_TYPE_BUILTIN:
    {
        // EXCEPTION: If SONG_ENDLEVEL is not available, continue playing level song.
        if (Song_playing >= SONG_FIRST_LEVEL_SONG && songnum == SONG_ENDLEVEL && !PHYSFSX_exists(BIMSongs[songnum].filename, 1))
            return Song_playing;

        Song_playing = -1;
#ifdef _WIN32
        if (GameArg.SndDisableSdlMixer)
        {
            if (digi_win32_play_midi_song( BIMSongs[songnum].filename, repeat )) // NOTE: If SDL_mixer active, this will still be called in mix_play_file in case file is hmp
            {
                Song_playing = songnum;
            }
        }
        else
#endif
#ifdef USE_SDLMIXER
        {
            if (mix_play_file(BIMSongs[songnum].filename, repeat, NULL))
            {
                Song_playing = songnum;
            }
        }
#endif
        break;
    }
    case MUSIC_TYPE_REDBOOK:
    {
        int num_tracks = RBAGetNumberOfTracks();

        Song_playing = -1;
        if ((songnum < SONG_ENDGAME) && (songnum + 2 <= num_tracks))
        {
            if (RBAPlayTracks(songnum + 2, songnum + 2, repeat ? redbook_repeat_func : NULL))
            {
                Redbook_playing = songnum + 2;
                Song_playing = songnum;
            }
        }
        else if ((songnum == SONG_ENDGAME) && (REDBOOK_ENDGAME_TRACK <= num_tracks)) // The endgame track is the last track
        {
            if (RBAPlayTracks(REDBOOK_ENDGAME_TRACK, REDBOOK_ENDGAME_TRACK, repeat ? redbook_repeat_func : NULL))
            {
                Redbook_playing = REDBOOK_ENDGAME_TRACK;
                Song_playing = songnum;
            }
        }
        else if ((songnum > SONG_ENDGAME) && (songnum + 1 <= num_tracks))
        {
            if (RBAPlayTracks(songnum + 1, songnum + 1, repeat ? redbook_repeat_func : NULL))
            {
                Redbook_playing = songnum + 1;
                Song_playing = songnum;
            }
        }
        break;
    }
#ifdef USE_SDLMIXER
    case MUSIC_TYPE_CUSTOM:
    {
        // EXCEPTION: If SONG_ENDLEVEL is undefined, continue playing level song.
        if (Song_playing >= SONG_FIRST_LEVEL_SONG && songnum == SONG_ENDLEVEL && !strlen(GameCfg.CMMiscMusic[songnum]))
            return Song_playing;

        Song_playing = -1;
        if (mix_play_file(GameCfg.CMMiscMusic[songnum], repeat, NULL))
            Song_playing = songnum;
        break;
    }
#endif
    default:
        Song_playing = -1;
        break;
    }

    // If we couldn't play the song, most likely because it wasn't specified, play no music.
    if (Song_playing == -1)
        songs_stop_all();

    return Song_playing;
}
示例#2
0
// play track given by levelnum (depending on the music type and it's playing behaviour) or increment/decrement current track number via offset value
int songs_play_level_song( int levelnum, int offset )
{
    int songnum;

    Assert( levelnum != 0 );

    songs_init();
    if (!Songs_initialized)
        return 0;

    songnum = (levelnum>0)?(levelnum-1):(-levelnum);

    switch (GameCfg.MusicType)
    {
    case MUSIC_TYPE_BUILTIN:
    {
        if (offset)
            return Song_playing;

        Song_playing = -1;
        if ((Num_bim_songs - SONG_FIRST_LEVEL_SONG) > 0)
        {
            songnum = SONG_FIRST_LEVEL_SONG + (songnum % (Num_bim_songs - SONG_FIRST_LEVEL_SONG));
#ifdef _WIN32
            if (GameArg.SndDisableSdlMixer)
            {
                if (digi_win32_play_midi_song( BIMSongs[songnum].filename, 1 )) // NOTE: If SDL_mixer active, this will still be called in mix_play_file in case file is hmp
                {
                    Song_playing = songnum;
                }
            }
#ifdef USE_SDLMIXER
            else
#endif
#endif
#ifdef USE_SDLMIXER
            {
                if (mix_play_file(BIMSongs[songnum].filename, 1, NULL))
                {
                    Song_playing = songnum;
                }
            }
#endif
        }
        break;
    }
    case MUSIC_TYPE_REDBOOK:
    {
        int n_tracks = RBAGetNumberOfTracks();
        int tracknum;

        if (!offset)
        {
            // we have just been told to play the same as we do already -> ignore
            if (Song_playing >= SONG_FIRST_LEVEL_SONG && songnum + SONG_FIRST_LEVEL_SONG == Song_playing)
                return Song_playing;

            tracknum = REDBOOK_FIRST_LEVEL_TRACK + ((n_tracks<=REDBOOK_FIRST_LEVEL_TRACK) ? 0 : (songnum % (n_tracks-REDBOOK_FIRST_LEVEL_TRACK)));
        }
        else
        {
            tracknum = Redbook_playing+offset;
            if (tracknum < REDBOOK_FIRST_LEVEL_TRACK)
                tracknum = n_tracks - (REDBOOK_FIRST_LEVEL_TRACK - tracknum) + 1;
            else if (tracknum > n_tracks)
                tracknum = REDBOOK_FIRST_LEVEL_TRACK + (tracknum - n_tracks) - 1;
        }

        Song_playing = -1;
        if (RBAEnabled() && (tracknum <= n_tracks))
        {
            if (RBAPlayTracks(tracknum, !songs_haved1_cd()?n_tracks:tracknum, songs_haved1_cd() ? redbook_repeat_func : redbook_first_song_func))
            {
                Song_playing = songnum + SONG_FIRST_LEVEL_SONG;
                Redbook_playing = tracknum;
            }
        }
        break;
    }
#ifdef USE_SDLMIXER
    case MUSIC_TYPE_CUSTOM:
    {
        if (GameCfg.CMLevelMusicPlayOrder == MUSIC_CM_PLAYORDER_RAND)
            GameCfg.CMLevelMusicTrack[0] = d_rand() % GameCfg.CMLevelMusicTrack[1]; // simply a random selection - no check if this song has already been played. But that's how I roll!
        else if (!offset)
        {
            if (GameCfg.CMLevelMusicPlayOrder == MUSIC_CM_PLAYORDER_CONT)
            {
                static int last_songnum = -1;

                if (Song_playing >= SONG_FIRST_LEVEL_SONG)
                    return Song_playing;

                // As soon as we start a new level, go to next track
                if (last_songnum != -1 && songnum != last_songnum)
                    ((GameCfg.CMLevelMusicTrack[0]+1>=GameCfg.CMLevelMusicTrack[1])?GameCfg.CMLevelMusicTrack[0]=0:GameCfg.CMLevelMusicTrack[0]++);
                last_songnum = songnum;
            }
            else if (GameCfg.CMLevelMusicPlayOrder == MUSIC_CM_PLAYORDER_LEVEL)
                GameCfg.CMLevelMusicTrack[0] = (songnum % GameCfg.CMLevelMusicTrack[1]);
        }
        else
        {
            GameCfg.CMLevelMusicTrack[0] += offset;
            if (GameCfg.CMLevelMusicTrack[0] < 0)
                GameCfg.CMLevelMusicTrack[0] = GameCfg.CMLevelMusicTrack[1] + GameCfg.CMLevelMusicTrack[0];
            if (GameCfg.CMLevelMusicTrack[0] + 1 > GameCfg.CMLevelMusicTrack[1])
                GameCfg.CMLevelMusicTrack[0] = GameCfg.CMLevelMusicTrack[0] - GameCfg.CMLevelMusicTrack[1];
        }

        Song_playing = -1;
        if (jukebox_play())
            Song_playing = songnum + SONG_FIRST_LEVEL_SONG;

        break;
    }
#endif
    default:
        Song_playing = -1;
        break;
    }

    // If we couldn't play the song, most likely because it wasn't specified, play no music.
    if (Song_playing == -1)
        songs_stop_all();

    return Song_playing;
}
示例#3
0
int mix_play_file(char *filename, int loop, void (*hook_finished_track)())
{
	SDL_RWops *rw = NULL;
	PHYSFS_file *filehandle = NULL;
	char full_path[PATH_MAX];
	char *fptr;
	unsigned int bufsize = 0;

	mix_free_music();	// stop and free what we're already playing, if anything

	fptr = strrchr(filename, '.');

	if (fptr == NULL)
		return 0;

	// It's a .hmp!
	if (!stricmp(fptr, ".hmp"))
	{
#ifdef _WIN32 // on _WIN32, play natively
		return digi_win32_play_midi_song( filename, loop );
#else // otherwise convert and load to current_music
		hmp2mid(filename, &current_music_hndlbuf, &bufsize);
		rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char));
		current_music = Mix_LoadMUS_RW(rw);
#endif
	}

	// try loading music via given filename
	if (!current_music)
		current_music = Mix_LoadMUS(filename);

	// allow the shell convention tilde character to mean the user's home folder
	// chiefly used for default jukebox level song music referenced in 'descent.m3u' for Mac OS X
	if (!current_music && *filename == '~')
	{
		snprintf(full_path, PATH_MAX, "%s%s", PHYSFS_getUserDir(),
				 &filename[1 + (!strncmp(&filename[1], PHYSFS_getDirSeparator(), strlen(PHYSFS_getDirSeparator())) ?
				 strlen(PHYSFS_getDirSeparator()) : 0)]);
		current_music = Mix_LoadMUS(full_path);
		if (current_music)
			filename = full_path;	// used later for possible error reporting
	}


	// no luck. so it might be in Searchpath. So try to build absolute path
	if (!current_music)
	{
		PHYSFSX_getRealPath(filename, full_path);
		current_music = Mix_LoadMUS(full_path);
		if (current_music)
			filename = full_path;	// used later for possible error reporting
	}

	// still nothin'? Let's open via PhysFS in case it's located inside an archive
	if (!current_music)
	{
		filehandle = PHYSFS_openRead(filename);
		if (filehandle != NULL)
		{
			unsigned len = (unsigned)(PHYSFSX_UNSAFE_TRUNCATE_TO_32BIT_INT)PHYSFS_fileLength(filehandle);
			unsigned char *p = (unsigned char *)d_realloc(current_music_hndlbuf, sizeof(char)*len);
			if (p)
			{
			current_music_hndlbuf = p;
			bufsize = (unsigned int)(PHYSFSX_UNSAFE_TRUNCATE_TO_32BIT_INT)PHYSFS_read(filehandle, current_music_hndlbuf, sizeof(char), len);
			rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char));
			current_music = Mix_LoadMUS_RW(rw);
			}
			PHYSFS_close(filehandle);
		}
	}

	if (current_music)
	{
		Mix_PlayMusic(current_music, (loop ? -1 : 1));
		Mix_HookMusicFinished(hook_finished_track ? hook_finished_track : mix_free_music);
		return 1;
	}
	else
	{
		con_printf(CON_CRITICAL,"Music %s could not be loaded: %s\n", filename, Mix_GetError());
		mix_stop_music();
	}

	return 0;
}