music.c
changeset 173 0821a4ea0008
parent 168 6bc3db482570
child 176 fa3cf3b26af4
     1.1 --- a/music.c	Fri May 03 04:09:27 2002 +0000
     1.2 +++ b/music.c	Thu May 16 18:28:06 2002 +0000
     1.3 @@ -121,7 +121,6 @@
     1.4  #endif
     1.5  	} data;
     1.6  	Mix_Fading fading;
     1.7 -	int fade_volume;
     1.8  	int fade_step;
     1.9  	int fade_steps;
    1.10  	int error;
    1.11 @@ -140,8 +139,11 @@
    1.12  static int ms_per_step;
    1.13  
    1.14  /* Local low-level functions prototypes */
    1.15 -static void lowlevel_halt(void);
    1.16 -static int  lowlevel_play(Mix_Music *music);
    1.17 +static void music_internal_volume(int volume);
    1.18 +static int  music_internal_play(Mix_Music *music, double position);
    1.19 +static int  music_internal_position(double position);
    1.20 +static int  music_internal_playing();
    1.21 +static void music_internal_halt(void);
    1.22  
    1.23  
    1.24  /* Support for hooking when the music has finished */
    1.25 @@ -158,53 +160,43 @@
    1.26  /* Mixing function */
    1.27  void music_mixer(void *udata, Uint8 *stream, int len)
    1.28  {
    1.29 -	if ( music_playing ) {
    1.30 -		if ( music_stopped ) {
    1.31 -			/* To avoid concurrency problems and the use of mutexes,
    1.32 -			   the music is always stopped from the sound thread */
    1.33 -			lowlevel_halt(); /* This function sets music_playing to NULL */
    1.34 -			return;
    1.35 -		}
    1.36 +	if ( music_playing && music_active ) {
    1.37  		/* Handle fading */
    1.38  		if ( music_playing->fading != MIX_NO_FADING ) {
    1.39  			if ( music_playing->fade_step++ < music_playing->fade_steps ) {
    1.40 -				int fade_volume = music_playing->fade_volume;
    1.41 +				int volume;
    1.42  				int fade_step = music_playing->fade_step;
    1.43  				int fade_steps = music_playing->fade_steps;
    1.44  
    1.45  				if ( music_playing->fading == MIX_FADING_OUT ) {
    1.46 -					Mix_VolumeMusic((fade_volume * (fade_steps-fade_step))
    1.47 -									/ fade_steps);
    1.48 +					volume = (music_volume * (fade_steps-fade_step)) / fade_steps;
    1.49  				} else { /* Fading in */
    1.50 -					Mix_VolumeMusic((fade_volume * fade_step) / fade_steps);
    1.51 +					volume = (music_volume * fade_step) / fade_steps;
    1.52  				}
    1.53 +				music_internal_volume(volume);
    1.54  			} else {
    1.55  				if ( music_playing->fading == MIX_FADING_OUT ) {
    1.56 -					lowlevel_halt();
    1.57 +					music_internal_halt();
    1.58 +					if ( music_finished_hook ) {
    1.59 +						music_finished_hook();
    1.60 +					}
    1.61  					return;
    1.62  				}
    1.63  				music_playing->fading = MIX_NO_FADING;
    1.64  			}
    1.65  		}
    1.66  		/* Restart music if it has to loop */
    1.67 -		if ( !Mix_PlayingMusic() ) {
    1.68 -			/* Restart music if it has to loop */
    1.69 +		if ( !music_internal_playing() ) {
    1.70 +			/* Restart music if it has to loop at a high level */
    1.71  			if ( music_loops && --music_loops ) {
    1.72 -				Mix_RewindMusic();
    1.73 -				if ( lowlevel_play(music_playing) < 0 ) {
    1.74 -					fprintf(stderr,"Warning: Music restart failed.\n");
    1.75 -					music_stopped = 1; /* Something went wrong */
    1.76 -					music_playing->fading = MIX_NO_FADING;
    1.77 +				music_internal_play(music_playing, 0.0);
    1.78 +			} else {
    1.79 +				music_internal_halt();
    1.80 +				if ( music_finished_hook ) {
    1.81 +					music_finished_hook();
    1.82  				}
    1.83 +				return;
    1.84  			}
    1.85 -			else if (music_finished_hook) {
    1.86 -			    lowlevel_halt();
    1.87 -			    music_finished_hook();
    1.88 -			    return;
    1.89 -			}
    1.90 -		}
    1.91 -		if ( music_volume <= 0 ) { /* Don't mix if volume is null */
    1.92 -			return;
    1.93  		}
    1.94  		switch (music_playing->type) {
    1.95  #ifdef CMD_MUSIC
    1.96 @@ -535,16 +527,20 @@
    1.97  void Mix_FreeMusic(Mix_Music *music)
    1.98  {
    1.99  	if ( music ) {
   1.100 -		/* Caution: If music is playing, mixer will crash */
   1.101 -		if ( music == music_playing && !music_stopped ) {
   1.102 -			if ( music->fading == MIX_FADING_OUT ) {
   1.103 -				/* Wait for the fade out to finish */
   1.104 -				while ( music_playing && !music_stopped && (music_playing->fading == MIX_FADING_OUT) )
   1.105 -					SDL_Delay(100);
   1.106 -			} else {
   1.107 -				Mix_HaltMusic(); /* Stop it immediately */
   1.108 +		/* Stop the music if it's currently playing */
   1.109 +		SDL_LockAudio();
   1.110 +		if ( music == music_playing ) {
   1.111 +			/* Wait for any fade out to finish */
   1.112 +			while ( music->fading == MIX_FADING_OUT ) {
   1.113 +				SDL_UnlockAudio();
   1.114 +				SDL_Delay(100);
   1.115 +				SDL_LockAudio();
   1.116 +			}
   1.117 +			if ( music == music_playing ) {
   1.118 +				music_internal_halt();
   1.119  			}
   1.120  		}
   1.121 +		SDL_UnlockAudio();
   1.122  		switch (music->type) {
   1.123  #ifdef CMD_MUSIC
   1.124  			case MUS_CMD:
   1.125 @@ -593,150 +589,234 @@
   1.126  	}
   1.127  }
   1.128  
   1.129 -static int lowlevel_play(Mix_Music *music)
   1.130 +/* Play a music chunk.  Returns 0, or -1 if there was an error.
   1.131 + */
   1.132 +static int music_internal_play(Mix_Music *music, double position)
   1.133  {
   1.134 -	if(!music)
   1.135 -		return(-1);
   1.136 +	int retval = 0;
   1.137  
   1.138 +	/* Note the music we're playing */
   1.139 +	if ( music_playing ) {
   1.140 +		music_internal_halt();
   1.141 +	}
   1.142 +	music_playing = music;
   1.143 +
   1.144 +	/* Set the initial volume */
   1.145 +	if ( music->fading == MIX_FADING_IN ) {
   1.146 +		music_internal_volume(0);
   1.147 +	} else {
   1.148 +		music_internal_volume(music_volume);
   1.149 +	}
   1.150 +
   1.151 +	/* Set up for playback */
   1.152  	switch (music->type) {
   1.153  #ifdef CMD_MUSIC
   1.154 -		case MUS_CMD:
   1.155 -			MusicCMD_SetVolume(music_volume);
   1.156 -			MusicCMD_Start(music->data.cmd);
   1.157 -			break;
   1.158 +	    case MUS_CMD:
   1.159 +		MusicCMD_Start(music->data.cmd);
   1.160 +		break;
   1.161  #endif
   1.162  #ifdef WAV_MUSIC
   1.163 -		case MUS_WAV:
   1.164 -			WAVStream_SetVolume(music_volume);
   1.165 -			WAVStream_Start(music->data.wave);
   1.166 -			break;
   1.167 +	    case MUS_WAV:
   1.168 +		WAVStream_Start(music->data.wave);
   1.169 +		break;
   1.170  #endif
   1.171  #ifdef MOD_MUSIC
   1.172 -		case MUS_MOD:
   1.173 -			Player_SetVolume((SWORD)music_volume);
   1.174 -			Player_Start(music->data.module);
   1.175 -			Player_SetPosition(0);
   1.176 -			break;
   1.177 +	    case MUS_MOD:
   1.178 +		Player_Start(music->data.module);
   1.179 +		break;
   1.180  #endif
   1.181  #ifdef MID_MUSIC
   1.182 -		case MUS_MID:
   1.183 +	    case MUS_MID:
   1.184  #ifdef USE_NATIVE_MIDI
   1.185 -  			if ( native_midi_ok ) {
   1.186 -				native_midi_setvolume(music_volume);
   1.187 -				native_midi_start(music->data.nativemidi);
   1.188 -			} MIDI_ELSE
   1.189 +		if ( native_midi_ok ) {
   1.190 +			native_midi_start(music->data.nativemidi);
   1.191 +		} MIDI_ELSE
   1.192  #endif
   1.193  #ifdef USE_TIMIDITY_MIDI
   1.194 -			if ( timidity_ok ) {
   1.195 -				Timidity_SetVolume(music_volume);
   1.196 -				Timidity_Start(music->data.midi);
   1.197 -			}
   1.198 +		if ( timidity_ok ) {
   1.199 +			Timidity_Start(music->data.midi);
   1.200 +		}
   1.201  #endif
   1.202 -			break;
   1.203 +		break;
   1.204  #endif
   1.205  #ifdef OGG_MUSIC
   1.206 -		case MUS_OGG:
   1.207 -			OGG_setvolume(music->data.ogg, music_volume);
   1.208 -			OGG_play(music->data.ogg);
   1.209 -			break;
   1.210 +	    case MUS_OGG:
   1.211 +		OGG_play(music->data.ogg);
   1.212 +		break;
   1.213  #endif
   1.214  #ifdef MP3_MUSIC
   1.215 -		case MUS_MP3:
   1.216 -			SMPEG_enableaudio(music->data.mp3,1);
   1.217 -			SMPEG_enablevideo(music->data.mp3,0);
   1.218 -			SMPEG_setvolume(music->data.mp3,(int)(((float)music_volume/(float)MIX_MAX_VOLUME)*100.0));
   1.219 -			SMPEG_play(music->data.mp3);
   1.220 -			break;
   1.221 +	    case MUS_MP3:
   1.222 +		SMPEG_enableaudio(music->data.mp3,1);
   1.223 +		SMPEG_enablevideo(music->data.mp3,0);
   1.224 +		SMPEG_play(music->data.mp3);
   1.225 +		break;
   1.226  #endif
   1.227 -		default:
   1.228 -			/* Unknown music type?? */
   1.229 -			return(-1);
   1.230 +	    default:
   1.231 +		Mix_SetError("Can't play unknown music type");
   1.232 +		retval = -1;
   1.233 +		break;
   1.234  	}
   1.235 -	return(0);
   1.236 +
   1.237 +	/* Set the playback position, note any errors if an offset is used */
   1.238 +	if ( retval == 0 ) {
   1.239 +		if ( position > 0.0 ) {
   1.240 +			if ( music_internal_position(position) < 0 ) {
   1.241 +				Mix_SetError("Position not implemented for music type");
   1.242 +				retval = -1;
   1.243 +			}
   1.244 +		} else {
   1.245 +			music_internal_position(0.0);
   1.246 +		}
   1.247 +	}
   1.248 +
   1.249 +	/* If the setup failed, we're not playing any music anymore */
   1.250 +	if ( retval < 0 ) {
   1.251 +		music_playing = NULL;
   1.252 +	}
   1.253 +	return(retval);
   1.254 +}
   1.255 +int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
   1.256 +{
   1.257 +	int retval;
   1.258 +
   1.259 +	/* Don't play null pointers :-) */
   1.260 +	if ( music == NULL ) {
   1.261 +		Mix_SetError("music parameter was NULL");
   1.262 +		return(-1);
   1.263 +	}
   1.264 +
   1.265 +	/* Setup the data */
   1.266 +	if ( ms ) {
   1.267 +		music->fading = MIX_FADING_IN;
   1.268 +	} else {
   1.269 +		music->fading = MIX_NO_FADING;
   1.270 +	}
   1.271 +	music->fade_step = 0;
   1.272 +	music->fade_steps = ms/ms_per_step;
   1.273 +
   1.274 +	/* Play the puppy */
   1.275 +	SDL_LockAudio();
   1.276 +	/* If the current music is fading out, wait for the fade to complete */
   1.277 +	while ( music_playing && (music_playing->fading == MIX_FADING_OUT) ) {
   1.278 +		SDL_UnlockAudio();
   1.279 +		SDL_Delay(100);
   1.280 +		SDL_LockAudio();
   1.281 +	}
   1.282 +	music_active = 1;
   1.283 +	music_loops = loops;
   1.284 +	retval = music_internal_play(music, position);
   1.285 +	SDL_UnlockAudio();
   1.286 +
   1.287 +	return(retval);
   1.288 +}
   1.289 +int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
   1.290 +{
   1.291 +	return Mix_FadeInMusicPos(music, loops, ms, 0.0);
   1.292 +}
   1.293 +int Mix_PlayMusic(Mix_Music *music, int loops)
   1.294 +{
   1.295 +	return Mix_FadeInMusicPos(music, loops, 0, 0.0);
   1.296  }
   1.297  
   1.298 -/* Play a music chunk.  Returns 0, or -1 if there was an error.
   1.299 -*/
   1.300 -int Mix_PlayMusic(Mix_Music *music, int loops)
   1.301 +/* Set the playing music position */
   1.302 +int music_internal_position(double position)
   1.303  {
   1.304 -	/* Don't play null pointers :-) */
   1.305 -	if ( music == NULL ) {
   1.306 -		return(-1);
   1.307 +	int retval = 0;
   1.308 +
   1.309 +	switch (music_playing->type) {
   1.310 +#ifdef MOD_MUSIC
   1.311 +	    case MUS_MOD:
   1.312 +		Player_SetPosition((UWORD)position);
   1.313 +		break;
   1.314 +#endif
   1.315 +#ifdef OGG_MUSIC
   1.316 +	    case MUS_OGG:
   1.317 +		OGG_jump_to_time(music_playing->data.ogg, position);
   1.318 +		break;
   1.319 +#endif
   1.320 +#ifdef MP3_MUSIC
   1.321 +	    case MUS_MP3:
   1.322 +		if ( position == 0.0 ) {
   1.323 +			SMPEG_rewind(music_playing->data.mp3);
   1.324 +		} else {
   1.325 +			SMPEG_skip(music_playing->data.mp3, position);
   1.326 +		}
   1.327 +		break;
   1.328 +#endif
   1.329 +	    default:
   1.330 +		/* TODO: Implement this for other music backends */
   1.331 +		retval = -1;
   1.332 +		break;
   1.333  	}
   1.334 -	/* If the current music is fading out, wait for the fade to complete */
   1.335 -	while ( music_playing && !music_stopped && music_playing->fading==MIX_FADING_OUT ) {
   1.336 -		SDL_Delay(100);
   1.337 -	}
   1.338 -
   1.339 -	if ( lowlevel_play(music) < 0 ) {
   1.340 -		return(-1);
   1.341 -	}
   1.342 -	music_active = 1;
   1.343 -	music_stopped = 0;
   1.344 -	music_loops = loops;
   1.345 -	music_playing = music;
   1.346 -	music_playing->fading = MIX_NO_FADING;
   1.347 -	return(0);
   1.348 +	return(retval);
   1.349  }
   1.350 -
   1.351  int Mix_SetMusicPosition(double position)
   1.352  {
   1.353 -	if ( music_playing && !music_stopped ) {
   1.354 -		switch ( music_playing->type ) {
   1.355 -#ifdef MOD_MUSIC
   1.356 -		case MUS_MOD:
   1.357 -			Player_SetPosition((UWORD)position);
   1.358 -			return(0);
   1.359 -			break;
   1.360 -#endif
   1.361 -#ifdef OGG_MUSIC
   1.362 -		case MUS_OGG:
   1.363 -			OGG_jump_to_time(music_playing->data.ogg, position);
   1.364 -			return(0);
   1.365 -			break;
   1.366 -#endif
   1.367 -#ifdef MP3_MUSIC
   1.368 -		case MUS_MP3:
   1.369 -			SMPEG_skip(music_playing->data.mp3, position);
   1.370 -			return(0);
   1.371 -			break;
   1.372 -#endif
   1.373 -		default:
   1.374 -			/* TODO: Implement this for other music backends */
   1.375 -			break;
   1.376 +	int retval;
   1.377 +
   1.378 +	SDL_LockAudio();
   1.379 +	if ( music_playing ) {
   1.380 +		retval = music_internal_position(position);
   1.381 +		if ( retval < 0 ) {
   1.382 +			Mix_SetError("Position not implemented for music type");
   1.383  		}
   1.384 +	} else {
   1.385 +		Mix_SetError("Music isn't playing");
   1.386 +		retval = -1;
   1.387  	}
   1.388 -	return(-1);
   1.389 -}
   1.390 +	SDL_UnlockAudio();
   1.391  
   1.392 -/* Fade in a music over "ms" milliseconds */
   1.393 -int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
   1.394 -{
   1.395 -	if ( music && music_volume > 0 ) { /* No need to fade if we can't hear it */
   1.396 -		music->fade_volume = music_volume;
   1.397 -		music_volume = 0;
   1.398 -		if ( Mix_PlayMusic(music, loops) < 0 ) {
   1.399 -			return(-1);
   1.400 -		}
   1.401 -		if ( position ) {
   1.402 -			if ( Mix_SetMusicPosition(position) < 0 ) {
   1.403 -				Mix_HaltMusic();
   1.404 -				return(-1);
   1.405 -			}
   1.406 -		}
   1.407 -		music_playing->fade_step = 0;
   1.408 -		music_playing->fade_steps = ms/ms_per_step;
   1.409 -		music_playing->fading = MIX_FADING_IN;
   1.410 -	}
   1.411 -	return(0);
   1.412 -}
   1.413 -
   1.414 -int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
   1.415 -{
   1.416 -	return Mix_FadeInMusicPos(music, loops, ms, 0);
   1.417 +	return(retval);
   1.418  }
   1.419  
   1.420  /* Set the music volume */
   1.421 +static void music_internal_volume(int volume)
   1.422 +{
   1.423 +	switch (music_playing->type) {
   1.424 +#ifdef CMD_MUSIC
   1.425 +	    case MUS_CMD:
   1.426 +		MusicCMD_SetVolume(volume);
   1.427 +		break;
   1.428 +#endif
   1.429 +#ifdef WAV_MUSIC
   1.430 +	    case MUS_WAV:
   1.431 +		WAVStream_SetVolume(volume);
   1.432 +		break;
   1.433 +#endif
   1.434 +#ifdef MOD_MUSIC
   1.435 +	    case MUS_MOD:
   1.436 +		Player_SetVolume((SWORD)volume);
   1.437 +		break;
   1.438 +#endif
   1.439 +#ifdef MID_MUSIC
   1.440 +	    case MUS_MID:
   1.441 +#ifdef USE_NATIVE_MIDI
   1.442 +		if ( native_midi_ok ) {
   1.443 +			native_midi_setvolume(volume);
   1.444 +		} MIDI_ELSE
   1.445 +#endif
   1.446 +#ifdef USE_TIMIDITY_MIDI
   1.447 +		if ( timidity_ok ) {
   1.448 +			Timidity_SetVolume(volume);
   1.449 +		}
   1.450 +#endif
   1.451 +		break;
   1.452 +#endif
   1.453 +#ifdef OGG_MUSIC
   1.454 +	    case MUS_OGG:
   1.455 +		OGG_setvolume(music_playing->data.ogg, volume);
   1.456 +		break;
   1.457 +#endif
   1.458 +#ifdef MP3_MUSIC
   1.459 +	    case MUS_MP3:
   1.460 +		SMPEG_setvolume(music_playing->data.mp3,(int)(((float)volume/(float)MIX_MAX_VOLUME)*100.0));
   1.461 +		break;
   1.462 +#endif
   1.463 +	    default:
   1.464 +		/* Unknown music type?? */
   1.465 +		break;
   1.466 +	}
   1.467 +}
   1.468  int Mix_VolumeMusic(int volume)
   1.469  {
   1.470  	int prev_volume;
   1.471 @@ -749,75 +829,35 @@
   1.472  		volume = SDL_MIX_MAXVOLUME;
   1.473  	}
   1.474  	music_volume = volume;
   1.475 -	if ( music_playing && !music_stopped ) {
   1.476 -		switch (music_playing->type) {
   1.477 -#ifdef CMD_MUSIC
   1.478 -		case MUS_CMD:
   1.479 -			MusicCMD_SetVolume(music_volume);
   1.480 -			break;
   1.481 -#endif
   1.482 -#ifdef WAV_MUSIC
   1.483 -		case MUS_WAV:
   1.484 -			WAVStream_SetVolume(music_volume);
   1.485 -			break;
   1.486 -#endif
   1.487 -#ifdef MOD_MUSIC
   1.488 -		case MUS_MOD:
   1.489 -			Player_SetVolume((SWORD)music_volume);
   1.490 -			break;
   1.491 -#endif
   1.492 -#ifdef MID_MUSIC
   1.493 -		case MUS_MID:
   1.494 -#ifdef USE_NATIVE_MIDI
   1.495 -			if ( native_midi_ok ) {
   1.496 -				native_midi_setvolume(music_volume);
   1.497 -			} MIDI_ELSE
   1.498 -#endif
   1.499 -#ifdef USE_TIMIDITY_MIDI
   1.500 -			if ( timidity_ok ) {
   1.501 -				Timidity_SetVolume(music_volume);
   1.502 -			}
   1.503 -#endif
   1.504 -			break;
   1.505 -#endif
   1.506 -#ifdef OGG_MUSIC
   1.507 -		case MUS_OGG:
   1.508 -			OGG_setvolume(music_playing->data.ogg, music_volume);
   1.509 -			break;
   1.510 -#endif
   1.511 -#ifdef MP3_MUSIC
   1.512 -		case MUS_MP3:
   1.513 -			SMPEG_setvolume(music_playing->data.mp3,(int)(((float)music_volume/(float)MIX_MAX_VOLUME)*100.0));
   1.514 -			break;
   1.515 -#endif
   1.516 -		default:
   1.517 -			/* Unknown music type?? */
   1.518 -			break;
   1.519 -		}
   1.520 +	SDL_LockAudio();
   1.521 +	if ( music_playing ) {
   1.522 +		music_internal_volume(music_volume);
   1.523  	}
   1.524 +	SDL_UnlockAudio();
   1.525  	return(prev_volume);
   1.526  }
   1.527  
   1.528 -static void lowlevel_halt(void)
   1.529 +/* Halt playing of music */
   1.530 +static void music_internal_halt(void)
   1.531  {
   1.532  	switch (music_playing->type) {
   1.533  #ifdef CMD_MUSIC
   1.534 -	case MUS_CMD:
   1.535 +	    case MUS_CMD:
   1.536  		MusicCMD_Stop(music_playing->data.cmd);
   1.537  		break;
   1.538  #endif
   1.539  #ifdef WAV_MUSIC
   1.540 -	case MUS_WAV:
   1.541 +	    case MUS_WAV:
   1.542  		WAVStream_Stop();
   1.543  		break;
   1.544  #endif
   1.545  #ifdef MOD_MUSIC
   1.546 -	case MUS_MOD:
   1.547 +	    case MUS_MOD:
   1.548  		Player_Stop();
   1.549  		break;
   1.550  #endif
   1.551  #ifdef MID_MUSIC
   1.552 -	case MUS_MID:
   1.553 +	    case MUS_MID:
   1.554  #ifdef USE_NATIVE_MIDI
   1.555  		if ( native_midi_ok ) {
   1.556  			native_midi_stop();
   1.557 @@ -831,113 +871,77 @@
   1.558  		break;
   1.559  #endif
   1.560  #ifdef OGG_MUSIC
   1.561 -	case MUS_OGG:
   1.562 +	    case MUS_OGG:
   1.563  		OGG_stop(music_playing->data.ogg);
   1.564  		break;
   1.565  #endif
   1.566  #ifdef MP3_MUSIC
   1.567 -	case MUS_MP3:
   1.568 +	    case MUS_MP3:
   1.569  		SMPEG_stop(music_playing->data.mp3);
   1.570  		break;
   1.571  #endif
   1.572 -	default:
   1.573 +	    default:
   1.574  		/* Unknown music type?? */
   1.575  		return;
   1.576  	}
   1.577 -	if ( music_playing->fading != MIX_NO_FADING ) /* Restore volume */
   1.578 -		music_volume = music_playing->fade_volume;
   1.579  	music_playing->fading = MIX_NO_FADING;
   1.580  	music_playing = NULL;
   1.581 -	music_active = 0;
   1.582 -	music_loops = 0;
   1.583 -	music_stopped = 0;
   1.584  }
   1.585 -
   1.586 -/* Halt playing of music */
   1.587  int Mix_HaltMusic(void)
   1.588  {
   1.589 -	if ( music_playing && !music_stopped ) {
   1.590 -		/* Mark the music to be stopped from the sound thread */
   1.591 -		music_stopped = 1;
   1.592 -		/* Wait for it to be actually stopped */
   1.593 -		while ( music_playing && music_active )
   1.594 -			SDL_Delay(10);
   1.595 +	SDL_LockAudio();
   1.596 +	if ( music_playing ) {
   1.597 +		music_internal_halt();
   1.598  	}
   1.599 +	SDL_UnlockAudio();
   1.600 +
   1.601  	return(0);
   1.602  }
   1.603  
   1.604  /* Progressively stop the music */
   1.605  int Mix_FadeOutMusic(int ms)
   1.606  {
   1.607 -	if ( music_playing && !music_stopped &&
   1.608 -	     (music_playing->fading == MIX_NO_FADING) ) {
   1.609 -		if ( music_volume > 0 ) {
   1.610 -			music_playing->fading = MIX_FADING_OUT;
   1.611 -			music_playing->fade_volume = music_volume;
   1.612 -			music_playing->fade_step = 0;
   1.613 -			music_playing->fade_steps = ms/ms_per_step;
   1.614 -			return(1);
   1.615 -		}
   1.616 +	int retval = 0;
   1.617 +
   1.618 +	SDL_LockAudio();
   1.619 +	if ( music_playing && (music_playing->fading == MIX_NO_FADING) ) {
   1.620 +		music_playing->fading = MIX_FADING_OUT;
   1.621 +		music_playing->fade_step = 0;
   1.622 +		music_playing->fade_steps = ms/ms_per_step;
   1.623 +		retval = 1;
   1.624  	}
   1.625 -	return(0);
   1.626 +	SDL_UnlockAudio();
   1.627 +
   1.628 +	return(retval);
   1.629  }
   1.630  
   1.631  Mix_Fading Mix_FadingMusic(void)
   1.632  {
   1.633 -	if( music_playing && !music_stopped )
   1.634 -		return music_playing->fading;
   1.635 -	return MIX_NO_FADING;
   1.636 +	Mix_Fading fading = MIX_NO_FADING;
   1.637 +
   1.638 +	SDL_LockAudio();
   1.639 +	if ( music_playing ) {
   1.640 +		fading = music_playing->fading;
   1.641 +	}
   1.642 +	SDL_UnlockAudio();
   1.643 +
   1.644 +	return(fading);
   1.645  }
   1.646  
   1.647  /* Pause/Resume the music stream */
   1.648  void Mix_PauseMusic(void)
   1.649  {
   1.650 -	if ( music_playing && !music_stopped ) {
   1.651 -		music_active = 0;
   1.652 -	}
   1.653 +	music_active = 0;
   1.654  }
   1.655  
   1.656  void Mix_ResumeMusic(void)
   1.657  {
   1.658 -	if ( music_playing && !music_stopped ) {
   1.659 -		music_active = 1;
   1.660 -	}
   1.661 +	music_active = 1;
   1.662  }
   1.663  
   1.664  void Mix_RewindMusic(void)
   1.665  {
   1.666 -	if ( music_playing && !music_stopped ) {
   1.667 -		switch ( music_playing->type ) {
   1.668 -#ifdef MOD_MUSIC
   1.669 -		case MUS_MOD:
   1.670 -			Player_Start(music_playing->data.module);
   1.671 -			Player_SetPosition(0);
   1.672 -			break;
   1.673 -#endif
   1.674 -#ifdef MP3_MUSIC
   1.675 -		case MUS_MP3:
   1.676 -			SMPEG_rewind(music_playing->data.mp3);
   1.677 -			break;
   1.678 -#endif
   1.679 -#ifdef OGG_MUSIC
   1.680 -		case MUS_OGG:
   1.681 -			OGG_jump_to_time(music_playing->data.ogg, 0);
   1.682 -			break;
   1.683 -#endif
   1.684 -#ifdef MID_MUSIC
   1.685 -		case MUS_MID:
   1.686 -#ifdef USE_NATIVE_MIDI
   1.687 -			if ( native_midi_ok ) {
   1.688 -				native_midi_stop();
   1.689 -			}
   1.690 -#endif
   1.691 -			break;
   1.692 -#endif
   1.693 -		default:
   1.694 -			/* TODO: Implement this for other music backends */
   1.695 -			break;
   1.696 -		}
   1.697 -	}
   1.698 +	Mix_SetMusicPosition(0.0);
   1.699  }
   1.700  
   1.701  int Mix_PausedMusic(void)
   1.702 @@ -946,66 +950,77 @@
   1.703  }
   1.704  
   1.705  /* Check the status of the music */
   1.706 +static int music_internal_playing()
   1.707 +{
   1.708 +	int playing = 1;
   1.709 +	switch (music_playing->type) {
   1.710 +#ifdef CMD_MUSIC
   1.711 +	    case MUS_CMD:
   1.712 +		if (!MusicCMD_Active(music_playing->data.cmd)) {
   1.713 +			playing = 0;
   1.714 +		}
   1.715 +		break;
   1.716 +#endif
   1.717 +#ifdef WAV_MUSIC
   1.718 +	    case MUS_WAV:
   1.719 +		if ( ! WAVStream_Active() ) {
   1.720 +			playing = 0;
   1.721 +		}
   1.722 +		break;
   1.723 +#endif
   1.724 +#ifdef MOD_MUSIC
   1.725 +	    case MUS_MOD:
   1.726 +		if ( ! Player_Active() ) {
   1.727 +			playing = 0;
   1.728 +		}
   1.729 +		break;
   1.730 +#endif
   1.731 +#ifdef MID_MUSIC
   1.732 +	    case MUS_MID:
   1.733 +#ifdef USE_NATIVE_MIDI
   1.734 +		if ( native_midi_ok ) {
   1.735 +			if ( ! native_midi_active() )
   1.736 +				playing = 0;
   1.737 +		} MIDI_ELSE
   1.738 +#endif
   1.739 +#ifdef USE_TIMIDITY_MIDI
   1.740 +		if ( timidity_ok ) {
   1.741 +			if ( ! Timidity_Active() )
   1.742 +				playing = 0;
   1.743 +		}
   1.744 +#endif
   1.745 +		break;
   1.746 +#endif
   1.747 +#ifdef OGG_MUSIC
   1.748 +	    case MUS_OGG:
   1.749 +		if ( ! OGG_playing(music_playing->data.ogg) ) {
   1.750 +			playing = 0;
   1.751 +		}
   1.752 +		break;
   1.753 +#endif
   1.754 +#ifdef MP3_MUSIC
   1.755 +	    case MUS_MP3:
   1.756 +		if ( SMPEG_status(music_playing->data.mp3) != SMPEG_PLAYING )
   1.757 +			playing = 0;
   1.758 +		break;
   1.759 +#endif
   1.760 +	    default:
   1.761 +		playing = 0;
   1.762 +		break;
   1.763 +	}
   1.764 +	return(playing);
   1.765 +}
   1.766  int Mix_PlayingMusic(void)
   1.767  {
   1.768 -	if ( music_playing && ! music_stopped ) {
   1.769 -		switch (music_playing->type) {
   1.770 -#ifdef CMD_MUSIC
   1.771 -			case MUS_CMD:
   1.772 -				if (!MusicCMD_Active(music_playing->data.cmd)) {
   1.773 -					return(0);
   1.774 -				}
   1.775 -				break;
   1.776 -#endif
   1.777 -#ifdef WAV_MUSIC
   1.778 -			case MUS_WAV:
   1.779 -				if ( ! WAVStream_Active() ) {
   1.780 -					return(0);
   1.781 -				}
   1.782 -				break;
   1.783 -#endif
   1.784 -#ifdef MOD_MUSIC
   1.785 -			case MUS_MOD:
   1.786 -				if ( ! Player_Active() ) {
   1.787 -					return(0);
   1.788 -				}
   1.789 -				break;
   1.790 -#endif
   1.791 -#ifdef MID_MUSIC
   1.792 -			case MUS_MID:
   1.793 -#ifdef USE_NATIVE_MIDI
   1.794 -				if ( native_midi_ok ) {
   1.795 -					if ( ! native_midi_active() )
   1.796 -						return(0);
   1.797 -				} MIDI_ELSE
   1.798 -#endif
   1.799 -#ifdef USE_TIMIDITY_MIDI
   1.800 -				if ( timidity_ok ) {
   1.801 -					if ( ! Timidity_Active() )
   1.802 -						return(0);
   1.803 -				}
   1.804 -#endif
   1.805 -				break;
   1.806 -#endif
   1.807 -#ifdef OGG_MUSIC
   1.808 -			case MUS_OGG:
   1.809 -				if ( ! OGG_playing(music_playing->data.ogg) ) {
   1.810 -					return(0);
   1.811 -				}
   1.812 -				break;
   1.813 -#endif
   1.814 -#ifdef MP3_MUSIC
   1.815 -			case MUS_MP3:
   1.816 -				if ( SMPEG_status(music_playing->data.mp3) != SMPEG_PLAYING )
   1.817 -					return(0);
   1.818 -				break;
   1.819 -#endif
   1.820 -			default:
   1.821 -				break;
   1.822 -		}
   1.823 -		return(1);
   1.824 +	int playing = 0;
   1.825 +
   1.826 +	SDL_LockAudio();
   1.827 +	if ( music_playing ) {
   1.828 +		playing = music_internal_playing();
   1.829  	}
   1.830 -	return(0);
   1.831 +	SDL_UnlockAudio();
   1.832 +
   1.833 +	return(playing);
   1.834  }
   1.835  
   1.836  /* Set the external music playback command */
   1.837 @@ -1031,17 +1046,17 @@
   1.838  	if ( music_playing && ! music_stopped ) {
   1.839  		switch (music_playing->type) {
   1.840  #ifdef MOD_MUSIC
   1.841 -			case MUS_MOD:
   1.842 -				if ( ! Player_Active() ) {
   1.843 -					return(-1);
   1.844 -				}
   1.845 -				Player_SetSynchroValue(i);
   1.846 -				return 0;
   1.847 -				break;
   1.848 +		    case MUS_MOD:
   1.849 +			if ( ! Player_Active() ) {
   1.850 +				return(-1);
   1.851 +			}
   1.852 +			Player_SetSynchroValue(i);
   1.853 +			return 0;
   1.854 +			break;
   1.855  #endif
   1.856 -			default:
   1.857 -				return(-1);
   1.858 -				break;
   1.859 +		    default:
   1.860 +			return(-1);
   1.861 +			break;
   1.862  		}
   1.863  		return(-1);
   1.864  	}
   1.865 @@ -1053,16 +1068,16 @@
   1.866  	if ( music_playing && ! music_stopped ) {
   1.867  		switch (music_playing->type) {
   1.868  #ifdef MOD_MUSIC
   1.869 -			case MUS_MOD:
   1.870 -				if ( ! Player_Active() ) {
   1.871 -					return(-1);
   1.872 -				}
   1.873 -				return Player_GetSynchroValue();
   1.874 -				break;
   1.875 +		    case MUS_MOD:
   1.876 +			if ( ! Player_Active() ) {
   1.877 +				return(-1);
   1.878 +			}
   1.879 +			return Player_GetSynchroValue();
   1.880 +			break;
   1.881  #endif
   1.882 -			default:
   1.883 -				return(-1);
   1.884 -				break;
   1.885 +		    default:
   1.886 +			return(-1);
   1.887 +			break;
   1.888  		}
   1.889  		return(-1);
   1.890  	}