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., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <simgear/misc/props.hxx>
27 #include <Include/general.hxx>
28 #include <Main/fg_props.hxx>
31 #include "ATCdisplay.hxx"
35 FGATCDisplay::FGATCDisplay() {
37 change_msg_flag = false;
44 FGATCDisplay::~FGATCDisplay() {
47 void FGATCDisplay::init() {
50 void FGATCDisplay::bind() {
53 void FGATCDisplay::unbind() {
56 // update - this actually draws the visuals and should be called from the main Flightgear rendering loop.
57 void FGATCDisplay::update(double dt) {
59 // These strings are used for temporary storage of the transmission string in order
60 // that the string we view only changes when the next repetition starts scrolling
61 // even though the master string (rep_msg_str) may change at any time.
62 static string msg1 = "";
63 static string msg2 = "";
66 //cout << "dsp_offset1 = " << dsp_offset1 << " dsp_offset2 = " << dsp_offset2 << endl;
67 if(dsp_offset1 == 0) {
70 if(dsp_offset2 == 0) {
73 // Check for the situation where one offset is negative and the message is changed
77 } else if(dsp_offset2 < 0) {
80 change_msg_flag = false;
83 float fps = general.get_frame_rate();
85 //cout << "In FGATC::update()" << endl;
86 SGPropertyNode *xsize_node = fgGetNode("/sim/startup/xsize");
87 SGPropertyNode *ysize_node = fgGetNode("/sim/startup/ysize");
88 int iwidth = xsize_node->getIntValue();
89 int iheight = ysize_node->getIntValue();
91 glMatrixMode( GL_PROJECTION );
94 gluOrtho2D( 0, iwidth, 0, iheight );
95 glMatrixMode( GL_MODELVIEW );
99 glDisable( GL_DEPTH_TEST );
100 glDisable( GL_LIGHTING );
102 glColor3f( 0.9, 0.4, 0.2 );
104 // guiFnt.drawString( rep_msg_str.c_str(),
105 // int(iwidth - guiFnt.getStringWidth(buf) - 10 - (int)dsp_offset),
107 guiFnt.drawString( msg1.c_str(),
108 int(iwidth - 10 - dsp_offset1),
110 guiFnt.drawString( msg2.c_str(),
111 int(iwidth - 10 - dsp_offset2),
113 glEnable( GL_DEPTH_TEST );
114 glEnable( GL_LIGHTING );
115 glMatrixMode( GL_PROJECTION );
117 glMatrixMode( GL_MODELVIEW );
120 // Try to scroll at a frame rate independent speed
121 // 40 pixels/second looks about right for now
122 if(dsp_offset1 >= dsp_offset2) {
123 dsp_offset1+=(40.0/fps);
124 dsp_offset2 = dsp_offset1 - (rep_msg_str.size() * 10) - 100;
125 if(dsp_offset1 > (iwidth + (rep_msg_str.size() * 10)))
128 dsp_offset2+=(40.0/fps);
129 dsp_offset1 = dsp_offset2 - (rep_msg_str.size() * 10) - 100;
130 if(dsp_offset2 > (iwidth + (rep_msg_str.size() * 10)))
137 //cout << "Attempting to render single message\n";
138 // We have at least one non-repeating message to process
139 msgList_itr = msgList.begin();
141 while(msgList_itr != msgList.end()) {
142 atcMessage m = *msgList_itr;
143 //cout << "m.counter = " << m.counter << '\n';
144 if(m.counter > m.stop_count) {
145 //cout << "Stopping single message\n";
146 msgList_itr = msgList.erase(msgList_itr);
147 } else if(m.counter > m.start_count) {
148 //cout << "Displaying single message\n";
149 // Display the message
150 // FIXME - I'm sure all this opengl code should only be called once until all drawing is finished
151 SGPropertyNode *xsize_node = fgGetNode("/sim/startup/xsize");
152 SGPropertyNode *ysize_node = fgGetNode("/sim/startup/ysize");
153 int iwidth = xsize_node->getIntValue();
154 int iheight = ysize_node->getIntValue();
155 glMatrixMode( GL_PROJECTION );
158 gluOrtho2D( 0, iwidth, 0, iheight );
159 glMatrixMode( GL_MODELVIEW );
163 glDisable( GL_DEPTH_TEST );
164 glDisable( GL_LIGHTING );
166 glColor3f( 0.9, 0.4, 0.2 );
168 guiFnt.drawString( m.msg.c_str(),
170 (iheight - 40) ); // TODO - relate the distance in that the string is rendered to the string length.
171 glEnable( GL_DEPTH_TEST );
172 glEnable( GL_LIGHTING );
173 glMatrixMode( GL_PROJECTION );
175 glMatrixMode( GL_MODELVIEW );
191 void FGATCDisplay::RegisterSingleMessage(string msg, int delay) {
196 m.start_count = delay * 30; // Fixme - need to use actual FPS
197 m.stop_count = m.start_count + 100; // Display for 3 - 5 seconds for now - this might have to change eg. be related to length of message in future
198 //cout << "m.stop_count = " << m.stop_count << '\n';
201 msgList.push_back(m);
202 //cout << "Single message registered\n";
205 void FGATCDisplay::RegisterRepeatingMessage(string msg) {
211 void FGATCDisplay::ChangeRepeatingMessage(string newmsg) {
212 rep_msg_str = newmsg;
213 change_msg_flag = true;
217 void FGATCDisplay::CancelRepeatingMessage() {