#include <Main/fg_props.hxx>
#include <simgear/math/point3d.hxx>
#include <simgear/debug/logstream.hxx>
-#include <simgear/sound/soundmgr.hxx>
+#include <simgear/sound/soundmgr_openal.hxx>
#include <math.h>
#include <string>
SG_USING_STD(string);
pending_transmission = "";
_timeout = 0;
_pending = false;
- _callback = NULL;
+ _callback_code = 0;
_transmit = false;
_transmitting = false;
voice = false;
playing = false;
voiceOK = false;
vPtr = NULL;
+ track = 0.0;
+ _tgtTrack = 0.0;
+ _trackSet = false;
+ _tgtRoll = 0.0;
+ _rollSuspended = false;
}
FGAIPlane::~FGAIPlane() {
if(_pending) {
if(tuned_station) {
if(tuned_station->GetFreqClear()) {
+ //cout << "TUNED STATION FREQ CLEAR\n";
+ tuned_station->SetFreqInUse();
_pending = false;
_transmit = true;
_transmitting = false;
_timeout = 0.0;
_pending = false;
// timed out - don't render.
+ if(_callback_code == 99) {
+ // MEGA-HACK - 99 is the remove self callback - currently this *does* need to be run even if the transmission isn't made.
+ ProcessCallback(_callback_code);
+ }
}
}
}
} else {
// Not tuned to ATC - Just go ahead and transmit
+ //cout << "NOT TUNED TO ATC\n";
_pending = false;
_transmit = true;
_transmitting = false;
// This turns on rendering if on the same freq as the user
// TODO - turn it off if user switches to another freq - keep track of where in message we are etc.
if(_transmit) {
+ //cout << "transmit\n";
double user_freq0 = fgGetDouble("/radios/comm[0]/frequencies/selected-mhz");
double user_freq1 = fgGetDouble("/radios/comm[1]/frequencies/selected-mhz");
_counter = 0.0;
_max_count = 5.0; // FIXME - hardwired length of message - need to calculate it!
- if(freq == user_freq0 || freq == user_freq1) {
+ //cout << "Transmission = " << pending_transmission << '\n';
+
+ // The radios dialog seems to set slightly imprecise freqs, eg 118.099998
+ // The eplison stuff below is a work-around
+ double eps0 = fabs(freq - user_freq0);
+ double eps1 = fabs(freq - user_freq1);
+ if(eps0 < 0.002 || eps1 < 0.002) {
//cout << "Transmitting..." << endl;
// we are on the same frequency, so check distance to the user plane
if(1) {
// For now assume in range !!!
// TODO - implement range checking
Render(plane.callsign, false);
- _transmit = false;
- _transmitting = true;
}
}
+ // Run the callback regardless of whether on same freq as user or not.
+ if(_callback_code) {
+ ProcessCallback(_callback_code);
+ }
+ _transmit = false;
+ _transmitting = true;
} else if(_transmitting) {
if(_counter >= _max_count) {
NoRender(plane.callsign);
_transmitting = false;
+ // For now we'll let ATC decide whether to respond
+ //if(tuned_station) tuned_station->SetResponseReqd(plane.callsign);
+ //if(tuned_station->get_ident() == "KRHV") cout << "Notifying transmission finished" << endl;
+ if(tuned_station) tuned_station->NotifyTransmissionFinished(plane.callsign);
}
_counter += dt;
}
-}
-
-void FGAIPlane::Bank(double angle) {
- // This *should* bank us smoothly to any angle
- if(fabs(roll - angle) > 0.6) {
- roll -= ((roll - angle)/fabs(roll - angle));
+
+ // Fly the plane if necessary
+ if(_trackSet) {
+ while((_tgtTrack - track) > 180.0) track += 360.0;
+ while((track - _tgtTrack) > 180.0) track -= 360.0;
+ double turn_time = 60.0;
+ track += (360.0 / turn_time) * dt * (_tgtTrack > track ? 1.0 : -1.0);
+ // TODO - bank a bit less for small turns.
+ Bank(25.0 * (_tgtTrack > track ? 1.0 : -1.0));
+ if(fabs(track - _tgtTrack) < 2.0) { // TODO - might need to optimise the delta there - it's on the large (safe) side atm.
+ track = _tgtTrack;
+ LevelWings();
+ }
}
-}
-
-// Duplication of Bank(0.0) really - should I cut this?
-void FGAIPlane::LevelWings(void) {
- // bring the plane back to level smoothly (this should work to come out of either bank)
- if(fabs(roll) > 0.6) {
- roll -= (roll/fabs(roll));
+
+ if(!_rollSuspended) {
+ if(fabs(_roll - _tgtRoll) > 0.6) {
+ // This *should* bank us smoothly to any angle
+ _roll -= ((_roll - _tgtRoll)/fabs(_roll - _tgtRoll));
+ } else {
+ _roll = _tgtRoll;
+ }
}
}
-void FGAIPlane::Transmit(ai_plane_callback_t callback) {
+void FGAIPlane::Transmit(int callback_code) {
SG_LOG(SG_ATC, SG_INFO, "Transmit called for plane " << plane.callsign << ", msg = " << pending_transmission);
_pending = true;
- _callback = callback;
+ _callback_code = callback_code;
_timeout = 0.0;
}
-void FGAIPlane::Transmit(double timeout, ai_plane_callback_t callback) {
+void FGAIPlane::ConditionalTransmit(double timeout, int callback_code) {
SG_LOG(SG_ATC, SG_INFO, "Timed transmit called for plane " << plane.callsign << ", msg = " << pending_transmission);
_pending = true;
- _callback = callback;
+ _callback_code = callback_code;
_timeout = timeout;
}
-void FGAIPlane::ImmediateTransmit(ai_plane_callback_t callback) {
+void FGAIPlane::ImmediateTransmit(int callback_code) {
Render(plane.callsign, false);
- if(_callback) {
- (*_callback)();
+ if(callback_code) {
+ ProcessCallback(callback_code);
}
}
+// Derived classes should override this.
+void FGAIPlane::ProcessCallback(int code) {
+}
+
// Render a transmission
// 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 FGAIPlane::Render(string refname, bool repeating) {
#ifdef ENABLE_AUDIO_SUPPORT
- voice = (voiceOK && fgGetBool("/sim/sound/audible")
- && fgGetBool("/sim/sound/voice"));
+ voice = (voiceOK && fgGetBool("/sim/sound/voice"));
if(voice) {
int len;
unsigned char* buf = vPtr->WriteMessage((char*)pending_transmission.c_str(), len, voice);
if(voice) {
- SGSimpleSound* simple = new SGSimpleSound(buf, len);
+ SGSoundSample* simple = new SGSoundSample(buf, len, 8000, false);
// 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("/radios/comm[0]/volume"));