4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "Startup.hpp"
25 #include "Interface.hpp"
26 #include "Components.hpp"
27 #include "Profile/Profile.hpp"
28 #include "Profile/ProfileKeys.hpp"
30 #include "Simulator.hpp"
31 #include "InfoBoxes/InfoBoxManager.hpp"
32 #include "Terrain/RasterTerrain.hpp"
33 #include "Terrain/RasterWeather.hpp"
34 #include "Input/InputEvents.hpp"
35 #include "Input/InputQueue.hpp"
36 #include "Geo/Geoid.hpp"
37 #include "Dialogs/XML.hpp"
38 #include "Dialogs/Dialogs.h"
39 #include "Dialogs/dlgSimulatorPrompt.hpp"
40 #include "Language/LanguageGlue.hpp"
41 #include "Language/Language.hpp"
42 #include "Protection.hpp"
43 #include "LogFile.hpp"
44 #include "Math/FastMath.h"
45 #include "UtilsSystem.hpp"
46 #include "FLARM/Glue.hpp"
47 #include "MapSettings.hpp"
48 #include "Logger/Logger.hpp"
49 #include "Logger/NMEALogger.hpp"
50 #include "Logger/GlueFlightLogger.hpp"
51 #include "Waypoint/WaypointDetailsReader.hpp"
52 #include "Blackboard/DeviceBlackboard.hpp"
53 #include "MapWindow/GlueMapWindow.hpp"
54 #include "Markers/Markers.hpp"
55 #include "Markers/ProtectedMarkers.hpp"
56 #include "Device/device.hpp"
57 #include "Topography/TopographyStore.hpp"
58 #include "Topography/TopographyGlue.hpp"
59 #include "Audio/VarioGlue.hpp"
60 #include "Screen/Busy.hpp"
61 #include "Polar/PolarGlue.hpp"
62 #include "Polar/Polar.hpp"
63 #include "CommandLine.hpp"
64 #include "MainWindow.hpp"
65 #include "Look/Look.hpp"
66 #include "Look/Fonts.hpp"
68 #include "Computer/GlideComputer.hpp"
69 #include "Computer/GlideComputerInterface.hpp"
70 #include "Computer/Events.hpp"
71 #include "StatusMessage.hpp"
72 #include "MergeThread.hpp"
73 #include "CalculationThread.hpp"
74 #include "Replay/Replay.hpp"
75 #include "LocalPath.hpp"
76 #include "IO/FileCache.hpp"
77 #include "Net/DownloadManager.hpp"
78 #include "Hardware/AltairControl.hpp"
79 #include "Hardware/Display.hpp"
80 #include "Hardware/DisplayGlue.hpp"
82 #include "NMEA/Aircraft.hpp"
83 #include "Waypoint/Waypoints.hpp"
84 #include "Waypoint/WaypointGlue.hpp"
86 #include "Airspace/AirspaceWarningManager.hpp"
87 #include "Airspace/Airspaces.hpp"
88 #include "Airspace/AirspaceGlue.hpp"
89 #include "Airspace/ProtectedAirspaceWarningManager.hpp"
91 #include "Task/TaskManager.hpp"
92 #include "Task/ProtectedTaskManager.hpp"
93 #include "Engine/Task/Ordered/OrderedTask.hpp"
94 #include "GlideSolvers/GlidePolar.hpp"
95 #include "Operation/VerboseOperationEnvironment.hpp"
96 #include "PageActions.hpp"
97 #include "Weather/Features.hpp"
98 #include "Weather/NOAAGlue.hpp"
99 #include "Weather/NOAAStore.hpp"
100 #include "Plane/PlaneGlue.hpp"
101 #include "UIState.hpp"
102 #include "Tracking/TrackingGlue.hpp"
103 #include "Units/Units.hpp"
104 #include "Formatter/UserGeoPointFormatter.hpp"
105 #include "Thread/Debug.hpp"
108 #include "Screen/OpenGL/Globals.hpp"
110 #include "DrawThread.hpp"
113 static Markers
*marks
;
114 static TaskManager
*task_manager
;
115 static GlideComputerEvents
*glide_computer_events
;
116 static GlideComputerTaskEvents
*task_events
;
121 if (StringIsEmpty(Profile::GetPath()) &&
122 !dlgStartupShowModal())
128 Units::SetConfig(CommonInterface::GetUISettings().units
);
129 SetUserCoordinateFormat(CommonInterface::GetUISettings().coordinate_format
);
131 #ifdef HAVE_MODEL_TYPE
132 global_model_type
= CommonInterface::GetSystemSettings().model_type
;
141 StartupLogFreeRamAndStorage();
143 CommonInterface::status_messages
.Startup(true);
145 if (is_simulator()) {
146 InputEvents::processGlideComputer(GCE_STARTUP_SIMULATOR
);
148 InputEvents::processGlideComputer(GCE_STARTUP_REAL
);
151 const TaskFactoryType task_type_default
=
152 CommonInterface::GetComputerSettings().task
.task_type_default
;
153 OrderedTask
*defaultTask
=
154 protected_task_manager
->TaskCreateDefault(&way_points
, task_type_default
);
157 ScopeSuspendAllThreads suspend
;
158 defaultTask
->CheckDuplicateWaypoints(way_points
);
159 way_points
.Optimise();
162 defaultTask
->FillMatPoints(way_points
);
163 protected_task_manager
->TaskCommit(*defaultTask
);
167 task_manager
->Resume();
169 CommonInterface::main_window
->Fullscreen();
170 InfoBoxManager::SetDirty();
174 CommonInterface::status_messages
.Startup(false);
179 * @param hInstance Instance handle
180 * @param lpCmdLine Command line string
181 * @return True if bootup successful, False otherwise
186 VerboseOperationEnvironment operation
;
189 //If "XCSoar" is already running, stop this instance
190 if (MainWindow::Find())
194 #ifdef HAVE_DOWNLOAD_MANAGER
195 Net::DownloadManager::Initialise();
198 LogFormat("Display dpi=%u,%u", Display::GetXDPI(), Display::GetYDPI());
200 // Creates the main window
202 TopWindowStyle style
;
203 if (CommandLine::full_screen
)
205 if (CommandLine::resizable
)
208 MainWindow
*const main_window
= CommonInterface::main_window
=
209 new MainWindow(CommonInterface::status_messages
);
210 main_window
->Create(SystemWindowSize(), style
);
211 if (!main_window
->IsDefined())
219 "npot=%d vbo=%d fbo=%d stencil=%#x",
223 OpenGL::texture_non_power_of_two
,
224 OpenGL::vertex_buffer_object
,
225 OpenGL::frame_buffer_object
,
226 OpenGL::render_buffer_stencil
);
229 main_window
->Initialise();
231 #ifdef SIMULATOR_AVAILABLE
232 // prompt for simulator if not set by command line argument "-simulator" or "-fly"
233 if (!sim_set_in_cmd_line_flag
) {
234 DialogLook white_look
;
235 white_look
.Initialise(Fonts::map_bold
, Fonts::map
, Fonts::map_label
,
236 Fonts::map_bold
, Fonts::map_bold
, Fonts::map_bold
);
237 white_look
.SetBackgroundColor(COLOR_WHITE
);
238 SetXMLDialogLook(white_look
);
240 SimulatorPromptResult result
= dlgSimulatorPromptShowModal();
246 global_simulator_flag
= false;
250 global_simulator_flag
= true;
256 SetXMLDialogLook(main_window
->GetLook().dialog
);
258 CommonInterface::SetSystemSettings().SetDefaults();
259 CommonInterface::SetComputerSettings().SetDefaults();
260 CommonInterface::SetUISettings().SetDefaults();
261 CommonInterface::SetUIState().Clear();
263 const auto &computer_settings
= CommonInterface::GetComputerSettings();
264 const auto &ui_settings
= CommonInterface::GetUISettings();
265 auto &live_blackboard
= CommonInterface::GetLiveBlackboard();
270 operation
.SetText(_("Initialising"));
272 /* create XCSoarData on the first start */
275 Display::LoadOrientation(operation
);
277 main_window
->InitialiseConfigured();
279 TCHAR path
[MAX_PATH
];
280 LocalPath(path
, _T("cache"));
281 file_cache
= new FileCache(path
);
285 CommonInterface::status_messages
.LoadFile();
286 InputEvents::readFile();
288 // Initialize DeviceBlackboard
289 device_blackboard
= new DeviceBlackboard();
291 DeviceListInitialise();
293 // Initialize Markers
294 marks
= new Markers();
295 protected_marks
= new ProtectedMarkers(*marks
);
297 #ifdef HAVE_AYGSHELL_DLL
298 const AYGShellDLL
&ayg
= main_window
->ayg_shell_dll
;
299 ayg
.SHSetAppKeyWndAssoc(VK_APP1
, *main_window
);
300 ayg
.SHSetAppKeyWndAssoc(VK_APP2
, *main_window
);
301 ayg
.SHSetAppKeyWndAssoc(VK_APP3
, *main_window
);
302 ayg
.SHSetAppKeyWndAssoc(VK_APP4
, *main_window
);
303 // Typical Record Button
304 // Why you can't always get this to work
305 // http://forums.devbuzz.com/m_1185/mpage_1/key_/tm.htm
306 // To do with the fact it is a global hotkey, but you can with code above
307 // Also APPA is record key on some systems
308 ayg
.SHSetAppKeyWndAssoc(VK_APP5
, *main_window
);
309 ayg
.SHSetAppKeyWndAssoc(VK_APP6
, *main_window
);
312 // Initialize main blackboard data
313 task_events
= new GlideComputerTaskEvents();
314 task_manager
= new TaskManager(computer_settings
.task
, way_points
);
315 task_manager
->SetTaskEvents(*task_events
);
316 task_manager
->Reset();
318 protected_task_manager
=
319 new ProtectedTaskManager(*task_manager
, computer_settings
.task
);
321 // Read the terrain file
322 operation
.SetText(_("Loading Terrain File..."));
323 LogFormat("OpenTerrain");
324 terrain
= RasterTerrain::OpenTerrain(file_cache
, operation
);
326 logger
= new Logger();
328 glide_computer
= new GlideComputer(way_points
, airspace_database
,
329 *protected_task_manager
,
331 glide_computer
->ReadComputerSettings(computer_settings
);
332 glide_computer
->SetTerrain(terrain
);
333 glide_computer
->SetLogger(logger
);
334 glide_computer
->Initialise();
336 replay
= new Replay(logger
, *protected_task_manager
);
338 // Load the EGM96 geoid data
341 GlidePolar
&gp
= CommonInterface::SetComputerSettings().polar
.glide_polar_task
;
342 gp
= GlidePolar(fixed(0));
343 gp
.SetMC(computer_settings
.task
.safety_mc
);
344 gp
.SetBugs(computer_settings
.polar
.degradation_factor
);
345 PlaneGlue::FromProfile(CommonInterface::SetComputerSettings().plane
);
346 PlaneGlue::Synchronize(computer_settings
.plane
,
347 CommonInterface::SetComputerSettings(), gp
);
348 task_manager
->SetGlidePolar(gp
);
350 // Read the topography file(s)
351 topography
= new TopographyStore();
352 LoadConfiguredTopography(*topography
, operation
);
354 // Read the waypoint files
355 WaypointGlue::LoadWaypoints(way_points
, terrain
, operation
);
357 // Read and parse the airfield info file
358 WaypointDetails::ReadFileFromProfile(way_points
, operation
);
360 // Set the home waypoint
361 WaypointGlue::SetHome(way_points
, terrain
,
362 CommonInterface::SetComputerSettings().poi
,
363 CommonInterface::SetComputerSettings().team_code
,
364 device_blackboard
, false);
366 // ReSynchronise the blackboards here since SetHome touches them
367 device_blackboard
->Merge();
368 CommonInterface::ReadBlackboardBasic(device_blackboard
->Basic());
370 // Scan for weather forecast
371 LogFormat("RASP load");
372 RASP
.ScanAll(CommonInterface::Basic().location
, operation
);
374 // Reads the airspace files
375 ReadAirspace(airspace_database
, terrain
, computer_settings
.pressure
,
379 const AircraftState aircraft_state
=
380 ToAircraftState(device_blackboard
->Basic(),
381 device_blackboard
->Calculated());
382 ProtectedAirspaceWarningManager::ExclusiveLease
lease(glide_computer
->GetAirspaceWarnings());
383 lease
->Reset(aircraft_state
);
387 noaa_store
= new NOAAStore();
388 noaa_store
->LoadFromProfile();
391 AudioVarioGlue::Initialise();
392 AudioVarioGlue::Configure(ui_settings
.sound
.vario
);
394 // Start the device thread(s)
395 operation
.SetText(_("Starting devices"));
399 -- Reset polar in case devices need the data
400 GlidePolar::UpdatePolar(true, computer_settings);
402 This should be done inside devStartup if it is really required
405 operation
.SetText(_("Initialising display"));
407 GlueMapWindow
*map_window
= main_window
->GetMap();
408 if (map_window
!= NULL
) {
409 map_window
->SetWaypoints(&way_points
);
410 map_window
->SetTask(protected_task_manager
);
411 map_window
->SetRoutePlanner(&glide_computer
->GetProtectedRoutePlanner());
412 map_window
->SetGlideComputer(glide_computer
);
413 map_window
->SetAirspaces(&airspace_database
);
415 map_window
->SetTopography(topography
);
416 map_window
->SetTerrain(terrain
);
417 map_window
->SetWeather(&RASP
);
418 map_window
->SetMarks(protected_marks
);
419 map_window
->SetLogger(logger
);
422 map_window
->SetNOAAStore(noaa_store
);
425 /* show map at home waypoint until GPS fix becomes available */
426 if (computer_settings
.poi
.home_location_available
)
427 map_window
->SetLocation(computer_settings
.poi
.home_location
);
430 // Finally ready to go.. all structures must be present before this.
432 // Create the drawing thread
433 #ifndef ENABLE_OPENGL
434 draw_thread
= new DrawThread(*map_window
);
435 draw_thread
->Start(true);
438 // Show the infoboxes
439 InfoBoxManager::Show();
441 // Create the calculation thread
442 CreateCalculationThread();
444 // Find unique ID of this PDA
447 glide_computer_events
= new GlideComputerEvents();
448 glide_computer_events
->Reset();
449 live_blackboard
.AddListener(*glide_computer_events
);
451 if (computer_settings
.logger
.enable_flight_logger
) {
452 flight_logger
= new GlueFlightLogger(live_blackboard
);
453 LocalPath(path
, _T("flights.log"));
454 flight_logger
->SetPath(path
);
457 if (computer_settings
.logger
.enable_nmea_logger
)
458 NMEALogger::enabled
= true;
460 LogFormat("ProgramStarted");
462 // Give focus to the map
463 main_window
->SetDefaultFocus();
465 // Start calculation thread
466 merge_thread
->Start();
467 calculation_thread
->Start();
469 PageActions::Update();
472 tracking
= new TrackingGlue();
473 tracking
->SetSettings(computer_settings
.tracking
);
475 #ifdef HAVE_SKYLINES_TRACKING_HANDLER
476 if (map_window
!= nullptr)
477 map_window
->SetSkyLinesData(&tracking
->GetSkyLinesData());
481 assert(!global_running
);
482 global_running
= true;
488 main_window
->FinishStartup();
496 VerboseOperationEnvironment operation
;
497 gcc_unused ScopeBusyIndicator busy
;
499 MainWindow
*const main_window
= CommonInterface::main_window
;
500 auto &live_blackboard
= CommonInterface::GetLiveBlackboard();
502 // Show progress dialog
503 operation
.SetText(_("Shutdown, please wait..."));
505 // Log shutdown information
506 LogFormat("Entering shutdown...");
508 main_window
->BeginShutdown();
510 StartupLogFreeRamAndStorage();
512 // Turn off all displays
513 global_running
= false;
516 if (tracking
!= NULL
)
517 tracking
->StopAsync();
520 // Stop logger and save igc file
521 operation
.SetText(_("Shutdown, saving logs..."));
522 logger
->GUIStopLogger(CommonInterface::Basic(), true);
524 delete flight_logger
;
525 flight_logger
= NULL
;
527 live_blackboard
.RemoveListener(*glide_computer_events
);
528 delete glide_computer_events
;
532 // Save settings to profile
533 operation
.SetText(_("Shutdown, saving profile..."));
538 AudioVarioGlue::Deinitialise();
540 operation
.SetText(_("Shutdown, please wait..."));
543 LogFormat("Stop threads");
544 #ifdef HAVE_DOWNLOAD_MANAGER
545 Net::DownloadManager::BeginDeinitialise();
547 #ifndef ENABLE_OPENGL
548 draw_thread
->BeginStop();
550 calculation_thread
->BeginStop();
551 merge_thread
->BeginStop();
553 // Wait for the calculations thread to finish
554 LogFormat("Waiting for calculation thread");
556 merge_thread
->Join();
560 calculation_thread
->Join();
561 delete calculation_thread
;
562 calculation_thread
= NULL
;
564 // Wait for the drawing thread to finish
565 #ifndef ENABLE_OPENGL
566 LogFormat("Waiting for draw thread");
572 LogFormat("delete MapWindow");
573 main_window
->Deinitialise();
575 // Save the task for the next time
576 operation
.SetText(_("Shutdown, saving task..."));
578 LogFormat("Save default task");
579 protected_task_manager
->TaskSaveDefault();
581 // Clear waypoint database
584 operation
.SetText(_("Shutdown, please wait..."));
586 // Clear weather database
589 // Clear terrain database
594 delete protected_marks
;
597 // Close any device connections
600 NMEALogger::Shutdown();
604 DeviceListDeinitialise();
606 delete device_blackboard
;
607 device_blackboard
= NULL
;
609 protected_task_manager
->SetRoutePlanner(NULL
);
611 delete protected_task_manager
;
619 if (tracking
!= NULL
) {
620 tracking
->WaitStopped();
625 #ifdef HAVE_DOWNLOAD_MANAGER
626 Net::DownloadManager::Deinitialise();
629 // Close the progress dialog
630 LogFormat("Close Progress Dialog");
633 // Clear the EGM96 database
636 delete glide_computer
;
640 // Clear airspace database
641 airspace_database
.clear();
643 // Destroy FlarmNet records
644 DeinitTrafficGlobals();
648 LogFormat("Close Windows - main");
649 main_window
->Destroy();
653 Display::RestoreOrientation();
655 StartupLogFreeRamAndStorage();
657 LogFormat("Finished shutdown");