X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FATCDCL%2FATC.cxx;h=41c56e64844998beb1db3d754b6fdedbc169d315;hb=0d9f2e3c9585cfc1fbc392e56c35fda8bef8c334;hp=2bc321805619481bed8f0698fdeb42cdfd700693;hpb=aacebaf4b8f101dbad17f20e5136f50cd6991a6f;p=flightgear.git diff --git a/src/ATCDCL/ATC.cxx b/src/ATCDCL/ATC.cxx index 2bc321805..41c56e648 100644 --- a/src/ATCDCL/ATC.cxx +++ b/src/ATCDCL/ATC.cxx @@ -22,43 +22,55 @@ # include #endif +#include "ATC.hxx" + +#include + #include #include #include
#include
-#include "ATC.hxx" -FGATC::FGATC() { - freqClear = true; - receiving = false; - respond = false; - runResponseCounter = false; - _runReleaseCounter = false; - responseID = ""; - responseReqd = false; - _type = INVALID; - _display = false; - _displaying = false; - + +FGATC::FGATC() : + _voiceOK(false), + _playing(false), + _sgr(NULL), + freqClear(true), + receiving(false), + respond(false), + responseID(""), + runResponseCounter(false), + _runReleaseCounter(false), + responseReqd(false), + _type(INVALID), + _display(false), // Transmission timing stuff - pending_transmission = ""; - _timeout = 0; - _pending = false; - _callback_code = 0; - _transmit = false; - _transmitting = false; - _counter = 0.0; - _max_count = 5.0; - - _voiceOK = false; + pending_transmission(""), + _timeout(0), + _pending(false), + _callback_code(0), + _transmit(false), + _transmitting(false), + _counter(0.0), + _max_count(5.0) +{ + SGSoundMgr *smgr = globals->get_soundmgr(); + _sgr = smgr->find("atc", true); + + _volume = fgGetNode("/sim/sound/atc/volume", true); + _enabled = fgGetNode("/sim/sound/atc/enabled", true); + _atc_external = fgGetNode("/sim/sound/atc/external-view", true); + _internal = fgGetNode("/sim/current-view/internal", true); } FGATC::~FGATC() { } -// Derived classes wishing to use the response counter should call this from their own Update(...). +// Derived classes wishing to use the response counter should +// call this from their own Update(...). void FGATC::Update(double dt) { if(runResponseCounter) { //cout << responseCounter << '\t' << responseTime << '\n'; @@ -100,6 +112,18 @@ void FGATC::Update(double dt) { } } +#ifdef ENABLE_AUDIO_SUPPORT + bool active = _atc_external->getBoolValue() || + _internal->getBoolValue(); + + if ( active && _enabled->getBoolValue() ) { + _sgr->set_volume( _volume->getFloatValue() ); + _sgr->resume(); // no-op if already in resumed state + } else { + _sgr->suspend(); + } +#endif + if(_transmit) { _counter = 0.0; _max_count = 5.0; // FIXME - hardwired length of message - need to calculate it! @@ -200,12 +224,9 @@ int FGATC::RemovePlane() { } void FGATC::SetData(ATCData* d) { - lon = d->lon; - lat = d->lat; - elev = d->elev; - x = d->x; - y = d->y; - z = d->z; + _type = d->type; + _geod = d->geod; + _cart = d->cart; range = d->range; ident = d->ident; name = d->name; @@ -216,37 +237,36 @@ void FGATC::SetData(ATCData* d) { // Outputs the transmission either on screen or as audio depending on user preference // The refname is a string to identify this sample to the sound manager // The repeating flag indicates whether the message should be repeated continuously or played once. -void FGATC::Render(string& msg, const string& refname, bool repeating) { +void FGATC::Render(string& msg, const float volume, + const string& refname, const bool repeating) { + if (volume < 0.05) return; + if (repeating) fgSetString("/sim/messages/atis", msg.c_str()); else fgSetString("/sim/messages/atc", msg.c_str()); - #ifdef ENABLE_AUDIO_SUPPORT +#ifdef ENABLE_AUDIO_SUPPORT _voice = (_voiceOK && fgGetBool("/sim/sound/voice")); if(_voice) { - int len; - unsigned char* buf = _vPtr->WriteMessage((char*)msg.c_str(), len, _voice); - if(_voice) { + size_t len; + void* buf = _vPtr->WriteMessage((char*)msg.c_str(), &len); + if(buf) { + NoRender(refname); try { - SGSoundSample *simple - = new SGSoundSample(buf, len, 8000); - // TODO - at the moment the volume is always set off comm1 - // and can't be changed after the transmission has started. - simple->set_volume(5.0 * fgGetDouble("/instrumentation/comm[0]/volume")); - globals->get_soundmgr()->add(simple, refname); - if(repeating) { - globals->get_soundmgr()->play_looped(refname); - } else { - globals->get_soundmgr()->play_once(refname); - } +// >>> Beware: must pass a (new) object to the (add) method, +// >>> because the (remove) method is going to do a (delete) +// >>> whether that's what you want or not. + SGSoundSample *simple = new SGSoundSample(&buf, len, 8000); + simple->set_volume(volume); + _sgr->add(simple, refname); + _sgr->play(refname, repeating); } catch ( sg_io_exception &e ) { SG_LOG(SG_GENERAL, SG_ALERT, e.getFormattedMessage()); } } - delete[] buf; } - #endif // ENABLE_AUDIO_SUPPORT +#endif // ENABLE_AUDIO_SUPPORT if(!_voice) { // first rip the underscores and the pause hints out of the string - these are for the convienience of the voice parser for(unsigned int i = 0; i < msg.length(); ++i) { @@ -264,8 +284,8 @@ void FGATC::NoRender(const string& refname) { if(_playing) { if(_voice) { #ifdef ENABLE_AUDIO_SUPPORT - globals->get_soundmgr()->stop(refname); - globals->get_soundmgr()->remove(refname); + _sgr->stop(refname); + _sgr->remove(refname); #endif } _playing = false; @@ -279,13 +299,73 @@ string FGATC::GenText(const string& m, int c) { ostream& operator << (ostream& os, atc_type atc) { switch(atc) { - case(INVALID): return(os << "INVALID"); - case(ATIS): return(os << "ATIS"); - case(GROUND): return(os << "GROUND"); - case(TOWER): return(os << "TOWER"); + case(AWOS): return(os << "AWOS"); + case(ATIS): return(os << "ATIS"); + case(GROUND): return(os << "GROUND"); + case(TOWER): return(os << "TOWER"); case(APPROACH): return(os << "APPROACH"); case(DEPARTURE): return(os << "DEPARTURE"); - case(ENROUTE): return(os << "ENROUTE"); + case(ENROUTE): return(os << "ENROUTE"); + case(INVALID): return(os << "INVALID"); } return(os << "ERROR - Unknown switch in atc_type operator << "); } + +std::istream& operator >> ( std::istream& fin, ATCData& a ) +{ + double f; + char ch; + char tp; + + fin >> tp; + + switch(tp) { + case 'I': + a.type = ATIS; + break; + case 'T': + a.type = TOWER; + break; + case 'G': + a.type = GROUND; + break; + case 'A': + a.type = APPROACH; + break; + case '[': + a.type = INVALID; + return fin >> skipeol; + default: + SG_LOG(SG_GENERAL, SG_ALERT, "Warning - unknown type \'" << tp << "\' found whilst reading ATC frequency data!\n"); + a.type = INVALID; + return fin >> skipeol; + } + + double lat, lon, elev; + + fin >> lat >> lon >> elev >> f >> a.range >> a.ident; + a.geod = SGGeod::fromDegM(lon, lat, elev); + a.name = ""; + fin >> ch; + if(ch != '"') a.name += ch; + while(1) { + //in >> noskipws + fin.unsetf(std::ios::skipws); + fin >> ch; + if((ch == '"') || (ch == 0x0A)) { + break; + } // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the " + a.name += ch; + } + fin.setf(std::ios::skipws); + //cout << "Comm name = " << a.name << '\n'; + + a.freq = (int)(f*100.0 + 0.5); + + // cout << a.ident << endl; + + // generate cartesian coordinates + a.cart = SGVec3d::fromGeod(a.geod); + return fin >> skipeol; +} +