mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 19:55:23 +00:00
329 lines
7.8 KiB
C++
329 lines
7.8 KiB
C++
/*
|
|
* Descent 3
|
|
* Copyright (C) 2024 Parallax Software
|
|
*
|
|
* 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, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
--- HISTORICAL COMMENTS FOLLOW ---
|
|
|
|
* $Logfile: /DescentIII/Main/music/streamer.cpp $
|
|
* $Revision: 10 $
|
|
* $Date: 4/01/99 4:50p $
|
|
* $Author: Matt $
|
|
*
|
|
* Stream interface with sequencer.
|
|
*
|
|
* $Log: /DescentIII/Main/music/streamer.cpp $
|
|
*
|
|
* 10 4/01/99 4:50p Matt
|
|
* Took out Warning() function, chaning those calls to mprintf()
|
|
*
|
|
* 9 2/26/99 5:26p Samir
|
|
* fixes to streaming audio to reflect fix in direct sound mixer.
|
|
*
|
|
* 8 12/10/98 10:12a Samir
|
|
* uses newer streaming audio library
|
|
*
|
|
* 7 12/07/98 11:45a Samir
|
|
* hacks to get music system mostly working in DS_8. Will change this
|
|
* system so it's a lot cleaner after music demo.
|
|
*
|
|
* 6 12/03/98 12:48p Samir
|
|
* speed up sequencer so that gap between samples isn't too big.
|
|
*
|
|
* 5 11/20/98 5:21p Samir
|
|
* added SEND_STRM_NEXT
|
|
*
|
|
* 4 11/13/98 2:27p Samir
|
|
* new music system.
|
|
*
|
|
* 3 8/10/98 5:53p Samir
|
|
* improved switching between streams and basic background/combat music.
|
|
*
|
|
* 2 7/28/98 5:43p Samir
|
|
* reorg of music system.
|
|
*
|
|
* 1 7/28/98 12:47p Samir
|
|
* moved and revamped from sequencer.cpp
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
#include "music.h"
|
|
#include "streamaudio.h"
|
|
|
|
oms_stream::oms_stream() {}
|
|
|
|
oms_stream::~oms_stream() {}
|
|
|
|
// processes a stream's events.
|
|
void oms_stream::Process(float frmtime) {
|
|
oms_q_evt evt, evt2 = {}; // event for use
|
|
|
|
if (m_timer > 0.0f)
|
|
m_timer -= frmtime;
|
|
|
|
// invalidate current process result.
|
|
m_valid_result = false;
|
|
|
|
if (!processCommand())
|
|
return;
|
|
|
|
// process queue events.
|
|
if (!m_q.recv(&evt))
|
|
return;
|
|
|
|
switch (evt.cmd) {
|
|
case OMS_STRM_LOAD:
|
|
processQLoad((const char *)evt.parm.p);
|
|
break;
|
|
|
|
case OMS_STRM_FADEOUT:
|
|
// reset timer for fadeout to 0 volume
|
|
STREAM_COMMANDI(OMS_STRM_FADEOUT);
|
|
STREAM_TIMER(evt.parm.f);
|
|
break;
|
|
|
|
case OMS_STRM_FADEIN:
|
|
// fade in to volume m_maxvol
|
|
STREAM_COMMANDI(OMS_STRM_FADEIN);
|
|
STREAM_TIMER(evt.parm.f);
|
|
break;
|
|
|
|
case OMS_STRM_STOP:
|
|
STREAM_COMMANDI(OMS_STRM_STOP);
|
|
m_stream.Stop();
|
|
break;
|
|
|
|
case OMS_STRM_FREE:
|
|
STREAM_COMMANDI(OMS_STRM_FREE);
|
|
m_stream.Close();
|
|
break;
|
|
|
|
case OMS_STRM_PLAY:
|
|
// process queue events.
|
|
if (!m_q.recv(&evt2)) {
|
|
Int3();
|
|
}
|
|
STREAM_COMMANDI(OMS_STRM_PLAY, evt2.parm.i);
|
|
m_stream.SetLoopCount(evt2.parm.i);
|
|
m_stream.SetVolume(evt.parm.f);
|
|
m_stream.Play();
|
|
break;
|
|
|
|
case OMS_STRM_SWITCH:
|
|
STREAM_COMMANDP(OMS_STRM_SWITCH, evt.parm.p);
|
|
m_stream.Stop(true, &m_data.i);
|
|
mprintf(0, "%d-%d ", m_data.i, m_stream.State());
|
|
break;
|
|
|
|
case OMS_STRM_NEXT:
|
|
// m_stream.Next((const char *)evt.parm.p);
|
|
if (!m_q.recv(&evt2)) {
|
|
Int3();
|
|
}
|
|
m_data.f = evt2.parm.f;
|
|
if (!m_q.recv(&evt2)) {
|
|
Int3();
|
|
}
|
|
m_data2.i = evt2.parm.i;
|
|
if (!m_q.recv(&evt2)) {
|
|
Int3();
|
|
}
|
|
STREAM_COMMANDP(OMS_STRM_NEXT, evt2.parm.p);
|
|
*(bool *)(evt2.parm.p) = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// sends an event to the stream.
|
|
void oms_stream::Send(oms_q_evt *evt) { m_q.send(*evt); }
|
|
|
|
// reset stream.
|
|
void oms_stream::Reset(OutrageMusicSeq *seq) {
|
|
m_timer = 0.0f;
|
|
m_timer_init = 0.0f;
|
|
m_maxvol = 1.0f;
|
|
m_status.cmd = OMS_STRM_FREE;
|
|
m_seq = seq;
|
|
m_q.flush();
|
|
m_stream.Close();
|
|
}
|
|
|
|
// volume.
|
|
void oms_stream::SetVolume(float vol) {
|
|
m_maxvol = vol;
|
|
m_stream.SetVolume(vol);
|
|
}
|
|
|
|
// processes current command on stream, return false to end processing.
|
|
bool oms_stream::processCommand() {
|
|
switch (m_status.cmd) {
|
|
case OMS_STRM_FADEIN:
|
|
// timed fadein to dest volume
|
|
if (m_timer <= 0.0f) {
|
|
m_stream.SetVolume(m_maxvol);
|
|
STREAM_COMMANDI(OMS_STRM_PLAY);
|
|
} else {
|
|
m_stream.SetVolume(m_maxvol * (m_timer_init - m_timer) / m_timer_init);
|
|
}
|
|
return false;
|
|
|
|
case OMS_STRM_FADEOUT:
|
|
// timed fadeout to dest volume
|
|
if (m_timer <= 0.0f) {
|
|
m_stream.SetVolume(0.0f);
|
|
STREAM_COMMANDI(OMS_STRM_PLAY);
|
|
} else {
|
|
m_stream.SetVolume(m_maxvol * m_timer / m_timer_init);
|
|
}
|
|
return false;
|
|
|
|
case OMS_STRM_SWITCH:
|
|
// if current measure is greater than initial measure at switch, then we will stop
|
|
// this stream and send a play command to the current dominant stream.
|
|
// mprintf(0, "%d-%d ",m_data.i, m_stream.State());
|
|
if (m_data.i || m_stream.State() == STRM_STOPPED || m_stream.State() == STRM_INVALID) {
|
|
bool *still_playing = (bool *)m_status.parm.p;
|
|
*still_playing = false;
|
|
if (m_status.cmd != OMS_STRM_STOP) {
|
|
STREAM_COMMANDI(OMS_STRM_STOP);
|
|
m_valid_result = true;
|
|
m_result.cmd = OMS_STRM_STOP;
|
|
}
|
|
}
|
|
return false;
|
|
|
|
case OMS_STRM_PLAY:
|
|
// check if stream is still playing. if not, then set current stream status and signal
|
|
// a normal song end.
|
|
if (m_stream.State() == STRM_STOPPED) {
|
|
if (m_status.cmd != OMS_STRM_STOP) {
|
|
STREAM_COMMANDI(OMS_STRM_STOP);
|
|
m_valid_result = true;
|
|
m_result.cmd = OMS_STRM_STOP;
|
|
return false;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case OMS_STRM_NEXT:
|
|
// if (m_stream.HasNextStarted()) {
|
|
// *(bool *)(m_status.parm.p) = false;
|
|
// m_stream.SetLoopCount(m_data2.i);
|
|
// m_stream.SetVolume(m_data.f);
|
|
// STREAM_COMMANDI(OMS_STRM_PLAY, m_data2.i);
|
|
// return false;
|
|
// }
|
|
// else {
|
|
// *(bool *)(m_status.parm.p) = true;
|
|
// }
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// processes load song q event.
|
|
void oms_stream::processQLoad(const char *fname) {
|
|
m_stream.Close();
|
|
|
|
if (m_stream.Open(fname)) {
|
|
STREAM_COMMANDP(OMS_STRM_LOAD, (void *)fname);
|
|
m_data.p = (void *)fname;
|
|
} else {
|
|
mprintf(0, "OMS: Couldn't load song %s.\n", fname);
|
|
|
|
STREAM_COMMANDI(OMS_STRM_FREE);
|
|
m_valid_result = true;
|
|
m_result.cmd = OMS_EVT_SONGENDED;
|
|
m_result.parm.p = (void *)fname;
|
|
}
|
|
}
|
|
|
|
// THESE FUNCTIONS SEND EVENTS TO THE STREAM EASILY
|
|
|
|
void oms_stream::SEND_STRM_LOAD(const char *fname) {
|
|
oms_q_evt evt;
|
|
|
|
evt.cmd = OMS_STRM_LOAD;
|
|
evt.parm.p = (void *)fname;
|
|
m_q.send(evt);
|
|
}
|
|
|
|
void oms_stream::SEND_STRM_FADEOUT(float time) {
|
|
oms_q_evt evt;
|
|
|
|
evt.cmd = OMS_STRM_FADEOUT;
|
|
evt.parm.f = time;
|
|
m_q.send(evt);
|
|
}
|
|
|
|
void oms_stream::SEND_STRM_FADEIN(float time) {
|
|
oms_q_evt evt;
|
|
|
|
evt.cmd = OMS_STRM_FADEIN;
|
|
evt.parm.f = time;
|
|
m_q.send(evt);
|
|
}
|
|
|
|
void oms_stream::SEND_STRM_STOP() {
|
|
oms_q_evt evt;
|
|
|
|
evt.cmd = OMS_STRM_STOP;
|
|
m_q.send(evt);
|
|
}
|
|
|
|
void oms_stream::SEND_STRM_PLAY(float vol, uint8_t count) {
|
|
oms_q_evt evt;
|
|
|
|
evt.cmd = OMS_STRM_PLAY;
|
|
evt.parm.f = vol;
|
|
m_q.send(evt);
|
|
evt.cmd = OMS_STRM_PARM;
|
|
evt.parm.i = (int)count;
|
|
m_q.send(evt);
|
|
}
|
|
|
|
void oms_stream::SEND_STRM_FREE() {
|
|
oms_q_evt evt;
|
|
|
|
evt.cmd = OMS_STRM_FREE;
|
|
m_q.send(evt);
|
|
}
|
|
|
|
void oms_stream::SEND_STRM_SWITCH(bool *switch_flag) {
|
|
oms_q_evt evt;
|
|
evt.cmd = OMS_STRM_SWITCH;
|
|
evt.parm.p = (void *)switch_flag;
|
|
m_q.send(evt);
|
|
}
|
|
|
|
void oms_stream::SEND_STRM_NEXT(const char *fname, float vol, uint8_t count, bool *switch_flag) {
|
|
oms_q_evt evt;
|
|
|
|
evt.cmd = OMS_STRM_NEXT;
|
|
evt.parm.p = (void *)fname;
|
|
m_q.send(evt);
|
|
evt.cmd = OMS_STRM_PARM;
|
|
evt.parm.f = vol;
|
|
m_q.send(evt);
|
|
evt.cmd = OMS_STRM_PARM;
|
|
evt.parm.i = (int)count;
|
|
m_q.send(evt);
|
|
evt.cmd = OMS_STRM_PARM;
|
|
evt.parm.p = (void *)switch_flag;
|
|
m_q.send(evt);
|
|
}
|