Revert "just treat music like a sound channel to fix war1gus#195"
This reverts commit 69f59b879b
.
This commit is contained in:
parent
94016eb710
commit
1a8db4b431
6 changed files with 164 additions and 72 deletions
|
@ -269,6 +269,7 @@ set(pathfinder_SRCS
|
|||
source_group(pathfinder FILES ${pathfinder_SRCS})
|
||||
|
||||
set(sound_SRCS
|
||||
src/sound/music.cpp
|
||||
src/sound/script_sound.cpp
|
||||
src/sound/sound.cpp
|
||||
src/sound/sound_id.cpp
|
||||
|
|
|
@ -68,7 +68,7 @@ extern bool UnitSoundIsPlaying(Origin *origin);
|
|||
/// Check, if this sample is already playing
|
||||
extern bool SampleIsPlaying(Mix_Chunk *sample);
|
||||
/// Load music
|
||||
extern Mix_Chunk *LoadMusic(const std::string &name);
|
||||
extern Mix_Music *LoadMusic(const std::string &name);
|
||||
/// Load a sample
|
||||
extern Mix_Chunk *LoadSample(const std::string &name);
|
||||
/// Play a sample
|
||||
|
@ -85,8 +85,10 @@ extern void SetEffectsEnabled(bool enabled);
|
|||
/// Check if effects are enabled
|
||||
extern bool IsEffectsEnabled();
|
||||
|
||||
/// Set the music finished callback
|
||||
void SetMusicFinishedCallback(void (*callback)());
|
||||
/// Play a music file
|
||||
extern int PlayMusic(Mix_Chunk *sample);
|
||||
extern int PlayMusic(Mix_Music *sample);
|
||||
/// Play a music file
|
||||
extern int PlayMusic(const std::string &file);
|
||||
/// Stop music playing
|
||||
|
|
102
src/sound/music.cpp
Normal file
102
src/sound/music.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name music.cpp - Background music support */
|
||||
//
|
||||
// (c) Copyright 2002-2006 by Lutz Sammer, Nehal Mistry, and Jimmy Salmon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; only version 2 of the License.
|
||||
//
|
||||
// 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
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
|
||||
//@{
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include "stratagus.h"
|
||||
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
#include "sound_server.h"
|
||||
#include "script.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Declaration
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#define SoundFrequency 44100 // sample rate of dsp
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Variables
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
volatile bool MusicFinished; /// Music ended and we need a new file
|
||||
|
||||
bool CallbackMusic; /// flag true callback ccl if stops
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Callback for when music has finished
|
||||
** Note: we are in the sdl audio thread
|
||||
*/
|
||||
static void MusicFinishedCallback()
|
||||
{
|
||||
MusicFinished = true;
|
||||
}
|
||||
|
||||
/**
|
||||
** Check if music is finished and play the next song
|
||||
*/
|
||||
void CheckMusicFinished(bool force)
|
||||
{
|
||||
// this races, but that's just fine, since we'll just miss a frame of we're unlucky
|
||||
bool proceed = MusicFinished;
|
||||
if (!(((proceed || force) && SoundEnabled() && IsMusicEnabled() && CallbackMusic))) {
|
||||
return;
|
||||
}
|
||||
lua_getglobal(Lua, "MusicStopped");
|
||||
if (!lua_isfunction(Lua, -1)) {
|
||||
fprintf(stderr, "No MusicStopped function in Lua\n");
|
||||
} else {
|
||||
LuaCall(0, 1);
|
||||
}
|
||||
MusicFinished = false;
|
||||
}
|
||||
|
||||
/**
|
||||
** Init music
|
||||
*/
|
||||
void InitMusic()
|
||||
{
|
||||
MusicFinished = false;
|
||||
SetMusicFinishedCallback(MusicFinishedCallback);
|
||||
#ifdef USE_FLUIDSYNTH
|
||||
InitFluidSynth();
|
||||
#endif
|
||||
}
|
||||
|
||||
//@}
|
|
@ -39,10 +39,13 @@
|
|||
|
||||
#include "sound_server.h"
|
||||
|
||||
#ifdef USE_FLUIDSYNTH
|
||||
#include "fluidsynth.h"
|
||||
#endif
|
||||
|
||||
#include "iocompat.h"
|
||||
#include "iolib.h"
|
||||
#include "unit.h"
|
||||
#include "script.h"
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_mixer.h"
|
||||
|
@ -54,10 +57,10 @@
|
|||
static bool SoundInitialized; /// is sound initialized
|
||||
static bool MusicEnabled = true;
|
||||
static bool EffectsEnabled = true;
|
||||
static int EffectsVolume = 255;
|
||||
static int MusicVolume = 255;
|
||||
static double VolumeScale = 1.0;
|
||||
static int MusicVolume = 0;
|
||||
|
||||
volatile bool MusicFinished;
|
||||
extern volatile bool MusicFinished;
|
||||
|
||||
/// Channels for sound effects and unit speech
|
||||
struct SoundChannel {
|
||||
|
@ -103,10 +106,8 @@ static void ChannelFinished(int channel)
|
|||
if (Channels[channel].FinishedCallback) {
|
||||
Channels[channel].FinishedCallback(channel);
|
||||
}
|
||||
if (Channels[channel].Unit) {
|
||||
delete Channels[channel].Unit;
|
||||
Channels[channel].Unit = NULL;
|
||||
}
|
||||
delete Channels[channel].Unit;
|
||||
Channels[channel].Unit = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,7 +120,7 @@ static void ChannelFinished(int channel)
|
|||
*/
|
||||
int SetChannelVolume(int channel, int volume)
|
||||
{
|
||||
return Mix_Volume(channel, volume);
|
||||
return Mix_Volume(channel, volume * VolumeScale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,19 +191,26 @@ void StopAllChannels()
|
|||
Mix_HaltChannel(-1);
|
||||
}
|
||||
|
||||
static Mix_Chunk *currentMusic = NULL;
|
||||
static int currentMusicChannel = -1;
|
||||
static Mix_Music *currentMusic = NULL;
|
||||
|
||||
static Mix_Chunk *LoadMusic(const char *name)
|
||||
static Mix_Music *LoadMusic(const char *name)
|
||||
{
|
||||
if (currentMusicChannel >= 0) {
|
||||
Mix_HaltChannel(currentMusicChannel);
|
||||
}
|
||||
if (currentMusic) {
|
||||
Mix_FreeChunk(currentMusic);
|
||||
currentMusic = NULL;
|
||||
Mix_HaltMusic();
|
||||
Mix_FreeMusic(currentMusic);
|
||||
}
|
||||
currentMusic = LoadSample(name);
|
||||
currentMusic = Mix_LoadMUS(name);
|
||||
if (currentMusic) {
|
||||
return currentMusic;
|
||||
}
|
||||
|
||||
CFile *f = new CFile;
|
||||
if (f->open(name, CL_OPEN_READ) == -1) {
|
||||
printf("Can't open file '%s'\n", name);
|
||||
delete f;
|
||||
return NULL;
|
||||
}
|
||||
currentMusic = Mix_LoadMUS_RW(f->as_SDL_RWops(), 0);
|
||||
return currentMusic;
|
||||
}
|
||||
|
||||
|
@ -228,10 +236,10 @@ static Mix_Chunk *LoadSample(const char *name)
|
|||
**
|
||||
** @return Mix_Music pointer
|
||||
*/
|
||||
Mix_Chunk *LoadMusic(const std::string &name)
|
||||
Mix_Music *LoadMusic(const std::string &name)
|
||||
{
|
||||
const std::string filename = LibraryFileName(name.c_str());
|
||||
Mix_Chunk *music = LoadMusic(filename.c_str());
|
||||
Mix_Music *music = LoadMusic(filename.c_str());
|
||||
|
||||
if (music == NULL) {
|
||||
fprintf(stderr, "Can't load the music '%s'\n", name.c_str());
|
||||
|
@ -272,7 +280,6 @@ int PlaySample(Mix_Chunk *sample, Origin *origin)
|
|||
DebugPrint("play sample %d\n" _C_ sample->volume);
|
||||
if (SoundEnabled() && EffectsEnabled && sample) {
|
||||
channel = Mix_PlayChannel(-1, sample, 0);
|
||||
SetChannelVolume(channel, EffectsVolume);
|
||||
Channels[channel].FinishedCallback = NULL;
|
||||
if (origin && origin->Base) {
|
||||
Origin *source = new Origin;
|
||||
|
@ -291,7 +298,7 @@ int PlaySample(Mix_Chunk *sample, Origin *origin)
|
|||
*/
|
||||
void SetEffectsVolume(int volume)
|
||||
{
|
||||
EffectsVolume = volume;
|
||||
VolumeScale = (volume * 1.0) / 255.0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -299,7 +306,7 @@ void SetEffectsVolume(int volume)
|
|||
*/
|
||||
int GetEffectsVolume()
|
||||
{
|
||||
return EffectsVolume;
|
||||
return VolumeScale * 255;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -322,40 +329,12 @@ bool IsEffectsEnabled()
|
|||
-- Music
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
bool CallbackMusic; /// flag true callback ccl if stops
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
** Check if music is finished and play the next song
|
||||
** Set the music finished callback
|
||||
*/
|
||||
void CheckMusicFinished(bool force)
|
||||
void SetMusicFinishedCallback(void (*callback)())
|
||||
{
|
||||
// this races, but that's just fine, since we'll just miss a frame of we're unlucky
|
||||
bool proceed = MusicFinished;
|
||||
if (!(((proceed || force) && SoundEnabled() && IsMusicEnabled() && CallbackMusic))) {
|
||||
return;
|
||||
}
|
||||
lua_getglobal(Lua, "MusicStopped");
|
||||
if (!lua_isfunction(Lua, -1)) {
|
||||
fprintf(stderr, "No MusicStopped function in Lua\n");
|
||||
} else {
|
||||
LuaCall(0, 1);
|
||||
}
|
||||
MusicFinished = false;
|
||||
}
|
||||
|
||||
/**
|
||||
** Callback for when music has finished
|
||||
** Note: we are in the sdl audio thread
|
||||
*/
|
||||
static void MusicFinishedCallback(int channel)
|
||||
{
|
||||
currentMusicChannel = -1;
|
||||
MusicFinished = true;
|
||||
Mix_HookMusicFinished(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -365,13 +344,13 @@ static void MusicFinishedCallback(int channel)
|
|||
**
|
||||
** @return 0 if music is playing, -1 if not.
|
||||
*/
|
||||
int PlayMusic(Mix_Chunk *sample)
|
||||
int PlayMusic(Mix_Music *sample)
|
||||
{
|
||||
if (sample) {
|
||||
Mix_VolumeMusic(MusicVolume);
|
||||
MusicFinished = false;
|
||||
Mix_VolumeChunk(sample, MusicVolume);
|
||||
int channel = Mix_FadeInChannel(-1, sample, 0, 500);
|
||||
Channels[channel].FinishedCallback = MusicFinishedCallback;
|
||||
Mix_PlayMusic(sample, 0);
|
||||
Mix_VolumeMusic(MusicVolume / 4.0);
|
||||
return 0;
|
||||
} else {
|
||||
DebugPrint("Could not play sample\n");
|
||||
|
@ -392,8 +371,16 @@ int PlayMusic(const std::string &file)
|
|||
return -1;
|
||||
}
|
||||
DebugPrint("play music %s\n" _C_ file.c_str());
|
||||
Mix_Chunk *music = LoadMusic(file);
|
||||
return PlayMusic(music);
|
||||
Mix_Music *music = LoadMusic(file);
|
||||
|
||||
if (music) {
|
||||
MusicFinished = false;
|
||||
Mix_FadeInMusic(music, 0, 200);
|
||||
return 0;
|
||||
} else {
|
||||
DebugPrint("Could not play %s\n" _C_ file.c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -401,9 +388,7 @@ int PlayMusic(const std::string &file)
|
|||
*/
|
||||
void StopMusic()
|
||||
{
|
||||
if (currentMusicChannel) {
|
||||
Mix_FadeOutChannel(currentMusicChannel, 500);
|
||||
}
|
||||
Mix_FadeOutMusic(200);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -413,10 +398,10 @@ void StopMusic()
|
|||
*/
|
||||
void SetMusicVolume(int volume)
|
||||
{
|
||||
// due to left-right separation, sound effect volume is effectively halfed,
|
||||
// so we adjust the music
|
||||
MusicVolume = volume;
|
||||
if (currentMusicChannel) {
|
||||
Mix_Volume(currentMusicChannel, volume);
|
||||
}
|
||||
Mix_VolumeMusic(volume / 4.0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -453,7 +438,7 @@ bool IsMusicEnabled()
|
|||
*/
|
||||
bool IsMusicPlaying()
|
||||
{
|
||||
return !MusicFinished;
|
||||
return Mix_PlayingMusic();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
@ -511,12 +496,12 @@ int InitSound()
|
|||
SoundInitialized = false;
|
||||
return 1;
|
||||
}
|
||||
MusicFinished = false;
|
||||
SoundInitialized = true;
|
||||
Mix_AllocateChannels(MaxChannels);
|
||||
Mix_ChannelFinished(ChannelFinished);
|
||||
|
||||
// Now we're ready for the callback to run
|
||||
Mix_ResumeMusic();
|
||||
Mix_Resume(-1);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -720,7 +720,9 @@ int stratagusMain(int argc, char **argv)
|
|||
|
||||
// Setup sound card, must be done before loading sounds, so that
|
||||
// SDL_mixer can auto-convert to the target format
|
||||
InitSound();
|
||||
if (!InitSound()) {
|
||||
InitMusic();
|
||||
}
|
||||
|
||||
LoadCcl(parameters.luaStartFilename, parameters.luaScriptArguments);
|
||||
|
||||
|
|
|
@ -361,7 +361,7 @@ int PlayMovie(const std::string &name)
|
|||
}
|
||||
|
||||
StopMusic();
|
||||
Mix_Chunk *sample = LoadMusic(filename);
|
||||
Mix_Music *sample = LoadMusic(filename);
|
||||
if (sample) {
|
||||
PlayMusic(sample);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue