@@ -38,14 +38,59 @@ uint8_t show_lp; // display long path, else short
3838
3939#define GRAYLINE_COS (-0 .208F ) // cos(90 + grayline angle), we use 12 degs
4040#define GRAYLINE_POW (0 .75F ) // cos power exponent, sqrt is too severe, 1 is too gradual
41- static SCoord moremap_s; // drawMoreEarth() scanning location
41+ static SCoord moremap_s; // drawMoreEarth() scanning location
42+ static bool moremap_active; // whether a map sweep is currently in progress
43+ static uint32_t moremap_generation; // incremented whenever a new sweep is explicitly scheduled
44+ static uint32_t next_redraw_ms; // next periodic redraw deadline once a sweep completes
45+ static bool mm_p; // mouse moved during a map sweep; redraw again when done
46+ static uint32_t mm_ms; // throttle mouse-driven city hover redraws
47+ static bool mp_a; // map popup menu currently running
48+ static bool mv_a; // map view menu currently running
49+ #define EARTH_REDRAW_INTERVAL_MS 30000U // redraw slow-changing map overlays at a conservative cadence
4250
4351// cached grid colors
4452uint16_t EARTH_GRIDC , EARTH_GRIDC00 ; // main and highlighted
4553
4654// flag to defer drawing over map until opportune time:
4755bool mapmenu_pending;
4856
57+ static void updateCircumstances ();
58+
59+ /* request a fresh visual sweep of the current map without reloading its source data.
60+ * used to clear old overlays and redraw moving symbols on demand.
61+ */
62+ void scheduleMapRedraw (void )
63+ {
64+ moremap_s.x = 0 ;
65+ moremap_s.y = map_b.y ;
66+ moremap_active = true ;
67+ next_redraw_ms = 0 ;
68+ moremap_generation++;
69+ }
70+
71+
72+
73+ void mm_redraw (void )
74+ {
75+ uint32_t now_ms = millis ();
76+
77+ // City hover is cursor-driven. Do not restart an active progressive map sweep;
78+ // remember that another sweep is needed and start it as soon as the current one finishes.
79+ if (now_ms - mm_ms < 33U || moremap_active) {
80+ mm_p = true ;
81+ return ;
82+ }
83+
84+ mm_p = false ;
85+ scheduleMapRedraw ();
86+ mm_ms = now_ms;
87+ }
88+
89+ bool mm_up (void )
90+ {
91+ return (mp_a || mv_a);
92+ }
93+
4994// grid spacing, degrees
5095#define LL_LAT_GRID 15
5196#define LL_LNG_GRID 15
@@ -447,7 +492,10 @@ static void drawMapPopup(void)
447492
448493 // go
449494 MenuInfo menu = {menu_b, ok_b, UF_CLOCKSOK , M_CANCELOK , 1 , n_menu, mitems};
450- if (runMenu (menu)) {
495+ mp_a = true ;
496+ bool ok = runMenu (menu);
497+ mp_a = false ;
498+ if (ok) {
451499 // init copy for changes
452500 PanZoom new_pz = pan_zoom;
453501
@@ -929,9 +977,11 @@ static void drawMapMenu()
929977 // run menu
930978 SBox ok_b;
931979 MenuInfo menu = {menu_b, ok_b, UF_CLOCKSOK , M_CANCELOK , 1 , MI_N , mitems};
932- bool menu_ok = runMenu (menu);
980+ mv_a = true ;
981+ bool ok = runMenu (menu);
982+ mv_a = false ;
933983
934- if (menu_ok ) {
984+ if (ok ) {
935985
936986
937987 // build new map_rotset
@@ -1118,18 +1168,43 @@ void initEarthMap()
11181168 updateZoneSCoords (ZONE_CQ );
11191169 updateZoneSCoords (ZONE_ITU );
11201170
1121- // init scan line in map_b
1122- moremap_s.x = 0 ; // avoid updateCircumstances() first call to drawMoreEarth()
1123- moremap_s.y = map_b.y ;
1124-
11251171 // now main loop can resume with drawMoreEarth()
1172+ scheduleMapRedraw ();
11261173}
11271174
11281175/* display another earth map row at mmoremap_s.
11291176 */
11301177void drawMoreEarth ()
11311178{
1179+ if (!moremap_active) {
1180+ uint32_t now_ms = millis ();
1181+ bool mm_due = mm_p && now_ms - mm_ms >= 33U ;
1182+ bool map_due = (int32_t )(now_ms - next_redraw_ms) >= 0 ;
1183+
1184+ // Only consume deferred overlays while the map is stable. If a redraw is
1185+ // due now, leave them pending so the fresh map does not immediately paint
1186+ // over them before the end-of-sweep handlers run.
1187+ if (!mm_due && !map_due) {
1188+ if (mapmenu_pending) {
1189+ drawMapMenu ();
1190+ mapmenu_pending = false ;
1191+ }
1192+ if (map_popup.pending ) {
1193+ drawMapPopup ();
1194+ map_popup.pending = false ;
1195+ }
1196+ return ;
1197+ }
11321198
1199+ if (mm_due) {
1200+ mm_p = false ;
1201+ mm_ms = now_ms;
1202+ }
1203+ updateCircumstances ();
1204+ scheduleMapRedraw ();
1205+ }
1206+
1207+ uint32_t sweep_generation = moremap_generation;
11331208 uint16_t last_x = map_b.x + EARTH_W - 1 ;
11341209
11351210 // draw next row
@@ -1167,9 +1242,19 @@ void drawMoreEarth()
11671242 // rotate?
11681243 checkBGMap ();
11691244
1170- // prep for next
1171- updateCircumstances ();
1172- moremap_s.y = map_b.y ;
1245+ // a menu action or map refresh may have already restarted the sweep.
1246+ if (moremap_generation != sweep_generation)
1247+ return ;
1248+
1249+ // otherwise stop here and wait until the next periodic or explicit redraw request.
1250+ moremap_active = false ;
1251+
1252+ if (mm_p) {
1253+ mm_p = false ;
1254+ mm_ms = millis ();
1255+ scheduleMapRedraw ();
1256+ }
1257+ next_redraw_ms = millis () + EARTH_REDRAW_INTERVAL_MS ;
11731258
11741259 // #define TIME_MAP_DRAW // RBF
11751260 #if defined(TIME_MAP_DRAW)
0 commit comments