// Copyright (c) Asobo Studio, All rights reserved. www.asobostudio.com #include #include "MSFS\MSFS_Render.h" #include #include "MSFS\Render\nanovg.h" #include #include "Shared.h" #include #include #include #include #ifdef _MSC_VER #define snprintf _snprintf_s #elif !defined(__MINGW32__) #include #endif static struct { bool bWeatherVisible = false; FsMapViewWeatherRadarMode eRadarMode; float fRadarCone = 60.f; bool bNeedUpdate = false; } mapViewRadarParam; std::map < FsContext, NVGcontext*> g_MapViewRadarNVGcontext; static FsTextureId mapViewTextureId = -1; // ------------------------ // Callbacks extern "C" { MSFS_CALLBACK bool MapViewRadar_gauge_callback(FsContext ctx, int service_id, void* pData) { switch (service_id) { case PANEL_SERVICE_PRE_INSTALL: { return true; } break; case PANEL_SERVICE_POST_INSTALL: { NVGparams params; params.userPtr = ctx; params.edgeAntiAlias = true; g_MapViewRadarNVGcontext[ctx] = nvgCreateInternal(¶ms); nvgCreateFont(g_MapViewRadarNVGcontext[ctx], "sans-bold", "./data/Roboto-Bold.ttf"); mapViewTextureId = fsMapViewCreate(ctx, 2048, 2048, 0); if (mapViewTextureId == -1) { return false; } fsMapViewSetVisibility(ctx, mapViewTextureId, true); fsMapViewSetViewMode(ctx, mapViewTextureId, FS_MAP_VIEW_MODE_AERIAL); fsMapViewSet3D(ctx, mapViewTextureId, false); fsMapViewSet2DViewFollowMode(ctx, mapViewTextureId, true); fsMapViewSet2DViewRadiusInMeters(ctx, mapViewTextureId, 10000.f); fsMapViewSetWeatherRadarVisibility(ctx, mapViewTextureId, false); mapViewRadarParam.bNeedUpdate = true; const int rainColorSize = 5; FsRainRateColor rainColors[rainColorSize] = { {{ 0.f, 0.f, 0.f, 1.f }, 0.2f}, {{ 0.f, 0.f, 0.2f, 1.f }, 2.5f}, {{ 0.f, 0.2f, 0.f, 1.f }, 10.4f}, {{ 0.2f, 0.f, 0.f, 1.f }, 50.f}, {{ 0.2f, 0.2f, 0.2f, 1.f }, 100.f}, }; fsMapViewSetWeatherRadarRainColors(ctx, mapViewTextureId, rainColors, rainColorSize); return true; } break; case PANEL_SERVICE_PRE_UPDATE: { int existingW, existingH; fsRenderGetTextureSize(ctx, mapViewTextureId, &existingW, &existingH); if (mapViewRadarParam.bNeedUpdate) { fsMapViewSetWeatherRadarVisibility(ctx, mapViewTextureId, mapViewRadarParam.bWeatherVisible); fsMapViewSetWeatherRadarMode(ctx, mapViewTextureId, mapViewRadarParam.eRadarMode); fsMapViewSetWeatherRadarConeAngleInRadians(ctx, mapViewTextureId, nvgDegToRad(mapViewRadarParam.fRadarCone)); mapViewRadarParam.bNeedUpdate = false; } return true; } case PANEL_SERVICE_PRE_DRAW: { NVGcontext* vg = g_MapViewRadarNVGcontext[ctx]; sGaugeDrawData* p_draw_data = (sGaugeDrawData*)pData; float pxRatio = (float)p_draw_data->fbWidth / (float)p_draw_data->winWidth; nvgBeginFrame(vg, p_draw_data->winWidth, p_draw_data->winHeight, pxRatio); nvgResetTransform(vg); // NetBingView if (mapViewTextureId >= 0) { NVGpaint netBingViewPaint = nvgImagePattern(vg, 0, 0, MAP_VIEW_RES_X, MAP_VIEW_RES_Y, 0.0f, mapViewTextureId, 1.f); nvgBeginPath(vg); nvgRect(vg, 0, 0, MAP_VIEW_RES_X, MAP_VIEW_RES_Y); nvgFillPaint(vg, netBingViewPaint); nvgFill(vg); } drawButton(vg, 0, "OFF", DEMO_BUTTON_1_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f); drawButton(vg, 0, "TOPVIEW", DEMO_BUTTON_2_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f); drawButton(vg, 0, "HORIZONTAL", DEMO_BUTTON_3_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f); drawButton(vg, 0, "VERTICAL", DEMO_BUTTON_4_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f); drawButton(vg, 0, "CONE+ ", DEMO_BUTTON_5_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f); drawButton(vg, 0, "CONE-", DEMO_BUTTON_6_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f); nvgEndFrame(vg); return true; } break; case PANEL_SERVICE_PRE_KILL: { NVGcontext* vg = g_MapViewRadarNVGcontext[ctx]; nvgDeleteInternal(vg); g_MapViewRadarNVGcontext.erase(ctx); return true; } break; } return false; } MSFS_CALLBACK void MapViewRadar_mouse_callback(float fX, float fY, int iFlags) { switch (iFlags) { // Mouse click event case MOUSE_LEFTSINGLE: // Switch to the next demo if (fX >= DEMO_BUTTON_1_PX && fX < DEMO_BUTTON_1_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY && fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) { mapViewRadarParam.bWeatherVisible = !mapViewRadarParam.bWeatherVisible; mapViewRadarParam.bNeedUpdate = true; } else if (fX >= DEMO_BUTTON_2_PX && fX < DEMO_BUTTON_2_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY && fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) { mapViewRadarParam.bWeatherVisible = true; mapViewRadarParam.eRadarMode = FS_MAP_VIEW_WEATHER_RADAR_MODE_TOPVIEW; mapViewRadarParam.bNeedUpdate = true; } else if (fX >= DEMO_BUTTON_3_PX && fX < DEMO_BUTTON_3_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY && fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) { mapViewRadarParam.bWeatherVisible = true; mapViewRadarParam.eRadarMode = FS_MAP_VIEW_WEATHER_RADAR_MODE_HORIZONTAL; mapViewRadarParam.bNeedUpdate = true; } else if (fX >= DEMO_BUTTON_4_PX && fX < DEMO_BUTTON_4_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY && fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) { mapViewRadarParam.bWeatherVisible = true; mapViewRadarParam.eRadarMode = FS_MAP_VIEW_WEATHER_RADAR_MODE_VERTICAL; mapViewRadarParam.bNeedUpdate = true; } else if (fX >= DEMO_BUTTON_5_PX && fX < DEMO_BUTTON_5_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY && fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) { mapViewRadarParam.fRadarCone += 60.f; if (mapViewRadarParam.fRadarCone > 360) mapViewRadarParam.fRadarCone = 360.f; mapViewRadarParam.bNeedUpdate = true; } else if (fX >= DEMO_BUTTON_6_PX && fX < DEMO_BUTTON_6_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY && fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) { mapViewRadarParam.fRadarCone -= 60.f; if (mapViewRadarParam.fRadarCone < 0.f) mapViewRadarParam.fRadarCone = 0.f; mapViewRadarParam.bNeedUpdate = true; } break; default: break; } } }