touchscreen: Kinetic scrolling v3

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]>
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 0e0982cb293ec6238cbd99f6ff2055b23c5decd1
Author: Aidan MacDonald <[email protected]>
Date:   Sun Nov 27 01:48:10 2022 +0000

    touchscreen: Kinetic scrolling v3
    
    Tune accel/decel/press coefficients and add a braking force which
    kicks in when swiping in the opposite direction of scrolling. This
    is instead of the usual acceleration force.
    
    Change-Id: I2b220c98674933a6957d6982020406342cd019bd

diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index 3d77afc929..ba155c0a16 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -561,22 +561,31 @@ struct kinetic {
 static struct kinetic kinetic;
 static struct gesture_vel list_gvel;
 
+/*
+ * NOTE: defaults were chosen for the Shanling Q1, and may need
+ *       tuning for other devices
+ */
+
 const struct list_kinetic_scroll_settings list_kinetic_scroll_accel_default = {
-    .a0 = 1000 << LIST_KINETIC_FRACBITS,
-    .a1 = 1 << (LIST_KINETIC_FRACBITS - 1),
-    /* delay is ignored for this one */
+    .a0 = 200 << LIST_KINETIC_FRACBITS,         /* 200.0 */
+    .a1 = (6 << LIST_KINETIC_FRACBITS) / 5,     /* 1.2 */
+};
+
+const struct list_kinetic_scroll_settings list_kinetic_scroll_brake_default = {
+    .a0 = 200 << LIST_KINETIC_FRACBITS,         /* 200.0 */
+    .a1 = (1 << LIST_KINETIC_FRACBITS) / 2,     /* 0.5 */
 };
 
 const struct list_kinetic_scroll_settings list_kinetic_scroll_decel_default = {
-    .a0 = 3000 << LIST_KINETIC_FRACBITS,
-    .a1 = 1 << (LIST_KINETIC_FRACBITS - 1),
-    .delay = 125 * HZ / 1000,
+    .a0 = 2000 << LIST_KINETIC_FRACBITS,        /* 2000.0 */
+    .a1 = (1 << LIST_KINETIC_FRACBITS) / 2,     /* 0.5 */
+    .delay = 125 * HZ / 1000,                   /* 125 ms */
 };
 
 const struct list_kinetic_scroll_settings list_kinetic_scroll_press_default = {
-    .a0 = 35000 << LIST_KINETIC_FRACBITS,
-    .a1 = 4 << LIST_KINETIC_FRACBITS,
-    .delay = 250 * HZ / 1000,
+    .a0 = 35000 << LIST_KINETIC_FRACBITS,       /* 35000.0 */
+    .a1 = 4 << LIST_KINETIC_FRACBITS,           /* 4.0 */
+    .delay = 250 * HZ / 1000,                   /* 250 ms */
 };
 
 static void kinetic_stop_scrolling(struct kinetic *k, struct gui_synclist *list)
@@ -683,22 +692,26 @@ static bool kinetic_start_scrolling(struct kinetic *k, struct gui_synclist *list
         return false;
 
     long yvel_fp = yvel << LIST_KINETIC_FRACBITS;
+    int vel_sgn = SIGN(k->cb_data.velocity);
+
     if (list->scroll_mode == SCROLL_KINETIC)
     {
-        long accel = kinetic_calc_accel(k->cb_data.velocity, LONG_MAX,
-                                        &global_settings.kinetic_scroll_accel);
-        accel = fp_mul(accel, RELOAD_INTERVAL_FP, LIST_KINETIC_FRACBITS);
-
-        /* the acceleration is in the direction of the swipe */
-        if (SIGN(accel) != SIGN(yvel_fp))
-            accel = -accel;
+        long accel;
+        if (SIGN(yvel) == vel_sgn)
+            accel = kinetic_calc_accel(k->cb_data.velocity, LONG_MAX,
+                                       &global_settings.kinetic_scroll_accel);
+        else
+            accel = -kinetic_calc_accel(k->cb_data.velocity, LONG_MAX,
+                                        &global_settings.kinetic_scroll_brake);
 
         yvel_fp += accel;
     }
 
     k->cb_data.list = list;
     k->cb_data.velocity += yvel_fp;
-    if (list->scroll_mode != SCROLL_KINETIC)
+    /* also reset distance & scroll duration after a direction change */
+    if (list->scroll_mode != SCROLL_KINETIC ||
+        vel_sgn != SIGN(k->cb_data.velocity))
     {
         k->cb_data.distance = 0;
         k->cb_data.scroll_duration = 0;
diff --git a/apps/gui/list.h b/apps/gui/list.h
index 534558c0bc..0e3a350ed7 100644
--- a/apps/gui/list.h
+++ b/apps/gui/list.h
@@ -203,20 +203,25 @@ struct list_kinetic_scroll_settings
     long delay;
 };
 
-/* Acceleration applied to the scroll velocity when a swipe occurs during
- * kinetic scrolling. This is needed to counteract the deceleration term
- * for high scrolling speeds, since the user can only input a low constant
- * acceleration from swiping alone. Delay is ignored. */
+/*
+ * accel: Extra impulse applied when swiping in the direction of scrolling,
+ *        proportional to the current velocity. This is what allows for high
+ *        scroll speeds. Delay is ignored.
+ *
+ * brake: Braking impulse applied when swiping in the opposite direction of
+ *        scrolling, which helps to change direction quickly even at high
+ *        speed. Delay is ignored.
+ *
+ * decel: Deceleration applied during scrolling. The delay is measured from
+ *        the start of scrolling or last change of direction.
+ *
+ * press: Deceleration applied while the screen is pressed (motion is not
+ *        needed to trigger). Additive with "decel". The delay is measured
+ *        from the start of the press.
+ */
 extern const struct list_kinetic_scroll_settings list_kinetic_scroll_accel_default;
-
-/* Deceleration applied to the scroll velocity during kinetic scrolling.
- * The delay occurs right at the beginning of scrolling, eg. a delay of
- * 1 second means deceleration starts 1 second after scrolling. */
+extern const struct list_kinetic_scroll_settings list_kinetic_scroll_brake_default;
 extern const struct list_kinetic_scroll_settings list_kinetic_scroll_decel_default;
-
-/* Deceleration applied during kinetic scrolling when the screen is
- * pressed for longer than the delay interval (motion is not required).
- * This is additive with list_kinetic_scroll_decel. */
 extern const struct list_kinetic_scroll_settings list_kinetic_scroll_press_default;
 #endif
 
diff --git a/apps/settings.h b/apps/settings.h
index 35af24c97d..f5d036f9da 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -801,6 +801,7 @@ struct user_settings
     int touch_mode;
     struct touchscreen_parameter ts_calibration_data;
     struct list_kinetic_scroll_settings kinetic_scroll_accel;
+    struct list_kinetic_scroll_settings kinetic_scroll_brake;
     struct list_kinetic_scroll_settings kinetic_scroll_decel;
     struct list_kinetic_scroll_settings kinetic_scroll_press;
 #endif
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 958e61f07f..5d4e6e6cb7 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -2429,6 +2429,10 @@ const struct settings_list settings[] = {
                    &list_kinetic_scroll_accel_default, "kinetic scroll accel",
                    list_kinetic_load_from_cfg, list_kinetic_write_to_cfg,
                    list_kinetic_is_default, list_kinetic_set_default),
+    CUSTOM_SETTING(0, kinetic_scroll_brake, -1,
+                   &list_kinetic_scroll_brake_default, "kinetic scroll brake",
+                   list_kinetic_load_from_cfg, list_kinetic_write_to_cfg,
+                   list_kinetic_is_default, list_kinetic_set_default),
     CUSTOM_SETTING(0, kinetic_scroll_decel, -1,
                    &list_kinetic_scroll_decel_default, "kinetic scroll decel",
                    list_kinetic_load_from_cfg, list_kinetic_write_to_cfg,
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.