@@ -880,18 +880,18 @@ void drawMapScale()
880880 {100 , 0x44CC44 , 0 },
881881 };
882882
883- // CM_TROPO — surface refractivity N-units. Low N = dry/cold (dark blue),
884- // high N = warm/humid (red). Ducting becomes likely above ~370 N-units.
885883 static const MapScalePoint tropo_scale[] = {
886- {280 , 0x00005A , 0 }, // near-black — very dry, no ducting
887- {295 , 0x001E8C , 0 }, // dark blue
888- {310 , 0x0050C8 , 0 }, // blue — below normal
889- {325 , 0x00A0D2 , 1 }, // cyan — normal
890- {340 , 0x50D250 , 1 }, // green — slightly enhanced
891- {355 , 0xA0E132 , 1 }, // yellow-green — superrefractive
892- {370 , 0xF0C800 , 1 }, // yellow — ducting possible
893- {395 , 0xFF8200 , 1 }, // orange — ducting probable
894- {420 , 0xE61E00 , 1 }, // red — strong ducting
884+ {0 , 0x444444 , 0 },
885+ {1 , 0x8603F1 , 0 },
886+ {2 , 0x01B4EF , 1 },
887+ {3 , 0x02D083 , 1 },
888+ {4 , 0xA5EB01 , 1 },
889+ {5 , 0xEFDE05 , 1 },
890+ {6 , 0xE9B10C , 1 },
891+ {7 , 0xFF8000 , 1 },
892+ {8 , 0xFF0000 , 0 },
893+ {9 , 0xFF80C0 , 1 },
894+ {10 , 0xFFB4DC , 1 },
895895 };
896896
897897 // set these depending on map
@@ -925,8 +925,8 @@ void drawMapScale()
925925 case CM_TROPO :
926926 msp = tropo_scale;
927927 n_scale = NARRAY (tropo_scale);
928- n_labels = 9 ;
929- title = " N-units " ;
928+ n_labels = 11 ;
929+ title = " Index " ;
930930 break ;
931931 case CM_WX :
932932 msp = w_scale;
@@ -1002,6 +1002,55 @@ void drawMapScale()
10021002 v = space_wx[SPCWX_AURORA ].value ;
10031003 v_ok = true ;
10041004 }
1005+ } else if (core_map == CM_TROPO ) {
1006+ // N.B. unlike DRAP/Aurora above, there's no independent "current value" feed to poll --
1007+ // Hepburn doesn't publish one and neither do we. Instead read whatever pixel is actually
1008+ // on screen under the cursor right now (getPixelRaw already reflects the correct
1009+ // projection/zoom/pan and day-night blend, so none of that needs re-deriving here) and
1010+ // nearest-match it against the same 11 colours the legend itself is drawn from, so this
1011+ // stays correct automatically if tropo_scale[] is ever retuned.
1012+ //
1013+ // The raw tropo_scale colour never actually appears on screen unblended -- the rendered
1014+ // map is always tinted (see update_tropo_maps.sh's make_bmp_v4_rgb565_topdown: 20% blend
1015+ // toward 205/220/205 by day, brightness x0.15 by night), so match against BOTH tinted
1016+ // candidates, derived here from the same table, and take whichever is closer. Verified
1017+ // this is exact away from the day/night terminator; in the narrow blended band right at
1018+ // the terminator itself, compositing two different colours can produce a third colour
1019+ // that's genuinely closer to some OTHER band's tinted variant -- that's an inherent limit
1020+ // of colour-matching a blended pixel, not something fixable here.
1021+ uint16_t mx, my;
1022+ if (tft.getMouse (&mx, &my)) {
1023+ SCoord ms = {mx, my};
1024+ uint8_t pr, pg, pb;
1025+ if (overMap (ms) && tft.getPixelRaw (mx, my, &pr, &pg, &pb)) {
1026+ int best_i = -1 ;
1027+ long best_d2 = 0 ;
1028+ for (unsigned i = 0 ; i < n_scale; i++) {
1029+ uint8_t cr = _MS_PTC (i) >> 16 , cg = (_MS_PTC (i) >> 8 ) & 0xFF , cb = _MS_PTC (i) & 0xFF ;
1030+ long ddr = (long )pr - (long )(cr*0 .8F + 205 *0 .2F );
1031+ long ddg = (long )pg - (long )(cg*0 .8F + 220 *0 .2F );
1032+ long ddb = (long )pb - (long )(cb*0 .8F + 205 *0 .2F );
1033+ long dday2 = ddr*ddr + ddg*ddg + ddb*ddb;
1034+ long dnr = (long )pr - (long )(cr*0 .15F );
1035+ long dng = (long )pg - (long )(cg*0 .15F );
1036+ long dnb = (long )pb - (long )(cb*0 .15F );
1037+ long dnight2 = dnr*dnr + dng*dng + dnb*dnb;
1038+ long d2 = dday2 < dnight2 ? dday2 : dnight2;
1039+ if (best_i < 0 || d2 < best_d2) {
1040+ best_d2 = d2;
1041+ best_i = (int )i;
1042+ }
1043+ }
1044+ if (best_i >= 0 ) {
1045+ v = _MS_PTV (best_i);
1046+ v_ok = true ;
1047+ }
1048+ }
1049+ }
1050+ // v_ok simply stays false whenever the cursor isn't over the map (or app), which is exactly
1051+ // what makes the marker disappear next redraw -- drawMapScale() repaints the whole gradient
1052+ // bar unconditionally every call (see the loop above), so there is nothing to explicitly
1053+ // erase; an absent marker this time overwrites a present one from last time for free.
10051054 }
10061055 if (v_ok) {
10071056 // find marker but beware range overflow and leave room for full width
0 commit comments