mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-11 00:39:59 +00:00
6dcf6c565a
git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@83 ea6a568a-9f4f-0410-981a-c910a81bb256
225 lines
4.2 KiB
Plaintext
225 lines
4.2 KiB
Plaintext
/*
|
|
OpenMW - The completely unofficial reimplementation of Morrowind
|
|
Copyright (C) 2008 Nicolay Korslund
|
|
Email: < korslund@gmail.com >
|
|
WWW: http://openmw.snaptoad.com/
|
|
|
|
This file (jukebox.mn) is part of the OpenMW package.
|
|
|
|
OpenMW is distributed as free software: you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License
|
|
version 3, as published by the Free Software Foundation.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
version 3 along with this program. If not, see
|
|
http://www.gnu.org/licenses/ .
|
|
|
|
*/
|
|
|
|
/*
|
|
A simple jukebox with a playlist. It can play, stop, pause with
|
|
fade in and fade out, and adjust volume.
|
|
*/
|
|
|
|
class Jukebox;
|
|
|
|
// Between 0 (off) and 1 (full volume)
|
|
float fadeLevel = 0.0;
|
|
|
|
// How much to fade in and out each second
|
|
float fadeInRate = 0.14;
|
|
float fadeOutRate = 0.30;
|
|
|
|
// Time between each fade step
|
|
float fadeInterval = 0.2;
|
|
|
|
// List of sounds to play
|
|
char[][] playlist;
|
|
|
|
// Name used for error messages
|
|
char[] name;
|
|
|
|
// Index of current song
|
|
int index;
|
|
|
|
// The music volume, set by the user. Does NOT change to adjust for
|
|
// fading, it is only updated when the user changes the volume
|
|
// settings. Updated from Config through updateVolume().
|
|
float musVolume;
|
|
|
|
bool isPlaying; // Is a song currently playing?
|
|
bool isPaused; // Is the song currently paused?
|
|
|
|
// Native functions to control music
|
|
native setSound(char[] filename);
|
|
native setVolume(float f);
|
|
native playSound();
|
|
native stopSound();
|
|
idle waitUntilFinished();
|
|
|
|
// Fade out and then stop the music. TODO: Rename these to resume()
|
|
// etc and use super.resume, when this is possible.
|
|
pause()
|
|
{
|
|
isPaused = true;
|
|
state = fadeOut;
|
|
}
|
|
|
|
resume()
|
|
{
|
|
if(!Config.useMusic) return;
|
|
|
|
if(isPaused) playSound();
|
|
else next();
|
|
|
|
isPaused = false;
|
|
state = fadeIn;
|
|
}
|
|
|
|
// Stop the current song. Calling resume again after this is called
|
|
// will start a new song.
|
|
stop()
|
|
{
|
|
stopSound();
|
|
|
|
isPlaying = false;
|
|
fadeLevel = 0.0;
|
|
state = null;
|
|
}
|
|
|
|
play()
|
|
{
|
|
if(!Config.useMusic) return;
|
|
|
|
if(index >= playlist.length)
|
|
return;
|
|
|
|
setSound(playlist[index]);
|
|
setVolume(musVolume*fadeLevel);
|
|
playSound();
|
|
|
|
isPlaying = true;
|
|
isPaused = false;
|
|
|
|
state = playing;
|
|
}
|
|
|
|
// Play the next song in the playlist
|
|
next()
|
|
{
|
|
if(!Config.useMusic) return;
|
|
|
|
if(isPlaying)
|
|
stop();
|
|
|
|
// Find the index of the next song, if any
|
|
if(playlist.length == 0) return;
|
|
|
|
if(++index >= playlist.length)
|
|
{
|
|
index = 0;
|
|
randomize();
|
|
}
|
|
|
|
play();
|
|
}
|
|
|
|
// Set the new music volume setting.
|
|
updateVolume(float f)
|
|
{
|
|
musVolume = f;
|
|
if(isPlaying)
|
|
setVolume(musVolume*fadeLevel);
|
|
}
|
|
|
|
setPlaylist(char[][] lst)
|
|
{
|
|
playlist = lst;
|
|
randomize();
|
|
}
|
|
|
|
// Randomize playlist.
|
|
randomize()
|
|
{
|
|
if(playlist.length < 2) return;
|
|
|
|
foreach(int i, char[] s; playlist)
|
|
{
|
|
// Index to switch with
|
|
int idx = randInt(i,playlist.length-1);
|
|
|
|
// To avoid playing the same song twice in a row, don't set the
|
|
// first song to the previous last.
|
|
if(i == 0 && idx == playlist.length-1)
|
|
idx--;
|
|
|
|
if(idx == i) // Skip if swapping with self
|
|
continue;
|
|
|
|
playlist[i] = playlist[idx];
|
|
playlist[idx] = s;
|
|
}
|
|
}
|
|
|
|
// Fade in
|
|
state fadeIn
|
|
{
|
|
begin:
|
|
setVolume(musVolume*fadeLevel);
|
|
|
|
sleep(fadeInterval);
|
|
|
|
fadeLevel += fadeInterval*fadeInRate;
|
|
|
|
if(fadeLevel >= 1.0)
|
|
{
|
|
fadeLevel = 1.0;
|
|
setVolume(musVolume);
|
|
state = playing;
|
|
}
|
|
goto begin;
|
|
}
|
|
|
|
// Fade out
|
|
state fadeOut
|
|
{
|
|
begin:
|
|
sleep(fadeInterval);
|
|
|
|
fadeLevel -= fadeInterval*fadeOutRate;
|
|
|
|
if(fadeLevel <= 0.0)
|
|
{
|
|
fadeLevel = 0.0;
|
|
stopSound();
|
|
isPlaying = false;
|
|
|
|
state = null;
|
|
}
|
|
|
|
setVolume(musVolume*fadeLevel);
|
|
goto begin;
|
|
}
|
|
|
|
state playing
|
|
{
|
|
begin:
|
|
setVolume(musVolume);
|
|
fadeLevel = 1.0;
|
|
|
|
while(true)
|
|
{
|
|
// Wait for the song to play. Will return imediately if the song has
|
|
// already stopped or if no song is playing
|
|
waitUntilFinished();
|
|
|
|
// Start playing the next song
|
|
next();
|
|
}
|
|
}
|