// sound.cpp // #include #include "sound.h" #include "event.h" #include "misc.h" #include "def.h" #include "resource.h" // Stops all sounds. bool CSound::StopAllSounds() { for (int i = 0; i < MAXSOUND; i ++) { if (!m_lpSDL[i]) continue; if (Mix_Playing (i + 1) == SDL_TRUE) Mix_FadeOutChannel (i + 1, 500); } return true; } CSound::CSound() { int i; m_bEnable = false; m_bState = false; m_MIDIFilename[0] = 0; m_audioVolume = 20; m_midiVolume = 15; m_lastMidiVolume = 0; m_nbSuspendSkip = 0; m_pMusic = nullptr; m_bStopped = false; for ( i=0 ; i= MAXSOUND ) return false; if (m_lpSDL[channel]) Flush(channel); m_lpSDL[channel] = Mix_LoadWAV (pFilename); if (!m_lpSDL[channel]) { SDL_Log ("Mix_LoadWAV: %s\n", Mix_GetError ()); return false; } return true; } // D�charge un son. void CSound::Flush(int channel) { if ( !m_bEnable ) return; if ( channel < 0 || channel >= MAXSOUND ) return; if (m_lpSDL[channel]) { Mix_FreeChunk (m_lpSDL[channel]); m_lpSDL[channel] = nullptr; } } // Fait entendre un son. // Le volume est compris entre 128 (max) et 0 (silence). // Le panoramique est compris entre 255,0 (gauche), 127,128 (centre) // et 0,255 (droite). bool CSound::Play(int channel, int volume, Uint8 panLeft, Uint8 panRight) { if (!m_bEnable) return true; if (!m_bState || !m_audioVolume) return true; if (channel < 0 || channel >= MAXSOUND) return false; Mix_SetPanning (channel + 1, panLeft, panRight); volume = volume * 100 * m_audioVolume / 20 / 100; Mix_Volume (channel + 1, volume); if (Mix_Playing (channel + 1) == SDL_FALSE) Mix_PlayChannel (channel + 1, m_lpSDL[channel], 0); return true; } // Fait entendre un son dans une image. // Si rank != -1, il indique le rang du blupi dont il faudra // �ventuellement stopper le dernier son en cours ! bool CSound::PlayImage(int channel, POINT pos, int rank) { int stopCh, volumex, volumey, volume; if ( rank >= 0 && rank < MAXBLUPI ) { stopCh = m_channelBlupi[rank]; if ( stopCh >= 0 && m_lpSDL[stopCh] != nullptr ) Mix_FadeOutChannel (stopCh + 1, 500); m_channelBlupi[rank] = channel; } Uint8 panRight, panLeft; volumex = MIX_MAX_VOLUME; volumey = MIX_MAX_VOLUME; if (pos.x < 0) { panRight = 0; panLeft = 255; volumex += pos.x; if (volumex < 0) volumex = 0; } else if (pos.x > LXIMAGE) { panRight = 255; panLeft = 0; volumex -= pos.x - LXIMAGE; if (volumex < 0) volumex = 0; } else { panRight = 255 * static_cast (pos.x) / LXIMAGE; panLeft = 255 - panRight; } if (pos.y < 0) { volumey += pos.y; if (volumey < 0) volumey = 0; } else if (pos.y > LYIMAGE) { volumey -= pos.y - LYIMAGE; if (volumey < 0) volumey = 0; } volume = volumex < volumey ? volumex : volumey; return Play(channel, volume, panLeft, panRight); } // Uses MCI to play a MIDI file. The window procedure // is notified when playback is complete. bool CSound::PlayMusic(const char *lpszMIDIFilename) { std::string path = GetBaseDir (); if ( !m_bEnable ) return true; if ( m_midiVolume == 0 ) return true; Mix_VolumeMusic (MIX_MAX_VOLUME * 100 * m_midiVolume / 20 / 100); m_lastMidiVolume = m_midiVolume; path += lpszMIDIFilename; m_pMusic = Mix_LoadMUS (path.c_str ()); if (!m_pMusic) { printf ("%s\n", Mix_GetError ()); return false; } if (Mix_PlayMusic (m_pMusic, 0) == -1) { printf ("%s\n", Mix_GetError ()); return false; } m_bStopped = false; strcpy(m_MIDIFilename, lpszMIDIFilename); return true; } // Restart the MIDI player. bool CSound::RestartMusic() { OutputDebug("RestartMusic\n"); if ( !m_bEnable ) return true; if ( m_midiVolume == 0 ) return true; if ( m_MIDIFilename[0] == 0 ) return false; return PlayMusic(m_MIDIFilename); } // Shuts down the MIDI player. void CSound::SuspendMusic() { if ( !m_bEnable ) return; if ( m_nbSuspendSkip != 0 ) { m_nbSuspendSkip --; return; } m_bStopped = true; Mix_HaltMusic (); } // Shuts down the MIDI player. void CSound::StopMusic() { SuspendMusic(); m_MIDIFilename[0] = 0; } // Retourne true si une musique est en cours. bool CSound::IsPlayingMusic() { return (m_MIDIFilename[0] != 0); } bool CSound::IsStoppedOnDemand () { return m_bStopped; } // Adapte le volume de la musique en cours, si n�cessaire. void CSound::AdaptVolumeMusic() { if (m_midiVolume != m_lastMidiVolume) { Mix_VolumeMusic (MIX_MAX_VOLUME * 100 * m_midiVolume / 20 / 100); m_lastMidiVolume = m_midiVolume; } } // Indique le nombre de suspend � sauter. void CSound::SetSuspendSkip(int nb) { m_nbSuspendSkip = nb; }