Sanjay Govind 10 месяцев назад
Родитель
Сommit
4e570a69d8
1 измененных файлов с 57 добавлено и 26 удалено
  1. 57 26
      virtual_portal.c

+ 57 - 26
virtual_portal.c

@@ -36,34 +36,50 @@ void virtual_portal_tick(void* ctx) {
     uint32_t elapsed = furi_get_tick() - led->start_time;
     if (elapsed < led->delay) {
         float t_phase = fminf((float)elapsed / (float)led->delay, 1);
-        if (led->current_phase == 0) {
-            if (led->last_r < led->target_r) {
-                led->r = lerp(led->last_r, led->target_r, t_phase);
-            }
-            if (led->last_g < led->target_g) {
-                led->g = lerp(led->last_g, led->target_g, t_phase);
-            }
-            if (led->last_b < led->target_b) {
-                led->b = lerp(led->last_b, led->target_b, t_phase);
+        
+        if (led->two_phase) {
+            if (led->current_phase == 0) {
+                // Phase 1: Increase channels that need to go up, hold others constant
+                if (led->target_r > led->last_r) {
+                    led->r = lerp(led->last_r, led->target_r, t_phase);
+                }
+                if (led->target_g > led->last_g) {
+                    led->g = lerp(led->last_g, led->target_g, t_phase);
+                }
+                if (led->target_b > led->last_b) {
+                    led->b = lerp(led->last_b, led->target_b, t_phase);
+                }
+            } else {
+                // Phase 2: Decrease channels that need to go down
+                if (led->target_r < led->last_r) {
+                    led->r = lerp(led->last_r, led->target_r, t_phase);
+                }
+                if (led->target_g < led->last_g) {
+                    led->g = lerp(led->last_g, led->target_g, t_phase);
+                }
+                if (led->target_b < led->last_b) {
+                    led->b = lerp(led->last_b, led->target_b, t_phase);
+                }
             }
         } else {
-            if (led->last_r > led->target_r) {
-                led->r = lerp(led->last_r, led->target_r, t_phase);
-            }
-            if (led->last_g > led->target_g) {
-                led->g = lerp(led->last_g, led->target_g, t_phase);
-            }
-            if (led->last_b > led->target_b) {
-                led->b = lerp(led->last_b, led->target_b, t_phase);
-            }
+            // Simple one-phase transition: all channels change together
+            led->r = lerp(led->last_r, led->target_r, t_phase);
+            led->g = lerp(led->last_g, led->target_g, t_phase);
+            led->b = lerp(led->last_b, led->target_b, t_phase);
         }
+        
         furi_hal_light_set(LightRed, led->r);
         furi_hal_light_set(LightGreen, led->g);
         furi_hal_light_set(LightBlue, led->b);
     } else if (led->two_phase && led->current_phase == 0) {
+        // Move to phase 2 - save the current state as our "last" values for phase 2
+        led->last_r = led->r;
+        led->last_g = led->g;
+        led->last_b = led->b;
         led->start_time = furi_get_tick();
         led->current_phase++;
     } else {
+        // Transition complete - set final values
         led->r = led->target_r;
         led->g = led->target_g;
         led->b = led->target_b;
@@ -87,26 +103,41 @@ void queue_led_command(VirtualPortal* virtual_portal, int side, uint8_t r, uint8
             led = &virtual_portal->left;
             break;
     }
-    led->running = false;
+    
+    // Store current values as last values
     led->last_r = led->r;
     led->last_g = led->g;
     led->last_b = led->b;
+    
+    // Set target values
     led->target_r = r;
     led->target_g = g;
     led->target_b = b;
+    
     if (duration) {
-        led->start_time = furi_get_tick();
-        led->delay = duration;
-        bool increasing = r > led->r || g > led->g || b > led->b;
-        bool decreasing = r < led->r || g < led->g || b < led->b;
+        // Determine if we need a two-phase transition
+        bool increasing = (r > led->last_r) || (g > led->last_g) || (b > led->last_b);
+        bool decreasing = (r < led->last_r) || (g < led->last_g) || (b < led->last_b);
         led->two_phase = increasing && decreasing;
-        led->current_phase = increasing ? 0 : 1;
-        if (increasing && decreasing) {
-            duration /= 2;
+        
+        // Set up transition parameters
+        led->start_time = furi_get_tick();
+        if (led->two_phase) {
+            // If two-phase, each phase gets half the duration
+            led->delay = duration / 2;
+        } else {
+            led->delay = duration;
         }
+        
+        // Start in phase 0
+        led->current_phase = 0;
         led->running = true;
     } else {
+        // Immediate change, no transition
         if (side == PORTAL_SIDE_RIGHT) {
+            led->r = r;
+            led->g = g;
+            led->b = b;
             furi_hal_light_set(LightRed, r);
             furi_hal_light_set(LightGreen, g);
             furi_hal_light_set(LightBlue, b);