1 // ATCdisplay.cxx - routines to display ATC output - graphically for now
3 // Written by David Luff, started October 2001.
5 // Copyright (C) 2001 David C Luff - david.luff@nottingham.ac.uk
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29 #include <simgear/compiler.h>
33 #include <simgear/props/props.hxx>
35 #include <Include/general.hxx>
36 #include <Main/fg_props.hxx>
39 #include "ATCdisplay.hxx"
43 FGATCDisplay::FGATCDisplay() {
45 change_msg_flag = false;
52 FGATCDisplay::~FGATCDisplay() {
55 void FGATCDisplay::init() {
58 void FGATCDisplay::bind() {
61 void FGATCDisplay::unbind() {
64 void FGATCDisplay::update(double dt)
66 std::cout << "OSGFIXME" << std::endl;
69 // update - this actually draws the visuals and should be called from the main Flightgear rendering loop.
70 void FGATCDisplay::update(double dt, osg::State& state) {
72 // These strings are used for temporary storage of the transmission string in order
73 // that the string we view only changes when the next repetition starts scrolling
74 // even though the master string (rep_msg_str) may change at any time.
75 static string msg1 = "";
76 static string msg2 = "";
78 if( rep_msg || msgList.size() ) {
79 //cout << "In FGATC::update()" << endl;
80 SGPropertyNode *xsize_node = fgGetNode("/sim/startup/xsize");
81 SGPropertyNode *ysize_node = fgGetNode("/sim/startup/ysize");
82 int iwidth = xsize_node->getIntValue();
83 int iheight = ysize_node->getIntValue();
85 glMatrixMode( GL_PROJECTION );
88 gluOrtho2D( 0, iwidth, 0, iheight );
89 glMatrixMode( GL_MODELVIEW );
93 glDisable( GL_DEPTH_TEST );
94 glDisable( GL_LIGHTING );
96 glColor3f( 0.9, 0.4, 0.2 );
98 float fps = general.get_frame_rate();
101 //cout << "dsp_offset1 = " << dsp_offset1 << " dsp_offset2 = " << dsp_offset2 << endl;
102 if(dsp_offset1 == 0) {
105 if(dsp_offset2 == 0) {
108 // Check for the situation where one offset is negative and the message is changed
109 if(change_msg_flag) {
110 if(dsp_offset1 < 0) {
112 } else if(dsp_offset2 < 0) {
115 change_msg_flag = false;
118 // guiFnt.drawString( rep_msg_str.c_str(),
119 // int(iwidth - guiFnt.getStringWidth(buf) - 10 - (int)dsp_offset),
121 guiFnt.drawString( msg1.c_str(),
122 int(iwidth - 10 - dsp_offset1),
124 guiFnt.drawString( msg2.c_str(),
125 int(iwidth - 10 - dsp_offset2),
128 // Try to scroll at a frame rate independent speed
129 // 40 pixels/second looks about right for now
130 if(dsp_offset1 >= dsp_offset2) {
131 dsp_offset1+=(40.0/fps);
132 dsp_offset2 = dsp_offset1 - (rep_msg_str.size() * 10) - 100;
133 if(dsp_offset1 > (iwidth + (rep_msg_str.size() * 10)))
136 dsp_offset2+=(40.0/fps);
137 dsp_offset1 = dsp_offset2 - (rep_msg_str.size() * 10) - 100;
138 if(dsp_offset2 > (iwidth + (rep_msg_str.size() * 10)))
145 //cout << "Attempting to render single message\n";
146 // We have at least one non-repeating message to process
147 if(fgGetBool("/ATC/display/scroll-single-messages")) { // Scroll single messages across the screen.
148 msgList_itr = msgList.begin();
150 while(msgList_itr != msgList.end()) {
151 atcMessage m = *msgList_itr;
152 //cout << "m.counter = " << m.counter << '\n';
153 if(m.dsp_offset > (iwidth + (m.msg.size() * 10))) {
154 //cout << "Stopping single message\n";
155 msgList_itr = msgList.erase(msgList_itr);
156 } else if(m.counter > m.start_count) {
157 //cout << "Drawing single message\n";
158 guiFnt.drawString( m.msg.c_str(),
159 int(iwidth - 10 - m.dsp_offset),
162 m.dsp_offset += (80.0/fps);
167 //cout << "Not yet started single message\n";
174 } else { // Display single messages for a short period of time.
175 msgList_itr = msgList.begin();
177 while(msgList_itr != msgList.end()) {
178 atcMessage m = *msgList_itr;
179 //cout << "m.counter = " << m.counter << '\n';
180 if(m.counter > m.stop_count) {
181 //cout << "Stopping single message\n";
182 msgList_itr = msgList.erase(msgList_itr);
183 } else if(m.counter > m.start_count) {
184 int pin = (((int)m.msg.size() * 8) >= iwidth ? 5 : (iwidth - (m.msg.size() * 8))/2);
185 //cout << m.msg << '\n';
186 //cout << "pin = " << pin << ", iwidth = " << iwidth << ", msg.size = " << m.msg.size() << '\n';
187 guiFnt.drawString( m.msg.c_str(), pin, (iheight - 40) );
201 glEnable( GL_DEPTH_TEST );
202 glEnable( GL_LIGHTING );
203 glMatrixMode( GL_PROJECTION );
205 glMatrixMode( GL_MODELVIEW );
210 void FGATCDisplay::RegisterSingleMessage(const string& msg, double delay) {
212 //cout << msg << '\n';
217 m.start_count = delay;
218 m.stop_count = m.start_count + 5.0; // Display for 5ish seconds for now - this might have to change eg. be related to length of message in future
219 //cout << "m.stop_count = " << m.stop_count << '\n';
223 msgList.push_back(m);
224 //cout << "Single message registered\n";
227 void FGATCDisplay::RegisterRepeatingMessage(const string& msg) {
234 void FGATCDisplay::ChangeRepeatingMessage(const string& newmsg) {
236 rep_msg_str = newmsg;
237 change_msg_flag = true;
241 void FGATCDisplay::CancelRepeatingMessage() {