Beispiel #1
0
int MapWindow::SharedTopView(LKSurface& Surface, DiagrammStruct* psDia , double fAS_Bearing, double fWP_Bearing)
{
    int iOldDisplayOrientation =  DisplayOrientation;
    DiagrammStruct m_Dia =	*psDia;
    const RECT& rct = m_Dia.rc;

    unsigned short getsideviewpage=GetSideviewPage();
    LKASSERT(getsideviewpage<NUMBER_OF_SHARED_MULTIMAPS);
    LKASSERT(Current_Multimap_SizeY!=SIZE0);

    DisplayOrientation = GetMMNorthUp(getsideviewpage);

    switch(GetMMNorthUp(getsideviewpage))
    {
    case TRACKUP:
        break;

    case NORTHUP:
    default:
        m_Dia.fXMin = -m_Dia.fXMax;
        break;
    }

    double fOldScale  =  zoom.Scale();
    const auto hfOld = Surface.SelectObject(LK8PanelUnitFont);

    if(zoom.AutoZoom())
        zoom.AutoZoom(false);
    double fFact = 1.25 ;
#ifdef INIT_CASE


    switch(ScreenSize) {

    case ss800x480:
        fFact=0.750;
        break;
    case ss640x480:
        fFact=0.938;
        break;
    case ss480x272:
        fFact=0.708;
        break;
    case ss400x240:
        fFact=0.750;
        break;
    case ss320x240:
        fFact=0.938;
        break;
    case ss480x800:
        fFact=1.250;
        break;
    case ss480x640:
        fFact=1.250;
        break;
    case ss272x480:
        fFact=1.250;
        break;
    case ss240x400:
        fFact=1.250;
        break;
    case ss240x320:
        fFact=1.250;
        break;
    default:
        fFact=1.000;
        break;
    }
#endif


    if((ScreenSizeX > 0) && (ScreenSizeY > 0))
    {
        if(ScreenSizeX > ScreenSizeY)
            fFact = (double)ScreenSizeY/(double)ScreenSizeX * 1.250;

    }
    PanLatitude  = DrawInfo.Latitude;
    PanLongitude = DrawInfo.Longitude;

    switch(GetMMNorthUp(getsideviewpage))
    {
    case TRACKUP:
        DisplayAngle = AngleLimit360(fAS_Bearing  +270.0);
        DisplayAircraftAngle = AngleLimit360(fWP_Bearing);
        break;

    case NORTHUP:
    default:
        DisplayAngle = 0;
        if( getsideviewpage == IM_HEADING || getsideviewpage==IM_VISUALGLIDE)
            DisplayAircraftAngle = AngleLimit360(fAS_Bearing);
        else
            DisplayAircraftAngle = AngleLimit360(DrawInfo.TrackBearing);
        break;
    }

    int iOldLocator = EnableThermalLocator;
    EnableThermalLocator =0;

    /*******/
#warning "wrong place for do that, always bad idea to change layout inside drawing fonctions !"
    MapWindow::ChangeDrawRect(rct);       // set new area for terrain and topology
    /*******/

    zoom.RequestedScale((m_Dia.fXMax -m_Dia.fXMin)  * fFact *  (DISTANCEMODIFY)/10.0f);

    POINT Orig           =  { CalcDistanceCoordinat(0.0,  (DiagrammStruct*) &m_Dia),(rct.bottom-rct.top)/2};
    POINT Orig_Aircraft= {0,0};

    zoom.ModifyMapScale();
    zoom.UpdateMapScale();

    const ScreenProjection _Proj = CalculateScreenPositions( Orig, rct, &Orig_Aircraft);

    CalculateScreenPositionsAirspace(rct, _Proj);

    bool terrainpainted=false;

    if (IsMultimapTerrain() &&  DerivedDrawInfo.TerrainValid && RasterTerrain::isTerrainLoaded() ) {
        LKTextBlack=false;
        BlackScreen=false;
        LockTerrainDataGraphics();
        DrawTerrain(Surface, rct, _Proj, GetAzimuth(), 40.0);
        UnlockTerrainDataGraphics();
        terrainpainted=true;
    } else {
        // We fill up the background wity chosen empty map color
        Surface.FillRect(&rct, hInvBackgroundBrush[BgMapColor]);
        // We force LK painting black values on screen depending on the background color in use
        // blackscreen would force everything to be painted white, instead
        LKTextBlack=BgMapColorTextBlack[BgMapColor];
        if (BgMapColor>6 ) BlackScreen=true;
        else BlackScreen=false;
    }

    ResetLabelDeclutter();

    // We reduce screen cluttering for some cases..
    short olddecluttermode=DeclutterMode;
    if (Current_Multimap_SizeY==SIZE4) goto _nomoredeclutter;
    if (Current_Multimap_SizeY<SIZE3) {
        DeclutterMode+=2;
    } else {
        if (Current_Multimap_SizeY==SIZE3)
            DeclutterMode++;
    }
    if (DeclutterMode>dmVeryHigh) DeclutterMode=dmVeryHigh;

_nomoredeclutter:

    if (IsMultimapTopology()) {
        // Do not print topology labels, to be used with another config later!
        // SaturateLabelDeclutter();
        DrawTopology(Surface, rct, _Proj);
    } else {
        // No topology is desired, but terrain requires water areas nevertheless
        if (terrainpainted) {
            DrawTopology(Surface, rct, _Proj, true); // water only!
        }
    }


    if (IsMultimapAirspace()) {
        DrawAirSpace(Surface, rct, _Proj);   // full screen, to hide clipping effect on low border
    }

    if (Flags_DrawTask && MapSpaceMode!=MSM_MAPASP && ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1)) {
        DrawTaskAAT(Surface, rct);
        DrawTask(Surface, rct, _Proj, Orig_Aircraft);
    }

    if (IsMultimapWaypoints()) {
        DrawWaypointsNew(Surface,rct);
    }
    if (Flags_DrawFAI)
        DrawFAIOptimizer(Surface, rct, _Proj, Orig_Aircraft);

    DeclutterMode=olddecluttermode; // set it back correctly

    /* THIS STUFF DOES NOT WORK IN SHARED MAPS, YET
       NEED FIXING LatLon2Screen for shared maps using Sideview
       #ifdef GTL2
       if (((FinalGlideTerrain == 2) || (FinalGlideTerrain == 4)) &&
    DerivedDrawInfo.TerrainValid)
    DrawTerrainAbove(hdc, rct);
       #endif
     */


    //
    // Stuff for MAPTRK only (M1)
    if (MapSpaceMode==MSM_MAPTRK) {
        if(IsMultimapTerrain() || IsMultimapTopology() ) {
            if (FinalGlideTerrain && DerivedDrawInfo.TerrainValid)
                DrawGlideThroughTerrain(Surface, rct, _Proj);
        }
        if (extGPSCONNECT)
            DrawBearing(Surface, rct, _Proj);
        // Wind arrow
        if (IsMultimapOverlaysGauges())
            DrawWindAtAircraft2(Surface, Orig_Aircraft, rct);
    }

    if (MapSpaceMode==MSM_MAPWPT) {
        if (extGPSCONNECT)
            DrawBearing(Surface, rct, _Proj);
    }

    switch(GetMMNorthUp(getsideviewpage)) {
    case NORTHUP:
    default:
        DrawCompass( Surface,  rct, 0);
        break;
    case TRACKUP:
        if(getsideviewpage ==  IM_HEADING || getsideviewpage == IM_VISUALGLIDE)
            DrawCompass( Surface,  rct, DrawInfo.TrackBearing-90.0);
        else
            DrawCompass( Surface,  rct, DisplayAngle);
        break;
    }


    /****************************************************************************************************
     * draw vertical line
     ****************************************************************************************************/
    POINT line[2];
    line[0].x = rct.left;
    line[0].y = Orig_Aircraft.y-1;
    line[1].x = rct.right;
    line[1].y = line[0].y;

    switch(GetMMNorthUp(getsideviewpage))
    {
    case TRACKUP:
        // Are we are not topview fullscreen?
        if (Current_Multimap_SizeY<SIZE4 && !(MapSpaceMode==MSM_VISUALGLIDE)) {
            Surface.DrawDashLine(NIBLSCALE(1), line[0], line[1],  Sideview_TextColor, rct);
        } else {
            if (TrackBar) {
                DrawHeadUpLine(Surface, Orig, rct, psDia->fXMin ,psDia->fXMax);
                if (ISGAAIRCRAFT) DrawFuturePos(Surface, Orig, rct, true);
            }
        }
        break;

    case NORTHUP:
    default:
        if (TrackBar) {
            DrawHeadUpLine(Surface, Orig, rct, psDia->fXMin ,psDia->fXMax);
            if (ISGAAIRCRAFT) DrawFuturePos(Surface, Orig, rct, true);
        }
        break;
    }
    DrawAircraft(Surface, Orig_Aircraft);

    // M3 has sideview always on, so wont apply here, and no need to check
    if (Current_Multimap_SizeY==SIZE4) {
        DrawMapScale(Surface,rct,0);
    }

    MapWindow::zoom.RequestedScale(fOldScale);
    EnableThermalLocator = iOldLocator;
    DisplayOrientation = iOldDisplayOrientation;
    Surface.SelectObject(hfOld);
    return 0;

}
void MapWindow::RenderMapWindowBg(LKSurface& Surface, const RECT& rc) {

    if ( (LKSurface::AlphaBlendSupported() && BarOpacity < 100) || mode.AnyPan() ) {
        RECT newRect = {0, 0, ScreenSizeX, ScreenSizeY};
        MapWindow::ChangeDrawRect(newRect);
    } else {
        RECT newRect = {0, 0, ScreenSizeX, ScreenSizeY - BottomSize - (ScreenSizeY-MapRect.bottom)-1};
        MapWindow::ChangeDrawRect(newRect);
    }

    if (QUICKDRAW) {
        goto _skip_calcs;
    }


    // Here we calculate arrival altitude, GD etc for map waypoints. Splitting with multicalc will result in delayed
    // updating of visible landables, for example. The nearest pages do this separately, with their own sorting.
    // Basically we assume -like for nearest- that values will not change that much in the multicalc split time.
    // Target and tasks are recalculated in real time in any case. Nearest too. 
    LKCalculateWaypointReachable(false);

_skip_calcs:

    if (PGZoomTrigger) {
        if (!mode.Is(Mode::MODE_PANORAMA)) {
            mode.Special(Mode::MODE_SPECIAL_PANORAMA, true);
            LastZoomTrigger = DrawInfo.Time;

            Message::AddMessage(1000, 3, gettext(TEXT("_@M872_"))); // LANDSCAPE ZOOM FOR 20s
            LKSound(TEXT("LK_TONEUP.WAV"));
        } else {
            // previously called, see if time has passed
            if (DrawInfo.Time > (LastZoomTrigger + 20.0)) {
                // time has passed, lets go back
                LastZoomTrigger = 0; // just for safety
                mode.Special(Mode::MODE_SPECIAL_PANORAMA, false);
                PGZoomTrigger = false;
                Message::AddMessage(1500, 3, gettext(TEXT("_@M873_"))); // BACK TO NORMAL ZOOM
                LKSound(TEXT("LK_TONEDOWN.WAV"));
            }
        }
    }

    // 
    // "Checkpoint Charlie"
    // This is were we process stuff for anything else but main map.
    // We let the calculations run also for MapSpace modes.
    // But for multimaps, we can also draw some more stuff..
    // We are also sent back here from next code, when we detect that
    // the MapSpace mode has changed from MAP to something else while we
    // were rendering.
    //
QuickRedraw:
    //
    if (DONTDRAWTHEMAP) {
        const bool isMultimap = IsMultiMapShared(); // DrawMapSpace can change "MapSpaceMode", get this before. 
        DrawMapSpace(Surface, rc);
        // Is this a "shared map" environment? 
        if (isMultimap) {
            // Shared map, of course not MSN_MAP, since dontdrawthemap was checked
            //
            if (IsMultimapOverlaysGauges()) {
                RenderOverlayGauges(Surface, rc);
            }
            if (IsMultimapOverlaysText()) {
                DrawLook8000(Surface, rc);
            }

        } else {
            // Not in map painting environment 
            // ex. nearest pages, but also MAPRADAR..
        }

        // 
        DrawBottomBar(Surface, rc);
#ifdef DRAWDEBUG
        DrawDebug(hdc, rc);
#endif
        // no need to do SelectObject as at the bottom of function
        return;
    }

    POINT Orig, Orig_Aircraft;
    CalculateOrigin(rc, &Orig);
    const ScreenProjection _Proj = CalculateScreenPositions(Orig, rc, &Orig_Aircraft);

    // When no terrain is painted, set a background0
    // Remember that in this case we have plenty of cpu time to spend for best result
    if (!IsMultimapTerrain() || !DerivedDrawInfo.TerrainValid || !RasterTerrain::isTerrainLoaded()) {
        // We force LK painting black values on screen depending on the background color in use
        // TODO make it an array once settled
        // blackscreen would force everything to be painted white, instead
        LKTextBlack = BgMapColorTextBlack[BgMapColor];
        if (BgMapColor > 6) BlackScreen = true;
        else BlackScreen = false;
    } else {
        LKTextBlack = false;
        BlackScreen = false;
    }

    // Logic of DONTDRAWTHEMAP is the following:
    // We are rendering the screen page here. If we are here, we passed Checkpoint Charlie.
    // So we were, at charlie, in MSM_MAP: preparing the main map stuff.
    // If we detect that MapSpace has CHANGED while we were doing our job here,
    // it means that the user has clicked meanwhile. He desires another page, so let's
    // reset our intentions and go back to beginning, or nearby..
    // We have a new job to do, for another MapSpace, no more MAP.
    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    bool terrainpainted = false;

    if ((IsMultimapTerrain() && (DerivedDrawInfo.TerrainValid)
            && RasterTerrain::isTerrainLoaded())
            ) {
        // sunelevation is never used, it is still a todo in Terrain
        double sunelevation = 40.0;
        double sunazimuth = GetAzimuth();

        LockTerrainDataGraphics();
        if (DONTDRAWTHEMAP) { // 100318
            UnlockTerrainDataGraphics();
            goto QuickRedraw;
        }
        
        if(DrawTerrain(Surface, DrawRect, _Proj, sunazimuth, sunelevation)) {
            terrainpainted = true;
        }
        
        if (DONTDRAWTHEMAP) {
            UnlockTerrainDataGraphics();
            goto QuickRedraw;
        }
        if (!QUICKDRAW) {
            // SHADED terrain unreachable, aka glide amoeba. This is not the outlined perimeter!
#ifdef GTL2
            if (((FinalGlideTerrain == 2) || (FinalGlideTerrain == 4)) &&
                    DerivedDrawInfo.TerrainValid) {
#else
            if ((FinalGlideTerrain == 2) && DerivedDrawInfo.TerrainValid) {
#endif
                DrawTerrainAbove(Surface, DrawRect);
            }
        }
        UnlockTerrainDataGraphics();
    }

    //
    // REMINDER: WE ARE IN MAIN MAP HERE: MSM_MAP ONLY, OR PANNING MODE!
    // MAPSPACEMODE CAN STILL CHANGE, DUE TO USER INPUT. BUT WE GOT HERE IN
    // EITHER PAN OR MSM_MAP.
    //

    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    if(!terrainpainted) {
        // fill background..
        Surface.FillRect(&rc, hInvBackgroundBrush[BgMapColor]);
    }
        
        
    if (IsMultimapTopology()) {
        DrawTopology(Surface, DrawRect, _Proj);
    } else {
        // If no topology wanted, but terrain painted, we paint only water stuff
        if (terrainpainted) DrawTopology(Surface, DrawRect, _Proj, true);
    }
#if 0
    StartupStore(_T("... Experimental1=%.0f\n"), Experimental1);
    StartupStore(_T("... Experimental2=%.0f\n"), Experimental2);
    Experimental1 = 0.0;
    Experimental2 = 0.0;
#endif

    // Topology labels are printed first, using OLD wps positions from previous run!
    // Reset for topology labels decluttering engine occurs also in another place here!
    ResetLabelDeclutter();

    if ((Flags_DrawTask || TargetDialogOpen) && ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1)) {
        DrawTaskAAT(Surface, DrawRect);
    }


    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    if (IsMultimapAirspace()) {
        DrawAirSpace(Surface, rc, _Proj);
    }

    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    // In QUICKDRAW dont draw trail, thermals, glide terrain
    if (QUICKDRAW) {
        goto _skip_stuff;
    }

    DrawThermalEstimate(Surface, DrawRect, _Proj);
    if (OvertargetMode == OVT_THER) DrawThermalEstimateMultitarget(Surface, DrawRect, _Proj);

    // draw red cross on glide through terrain marker
    if (FinalGlideTerrain && DerivedDrawInfo.TerrainValid) {
        DrawGlideThroughTerrain(Surface, DrawRect, _Proj);
    }

    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

_skip_stuff:

    if (IsMultimapAirspace() && AirspaceWarningMapLabels) {
        DrawAirspaceLabels(Surface, DrawRect, _Proj, Orig_Aircraft);
        if (DONTDRAWTHEMAP) { // 100319
            goto QuickRedraw;
        }
    }

    if (IsMultimapWaypoints()) {
        DrawWaypointsNew(Surface, DrawRect);
    }
    if (TrailActive) {
        LKDrawLongTrail(Surface, Orig_Aircraft, DrawRect);
        // NEED REWRITING
        LKDrawTrail(Surface, DrawRect, _Proj);
    }
    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    if ((Flags_DrawTask || TargetDialogOpen) && ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1)) {
        DrawTask(Surface, DrawRect, _Proj, Orig_Aircraft);

    }
    if (Flags_DrawFAI) {
        if (MapWindow::DerivedDrawInfo.Flying) { // FAI optimizer does not depend on tasks, being based on trace
            DrawFAIOptimizer(Surface, DrawRect, _Proj, Orig_Aircraft);
        } else { // not flying => show FAI sectors for the task
            if (ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1)) {
                DrawTaskSectors(Surface, DrawRect, _Proj);
            }
        }
    }


    // In QUICKDRAW do not paint other useless stuff
    if (QUICKDRAW) {
        if (extGPSCONNECT) DrawBearing(Surface, DrawRect, _Proj);
        goto _skip_2;
    }

    // ---------------------------------------------------

    DrawTeammate(Surface, rc, _Proj);

    if (extGPSCONNECT) {
        DrawBestCruiseTrack(Surface, Orig_Aircraft);
        DrawBearing(Surface, DrawRect, _Proj);
    }

    // draw wind vector at aircraft
    if (NOTANYPAN) {
        DrawWindAtAircraft2(Surface, Orig_Aircraft, DrawRect);
    } else if (mode.Is(Mode::MODE_TARGET_PAN)) {
        DrawWindAtAircraft2(Surface, Orig, rc);
    }

    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    // Draw traffic and other specifix LK gauges
    LKDrawFLARMTraffic(Surface, DrawRect, _Proj, Orig_Aircraft);

    // ---------------------------------------------------
_skip_2:

    if (NOTANYPAN) {

        if (IsMultimapOverlaysGauges()) {
            RenderOverlayGauges(Surface, rc);
        }
        
        if (TrackBar) {
            DrawHeading(Surface, Orig, DrawRect);
            if (ISGAAIRCRAFT) {
                DrawFuturePos(Surface, Orig, DrawRect);
            }
        }
        
        if (ISGAAIRCRAFT) {
            DrawHSIarc(Surface, Orig, DrawRect);
        }        

        if (IsMultimapOverlaysText()) {
            DrawLook8000(Surface, rc);
        }
        DrawBottomBar(Surface, rc);
    }

    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    // Draw glider or paraglider
    if (extGPSCONNECT) {
        DrawAircraft(Surface, Orig_Aircraft);
    }



#if USETOPOMARKS
    // marks on top...
    DrawMarks(hdc, rc);
#endif

    if (!INPAN) {
        DrawMapScale(Surface, rc, zoom.BigZoom()); // unused BigZoom
        DrawCompass(Surface, rc, DisplayAngle);
    }

#ifdef DRAWDEBUG
    DrawDebug(hdc, rc);
#endif

}