commit 2666a48cecce12fb978d0d4e53c9a9fb8d2b8305
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon May 13 23:00:33 2019 +0100

    1. Change the API of Dynamic: split makeNowRunFor into two separate 'setDuration' and 'resetToBeginning'
    2. Major changes to the 'Dynamic' app so that we can check more about the Dynamics.

diff --git a/src/main/java/org/distorted/examples/dynamic/DynamicActivity.java b/src/main/java/org/distorted/examples/dynamic/DynamicActivity.java
index 0905e57..fee168c 100644
--- a/src/main/java/org/distorted/examples/dynamic/DynamicActivity.java
+++ b/src/main/java/org/distorted/examples/dynamic/DynamicActivity.java
@@ -20,6 +20,7 @@
 package org.distorted.examples.dynamic;
 
 import org.distorted.library.main.DistortedLibrary;
+import org.distorted.library.type.Dynamic;
 import org.distorted.library.type.Dynamic1D;
 import org.distorted.examples.R;
 
@@ -27,15 +28,18 @@ import android.app.Activity;
 import android.opengl.GLSurfaceView;
 import android.os.Bundle;
 import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
 import android.widget.SeekBar;
+import android.widget.Spinner;
 import android.widget.TextView;
 import android.widget.SeekBar.OnSeekBarChangeListener;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class DynamicActivity extends Activity implements OnSeekBarChangeListener
+public class DynamicActivity extends Activity implements OnSeekBarChangeListener, AdapterView.OnItemSelectedListener
     {
-    private TextView textD, textN;
+    private TextView textD, textC, textN;
     private int p0,p1,p2;
     private int mDim, mMode;
 
@@ -46,25 +50,46 @@ public class DynamicActivity extends Activity implements OnSeekBarChangeListener
       super.onCreate(savedState);
       setContentView(R.layout.dynamicslayout);
 
-      textD = (TextView)findViewById(R.id.dynamicTextDuration);
-      textN = (TextView)findViewById(R.id.dynamicTextNoise);
+      textD = findViewById(R.id.dynamicTextDuration);
+      textC = findViewById(R.id.dynamicTextCount);
+      textN = findViewById(R.id.dynamicTextNoise);
 
       p0=p1=p2=0;
       mDim = DynamicSurfaceView.DIM_2D;
       mMode= Dynamic1D.MODE_LOOP;
 
-      SeekBar barD = (SeekBar)findViewById(R.id.dynamicSeekDuration);
+      SeekBar barD = findViewById(R.id.dynamicSeekDuration);
       barD.setOnSeekBarChangeListener(this);
-      SeekBar bar0 = (SeekBar)findViewById(R.id.dynamicSeekNoise0);
+      SeekBar barC = findViewById(R.id.dynamicSeekCount);
+      barC.setOnSeekBarChangeListener(this);
+      SeekBar bar0 = findViewById(R.id.dynamicSeekNoise0);
       bar0.setOnSeekBarChangeListener(this);
-      SeekBar bar1 = (SeekBar)findViewById(R.id.dynamicSeekNoise1);
+      SeekBar bar1 = findViewById(R.id.dynamicSeekNoise1);
       bar1.setOnSeekBarChangeListener(this);
-      SeekBar bar2 = (SeekBar)findViewById(R.id.dynamicSeekNoise2);
+      SeekBar bar2 = findViewById(R.id.dynamicSeekNoise2);
       bar2.setOnSeekBarChangeListener(this);
 
+      Spinner dimensionSpinner  = findViewById(R.id.dynamicSpinnerDimension);
+      dimensionSpinner.setOnItemSelectedListener(this);
+      String[] dimensions = { "Dimension 1" , "Dimension 2" , "Dimension 3 (XY)" , "Dimension 3 (XZ)" };
+
+      ArrayAdapter<String> adapterDim = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, dimensions );
+      adapterDim.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+      dimensionSpinner.setAdapter(adapterDim);
+      dimensionSpinner.setSelection(1);
+
+      Spinner modeSpinner  = findViewById(R.id.dynamicSpinnerMode);
+      modeSpinner.setOnItemSelectedListener(this);
+      String[] modes = { "MODE_LOOP" , "MODE_PATH" , "MODE_JUMP" };
+
+      ArrayAdapter<String> adapterMode = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, modes );
+      adapterMode.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+      modeSpinner.setAdapter(adapterMode);
+
       if( savedState==null )
         {
         barD.setProgress(50);
+        barC.setProgress(20);
         bar0.setProgress(0);
         bar1.setProgress(0);
         bar2.setProgress(0);
@@ -77,7 +102,7 @@ public class DynamicActivity extends Activity implements OnSeekBarChangeListener
       {
       super.onResume();
       
-      GLSurfaceView view = (GLSurfaceView) this.findViewById(R.id.dynamicSurfaceView);
+      GLSurfaceView view = findViewById(R.id.dynamicSurfaceView);
       view.onResume();
       }
 
@@ -85,7 +110,7 @@ public class DynamicActivity extends Activity implements OnSeekBarChangeListener
     @Override
     protected void onPause() 
       {
-      GLSurfaceView view = (GLSurfaceView) this.findViewById(R.id.dynamicSurfaceView);
+      GLSurfaceView view = findViewById(R.id.dynamicSurfaceView);
       view.onPause();
 
       DistortedLibrary.onPause();
@@ -106,69 +131,68 @@ public class DynamicActivity extends Activity implements OnSeekBarChangeListener
       DistortedLibrary.onDestroy();
       super.onDestroy();
       }     
- 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    public void Loop(View v)
-      {
-      DynamicSurfaceView view = (DynamicSurfaceView) this.findViewById(R.id.dynamicSurfaceView);
-      view.setMode(Dynamic1D.MODE_LOOP);
-      mMode = Dynamic1D.MODE_LOOP;
-      }     
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void Path(View v)
-      {
-      DynamicSurfaceView view = (DynamicSurfaceView) this.findViewById(R.id.dynamicSurfaceView);
-      view.setMode(Dynamic1D.MODE_PATH);
-      mMode = Dynamic1D.MODE_PATH;
-      }  
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void Jump(View v)
+    public void setDim(int dim)
       {
-      DynamicSurfaceView view = (DynamicSurfaceView) this.findViewById(R.id.dynamicSurfaceView);
-      view.setMode(Dynamic1D.MODE_JUMP);
-      mMode = Dynamic1D.MODE_JUMP;
-      }  
-    
+      DynamicSurfaceView view = findViewById(R.id.dynamicSurfaceView);
+      view.setDimension(dim);
+      mDim = dim;
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void Dim1D(View v)
+    public void setMode(int mode)
       {
-      DynamicSurfaceView view = (DynamicSurfaceView) this.findViewById(R.id.dynamicSurfaceView);
-      view.setDimension(DynamicSurfaceView.DIM_1D);
-      mDim = DynamicSurfaceView.DIM_1D;
-      }  
+      DynamicSurfaceView view = findViewById(R.id.dynamicSurfaceView);
+      view.setMode(mode);
+      mMode = mode;
+      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void Dim2D(View v)
+    public void Start(View v)
       {
-      DynamicSurfaceView view = (DynamicSurfaceView) this.findViewById(R.id.dynamicSurfaceView);
-      view.setDimension(DynamicSurfaceView.DIM_2D);
-      mDim = DynamicSurfaceView.DIM_2D;
-      }  
-    
+      DynamicSurfaceView view = findViewById(R.id.dynamicSurfaceView);
+      view.startDynamic();
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void Dim3DXY(View v)
+    public void Reset(View v)
       {
-      DynamicSurfaceView view = (DynamicSurfaceView) this.findViewById(R.id.dynamicSurfaceView);
-      view.setDimension(DynamicSurfaceView.DIM_3DXY);
-      mDim = DynamicSurfaceView.DIM_3DXY;
-      }  
+      DynamicSurfaceView view = findViewById(R.id.dynamicSurfaceView);
+      view.resetPoints();
+      view.stopDynamic();
+      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void Dim3DXZ(View v)
+    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
       {
-      DynamicSurfaceView view = (DynamicSurfaceView) this.findViewById(R.id.dynamicSurfaceView);
-      view.setDimension(DynamicSurfaceView.DIM_3DXZ);
-      mDim = DynamicSurfaceView.DIM_3DXZ;
-      }  
+      int spinnerID = parent.getId();
+
+      if( spinnerID == R.id.dynamicSpinnerDimension )
+        {
+        switch(pos)
+          {
+          case 0: setDim(DynamicSurfaceView.DIM_1D  ); break;
+          case 1: setDim(DynamicSurfaceView.DIM_2D  ); break;
+          case 2: setDim(DynamicSurfaceView.DIM_3DXY); break;
+          case 3: setDim(DynamicSurfaceView.DIM_3DXZ); break;
+          }
+        }
+      else if( spinnerID == R.id.dynamicSpinnerMode )
+        {
+        switch(pos)
+          {
+          case 0: setMode(Dynamic.MODE_LOOP); break;
+          case 1: setMode(Dynamic.MODE_PATH); break;
+          case 2: setMode(Dynamic.MODE_JUMP); break;
+          }
+        }
+      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -191,27 +215,15 @@ public class DynamicActivity extends Activity implements OnSeekBarChangeListener
       mDim = savedInstanceState.getInt("dim");
       mMode= savedInstanceState.getInt("mode");
 
-      switch(mDim)
-        {
-        case DynamicSurfaceView.DIM_1D  : Dim1D(null)  ; break;
-        case DynamicSurfaceView.DIM_2D  : Dim2D(null)  ; break;
-        case DynamicSurfaceView.DIM_3DXY: Dim3DXY(null); break;
-        case DynamicSurfaceView.DIM_3DXZ: Dim3DXZ(null); break;
-        }
-
-      switch(mMode)
-        {
-        case Dynamic1D.MODE_JUMP: Jump(null); break;
-        case Dynamic1D.MODE_PATH: Path(null); break;
-        case Dynamic1D.MODE_LOOP: Loop(null); break;
-        }
+      setDim(mDim);
+      setMode(mMode);
       }
 
-///////////////////////////////////////////////////////////////////
-    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
     public void onProgressChanged(SeekBar bar, int progress, boolean fromUser) 
       {
-      DynamicSurfaceView view = (DynamicSurfaceView) this.findViewById(R.id.dynamicSurfaceView);
+      DynamicSurfaceView view = findViewById(R.id.dynamicSurfaceView);
       int id = bar.getId();
 
       if( id == R.id.dynamicSeekDuration )
@@ -220,7 +232,13 @@ public class DynamicActivity extends Activity implements OnSeekBarChangeListener
         int i = (int)(v/100);
         float t = i/10.0f;
         view.setDuration((int)v);
-        textD.setText("Duration: "+(int)t+" s");
+        textD.setText(getString(R.string.duration_placeholder, (int)t ));
+        }
+      else if( id == R.id.dynamicSeekCount )
+        {
+        float count = progress*0.05f;
+        view.setCount(count);
+        textC.setText(getString(R.string.count_placeholder, count ));
         }
       else
         {
@@ -232,18 +250,13 @@ public class DynamicActivity extends Activity implements OnSeekBarChangeListener
           }
 
         view.setNoise(p0/100.0f,p1/100.0f,p2/100.0f);
-        textN.setText("Noise: "+(p0/100.f)+" "+(p1/100.f)+" "+(p2/100.f));
+        textN.setText(getString(R.string.noise2_placeholder, (p0/100.f) , (p1/100.f), (p2/100.f) ));
         }
       }
 
-///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
     public void onStartTrackingTouch(SeekBar bar) { }
-    
-///////////////////////////////////////////////////////////////////
-
     public void onStopTrackingTouch(SeekBar bar)  { }
-    
-///////////////////////////////////////////////////////////////////
-// end of file
+    public void onNothingSelected(AdapterView<?> parent) { }
 }
diff --git a/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java b/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java
index d6d7724..858276d 100644
--- a/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java
+++ b/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java
@@ -47,7 +47,7 @@ class DynamicRenderer implements GLSurfaceView.Renderer
    private Bitmap mBitmap;
    private Paint mPaint;
 
-   static int texW, texH;
+   private static int texW, texH;
     
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -86,6 +86,9 @@ class DynamicRenderer implements GLSurfaceView.Renderer
      texW = width;
      texH = height;
 
+     DynamicSurfaceView.setHalfHeight(texH/2);
+     DynamicSurfaceView.setHalfWidth(texW/2);
+
      if( mTexture!=null ) mTexture.markForDeletion();
      mTexture= new DistortedTexture(texW,texH);
      mBitmap = Bitmap.createBitmap(texW,texH, Bitmap.Config.ARGB_8888);
diff --git a/src/main/java/org/distorted/examples/dynamic/DynamicSurfaceView.java b/src/main/java/org/distorted/examples/dynamic/DynamicSurfaceView.java
index 2328e6b..a2a6bd8 100644
--- a/src/main/java/org/distorted/examples/dynamic/DynamicSurfaceView.java
+++ b/src/main/java/org/distorted/examples/dynamic/DynamicSurfaceView.java
@@ -22,6 +22,7 @@ package org.distorted.examples.dynamic;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.pm.ConfigurationInfo;
+import android.graphics.Rect;
 import android.opengl.GLSurfaceView;
 import android.view.MotionEvent;
 import android.util.AttributeSet;
@@ -47,22 +48,25 @@ public class DynamicSurfaceView extends GLSurfaceView
     public static final int DIM_3DXZ = 3; 
 
     private static final int NUM_POINTS = 250;
-    private static final int MAX_POINTS =   6;
-
     private static final Object lock = new Object();
 
+    private static int halfScreenHeight=0;
+    private static int halfScreenWidth =0;
+
     private Dynamic1D di1D;
     private Dynamic2D di2D;
     private Dynamic3D di3D;
     
     private Paint mPaint;
-    private int moving;
+    private int mMoving;
     private int mDuration;
     private int mPosition;
-    private long mDiffTime, mLastTime;
+    private long mDiffTime, mLastTime, mStartTime;
     private float mNoise0, mNoise1, mNoise2;
+    private float mCount;
 
     private int mSize1, mSize2, mSizeT, mAvg;
+    private float mFontHeight;
 
     private int currentDim= DIM_2D;
     
@@ -75,7 +79,8 @@ public class DynamicSurfaceView extends GLSurfaceView
     private Static3D p3N;
 
     private float[] mPoints = new float[3*NUM_POINTS];
-      
+    private boolean mRunning;
+
 ///////////////////////////////////////////////////////////////////
     
     public DynamicSurfaceView(Context context, AttributeSet attrs)
@@ -86,20 +91,24 @@ public class DynamicSurfaceView extends GLSurfaceView
       mPaint.setStyle(Style.FILL);
       mPaint.setAntiAlias(true);
 
-      moving    = -1;
+      mMoving = -1;
       mDuration = 10000;
+      mCount    = 0.0f;
       mPosition = 0;
       mNoise0   = 0.0f;
       mNoise1   = 0.0f;
       mNoise2   = 0.0f;
       mDiffTime = -1;
       mLastTime = -1;
+      mStartTime= -1;
+
+      mRunning = false;
 
-      di1D = new Dynamic1D(mDuration,0.0f);
+      di1D = new Dynamic1D(mDuration,mCount);
       p1N  = new Static1D(mNoise0);
-      di2D = new Dynamic2D(mDuration,0.0f);
+      di2D = new Dynamic2D(mDuration,mCount);
       p2N  = new Static2D(mNoise0,mNoise1);
-      di3D = new Dynamic3D(mDuration,0.0f);
+      di3D = new Dynamic3D(mDuration,mCount);
       p3N  = new Static3D(mNoise0,mNoise1,mNoise2);
 
       di1D.setAccessMode(Dynamic.ACCESS_SEQUENTIAL);
@@ -125,14 +134,34 @@ public class DynamicSurfaceView extends GLSurfaceView
       mAvg = (width+height)/2;
 
       mSize1 = mAvg/150;
-      mSize2 = mAvg/60;
+      mSize2 = mAvg/50;
       mSizeT = mAvg/30;
 
       mPaint.setTextSize(mSizeT);
+      mPaint.setTextAlign(Paint.Align.CENTER);
+
+      final Rect textBounds = new Rect();
+      String text = "1";
+      mPaint.getTextBounds(text, 0, text.length(), textBounds);
+      mFontHeight = textBounds.exactCenterY();
 
       clearPoints();
       }
 
+///////////////////////////////////////////////////////////////////
+
+    public static void setHalfWidth(int hw)
+      {
+      halfScreenWidth = hw;
+      }
+
+///////////////////////////////////////////////////////////////////
+
+    public static void setHalfHeight(int hh)
+      {
+      halfScreenHeight = hh;
+      }
+
 ///////////////////////////////////////////////////////////////////
 
     public void setMode(int mode)
@@ -148,9 +177,20 @@ public class DynamicSurfaceView extends GLSurfaceView
       {
       mDuration = duration;
       
-      di1D.makeRunNowFor(duration);
-      di2D.makeRunNowFor(duration);
-      di3D.makeRunNowFor(duration);
+      di1D.setDuration(duration);
+      di2D.setDuration(duration);
+      di3D.setDuration(duration);
+      }
+
+///////////////////////////////////////////////////////////////////
+
+    public void setCount(float count)
+      {
+      mCount = count;
+
+      di1D.setCount(count);
+      di2D.setCount(count);
+      di3D.setCount(count);
       }
 
 ///////////////////////////////////////////////////////////////////
@@ -178,16 +218,9 @@ public class DynamicSurfaceView extends GLSurfaceView
         {
         if( !(currentDim==DIM_3DXY && dim==DIM_3DXZ) && !(currentDim==DIM_3DXZ && dim==DIM_3DXY) )
           {
-          synchronized(lock)
-            {
-            di1D.removeAll();
-            di2D.removeAll();
-            di3D.removeAll();
-
-            clearPoints();
-            }
+          resetPoints();
           }
-      
+
         currentDim = dim;
         }
       }
@@ -196,8 +229,6 @@ public class DynamicSurfaceView extends GLSurfaceView
     
     public void drawCurve(Canvas c, long time)
       {
-      if ( ++mPosition >= NUM_POINTS ) mPosition=0;
-
       if( mLastTime<0 )
         {
         mLastTime = time;
@@ -211,9 +242,20 @@ public class DynamicSurfaceView extends GLSurfaceView
         {
         switch(currentDim)
           {
-          case DIM_1D: drawCurve1D(c,time); break;
-          case DIM_2D: drawCurve2D(c,time); break;
-          default    : drawCurve3D(c,time); break;
+          case DIM_1D: drawHorizontalAxis(c,"x");
+                       drawPath(c,di1D,1,time);
+                       drawRedPoints1D(c);
+                       break;
+          case DIM_2D: drawHorizontalAxis(c,"x");
+                       drawVerticalAxis  (c,"y");
+                       drawPath(c,di2D,1,time);
+                       drawRedPoints2D(c);
+                       break;
+          default    : drawHorizontalAxis(c,"x");
+                       drawVerticalAxis  (c, currentDim==DIM_3DXY ? "y" : "z" );
+                       drawPath(c,di3D,(currentDim==DIM_3DXY ? 1:2),time);
+                       drawRedPoints3D(c);
+                       break;
           }
         }
 
@@ -232,109 +274,147 @@ public class DynamicSurfaceView extends GLSurfaceView
 
 ///////////////////////////////////////////////////////////////////
 
-    private void drawCurve1D(Canvas c, long time)
+    public void resetPoints()
       {
-      int len = di1D.getNumPoints();   
-      mPaint.setColor(0xff000000);
-      
-      c.drawLine(0, DynamicRenderer.texH/2, DynamicRenderer.texW, DynamicRenderer.texH/2, mPaint);
-      c.drawText("x", 0.95f*DynamicRenderer.texW, DynamicRenderer.texH /2 + mSizeT , mPaint);
-
-      if( len>=2 )
+      synchronized(lock)
         {
-        di1D.get(mPoints,3*mPosition, time, mDiffTime);
+        clearPoints();
 
-        for(int i=0; i<NUM_POINTS; i++)
+        switch(currentDim)
           {
-          int color = i<=mPosition ? 0xff - (mPosition           -i)*0xff/(NUM_POINTS-1)
-                                   : 0xff - (mPosition+NUM_POINTS-i)*0xff/(NUM_POINTS-1);
-         
-          mPaint.setColor( 0xffffff + ((color&0xff)<<24) ); 
-          c.drawCircle(mPoints[3*i], DynamicRenderer.texH/2 , mSize1, mPaint );
+          case DIM_1D  : di1D.removeAll(); break;
+          case DIM_2D  : di2D.removeAll(); break;
+          case DIM_3DXY:
+          case DIM_3DXZ: di3D.removeAll(); break;
           }
         }
-     
-      mPaint.setColor(0xffff0000);
-      
-      for(int curr=0; curr<len; curr++)
-        {      
-        p1D = di1D.getPoint(curr);
-        c.drawCircle(p1D.get1(), DynamicRenderer.texH/2 , mSize2, mPaint);
-        }   
       }
-    
+
 ///////////////////////////////////////////////////////////////////
-      
-    private void drawCurve2D(Canvas c, long time)
+
+    public void startDynamic()
+      {
+      mRunning = true;
+      mLastTime= -1;
+      mStartTime = System.currentTimeMillis();
+
+      clearPoints();
+      di1D.resetToBeginning();
+      di2D.resetToBeginning();
+      di3D.resetToBeginning();
+      }
+
+///////////////////////////////////////////////////////////////////
+
+    public void stopDynamic()
+      {
+      mRunning = false;
+      }
+
+///////////////////////////////////////////////////////////////////
+
+    private void drawHorizontalAxis(Canvas c, String label)
       {
-      int len = di2D.getNumPoints();   
       mPaint.setColor(0xff000000);
-      
-      c.drawLine(0, DynamicRenderer.texH/2, DynamicRenderer.texW, DynamicRenderer.texH/2, mPaint);
-      c.drawLine(DynamicRenderer.texW/2, 0, DynamicRenderer.texW/2, DynamicRenderer.texH, mPaint);
-      
-      c.drawText("x", 0.95f* DynamicRenderer.texW    , DynamicRenderer.texH/2+mSizeT , mPaint);
-      c.drawText("y", DynamicRenderer.texW/2 + mSizeT,                        mSizeT , mPaint);
-      
+
+      c.drawLine(0, halfScreenHeight, halfScreenWidth*2, halfScreenHeight, mPaint);
+      c.drawText( label, 0.95f*halfScreenWidth*2, halfScreenHeight + mSizeT , mPaint);
+      }
+
+
+///////////////////////////////////////////////////////////////////
+
+    private void drawVerticalAxis(Canvas c, String label)
+      {
+      mPaint.setColor(0xff000000);
+
+      c.drawLine(halfScreenWidth, 0, halfScreenWidth, halfScreenHeight*2, mPaint);
+      c.drawText(label, halfScreenWidth + mSizeT,                mSizeT , mPaint);
+      }
+
+///////////////////////////////////////////////////////////////////
+
+    private void drawPath(Canvas c, Dynamic dyn, int index, long time)
+      {
+      int len = dyn.getNumPoints();
+
       if( len>=2 )
         {
-        di2D.get(mPoints,3*mPosition, time, mDiffTime);
+        if( mRunning )
+          {
+          if ( ++mPosition >= NUM_POINTS ) mPosition=0;
+
+          if( dyn.getDimension()==1 )
+            {
+            mPoints[3*mPosition+index] = halfScreenHeight;
+            }
+
+          if( dyn.get(mPoints,3*mPosition, time-mStartTime, mDiffTime) )
+            {
+            stopDynamic();
+            }
+          }
 
         for(int i=0; i<NUM_POINTS; i++)
           {
           int color = i<=mPosition ? 0xff - (mPosition           -i)*0xff/(NUM_POINTS-1)
                                    : 0xff - (mPosition+NUM_POINTS-i)*0xff/(NUM_POINTS-1);
-         
+
           mPaint.setColor( 0xffffff + ((color&0xff)<<24) );
-          c.drawCircle(mPoints[3*i], mPoints[3*i+1], mSize1, mPaint );
+          c.drawCircle(mPoints[3*i], mPoints[3*i+index] , mSize1, mPaint );
           }
         }
-     
-      mPaint.setColor(0xffff0000);
-      
+      }
+
+///////////////////////////////////////////////////////////////////
+
+    private void drawRedPoints1D(Canvas c)
+      {
+      int len = di1D.getNumPoints();
+
       for(int curr=0; curr<len; curr++)
-        {      
-        p2D = di2D.getPoint(curr);
-        c.drawCircle(p2D.get1(),p2D.get2(), mSize2, mPaint);
+        {
+        p1D = di1D.getPoint(curr);
+        drawRedPoint(c,curr+"", p1D.get1(), halfScreenHeight);
         }
       }
 
 ///////////////////////////////////////////////////////////////////
-      
-    private void drawCurve3D(Canvas c, long time)
+
+    private void drawRedPoints2D(Canvas c)
       {
-      int len = di3D.getNumPoints();   
-      mPaint.setColor(0xff000000);
-      
-      c.drawLine(0, DynamicRenderer.texH/2, DynamicRenderer.texW  , DynamicRenderer.texH/2, mPaint);
-      c.drawLine(DynamicRenderer.texW/2, 0, DynamicRenderer.texW/2, DynamicRenderer.texH  , mPaint);
-      
-      c.drawText( "x"                             , 0.95f* DynamicRenderer.texW    , DynamicRenderer.texH/2 + mSizeT , mPaint);
-      c.drawText( currentDim==DIM_3DXY ? "y" : "z", DynamicRenderer.texW/2 + mSizeT,                          mSizeT , mPaint);
-      
-      if( len>=2 )
-        {
-        di3D.get(mPoints, 3*mPosition, time, mDiffTime);
+      int len = di2D.getNumPoints();
 
-        for(int i=0; i<NUM_POINTS; i++)
-          {
-          int color = i<=mPosition ? 0xff - (mPosition           -i)*0xff/(NUM_POINTS-1)
-                                   : 0xff - (mPosition+NUM_POINTS-i)*0xff/(NUM_POINTS-1);
-         
-          mPaint.setColor( 0xffffff + ((color&0xff)<<24) ); 
-          c.drawCircle(mPoints[3*i], mPoints[3*i + (currentDim==DIM_3DXY ? 1:2) ], mSize1, mPaint );
-          }
+      for(int curr=0; curr<len; curr++)
+        {
+        p2D = di2D.getPoint(curr);
+        drawRedPoint(c,curr+"", p2D.get1(), p2D.get2());
         }
-     
-      mPaint.setColor(0xffff0000);
-      
+      }
+
+///////////////////////////////////////////////////////////////////
+
+    private void drawRedPoints3D(Canvas c)
+      {
+      int len = di3D.getNumPoints();
+
       for(int curr=0; curr<len; curr++)
-        {      
+        {
         p3D = di3D.getPoint(curr);
-        c.drawCircle(p3D.get1(), currentDim==DIM_3DXY ? p3D.get2():p3D.get3(), mSize2, mPaint);
-        }   
+        drawRedPoint(c,curr+"", p3D.get1(), currentDim==DIM_3DXY ? p3D.get2():p3D.get3());
+        }
       }
-    
+
+///////////////////////////////////////////////////////////////////
+
+    private void drawRedPoint(Canvas c, String label, float width, float height)
+      {
+      mPaint.setColor(0xffff0000);
+      c.drawCircle( width, height, mSize2, mPaint);
+      mPaint.setColor(0xffffffff);
+      c.drawText(label, width,height-mFontHeight, mPaint);
+      }
+
 ///////////////////////////////////////////////////////////////////
 
     private void addNewPoint(int x, int y)
@@ -353,19 +433,14 @@ public class DynamicSurfaceView extends GLSurfaceView
                                     
                        if( (x-gx)*(x-gx) < (mAvg*mAvg/100) )
                          {
-                         moving = g;
+                         mMoving = g;
                          break;
                          }
                        }
-                     if( moving<0 )
+                     if( mMoving <0 )
                        {
                        synchronized(lock)
                          {
-                         if( len>=MAX_POINTS )
-                           {
-                           di1D.removeAll();
-                           clearPoints();
-                           }
                          di1D.add(new Static1D(x));
                          }
                        }
@@ -380,19 +455,14 @@ public class DynamicSurfaceView extends GLSurfaceView
                                     
                        if( (x-gx)*(x-gx) + (y-gy)*(y-gy) < (mAvg*mAvg/100) )
                          {
-                         moving = g;
+                         mMoving = g;
                          break;
                          }
                        }
-                     if( moving<0 )
+                     if( mMoving <0 )
                        {
                        synchronized(lock)
                          {
-                         if( len>=MAX_POINTS )
-                           {
-                           di2D.removeAll();
-                           clearPoints();
-                           }
                          di2D.add(new Static2D(x,y));
                          }
                        }
@@ -410,7 +480,7 @@ public class DynamicSurfaceView extends GLSurfaceView
                        {
                        if( (x-gx)*(x-gx) + (y-gy)*(y-gy) < (mAvg*mAvg/100) )
                          {
-                         moving = g;
+                         mMoving = g;
                          break;
                          }
                        }
@@ -418,28 +488,22 @@ public class DynamicSurfaceView extends GLSurfaceView
                        {
                        if( (x-gx)*(x-gx) + (y-gz)*(y-gz) < (mAvg*mAvg/100) )
                          {
-                         moving = g;
+                         mMoving = g;
                          break;
                          }
                        }
                      }
-                   if( moving<0 )
+                   if( mMoving <0 )
                      { 
                      synchronized(lock)
                        {
-                       if( len>=MAX_POINTS )
-                         {
-                         di3D.removeAll();
-                         clearPoints();
-                         }
-                    
                        if( currentDim==DIM_3DXY )
                          {
-                         di3D.add(new Static3D(x,y, DynamicRenderer.texH/2));
+                         di3D.add(new Static3D(x,y, halfScreenHeight));
                          }
                        if( currentDim==DIM_3DXZ )
                          {
-                         di3D.add(new Static3D(x, DynamicRenderer.texH/2,y));
+                         di3D.add(new Static3D(x, halfScreenHeight,y));
                          }
                        }
                      }
@@ -449,7 +513,8 @@ public class DynamicSurfaceView extends GLSurfaceView
     
 ///////////////////////////////////////////////////////////////////
     
-    @Override public boolean onTouchEvent(MotionEvent event) 
+    @Override
+    public boolean onTouchEvent(MotionEvent event)
       {
       int action = event.getAction();
       int xDown, yDown;
@@ -462,25 +527,25 @@ public class DynamicSurfaceView extends GLSurfaceView
                                       addNewPoint(xDown,yDown);
                                     
                                       break;
-        case MotionEvent.ACTION_MOVE: if( moving>=0 )
+        case MotionEvent.ACTION_MOVE: if( mMoving >=0 )
                                         {
                                         xDown = (int)event.getX();
                                         yDown = (int)event.getY();
                                         
                                         switch(currentDim)
                                           {
-                                          case DIM_1D  : di1D.setPoint(moving, xDown); 
+                                          case DIM_1D  : di1D.setPoint(mMoving, xDown);
                                                          break;
-                                          case DIM_2D  : di2D.setPoint(moving, xDown, yDown);
+                                          case DIM_2D  : di2D.setPoint(mMoving, xDown, yDown);
                                                          break;
-                                          case DIM_3DXY: di3D.setPoint(moving, xDown, yDown, (int)di3D.getPoint(moving).get3());
+                                          case DIM_3DXY: di3D.setPoint(mMoving, xDown, yDown, (int)di3D.getPoint(mMoving).get3());
                                                          break;
-                                          case DIM_3DXZ: di3D.setPoint(moving, xDown, (int)di3D.getPoint(moving).get2(), yDown);
+                                          case DIM_3DXZ: di3D.setPoint(mMoving, xDown, (int)di3D.getPoint(mMoving).get2(), yDown);
                                                          break;
                                           }
                                         }                           
                                       break;
-        case MotionEvent.ACTION_UP  : moving = -1;
+        case MotionEvent.ACTION_UP  : mMoving = -1;
                                       break;
         }
             
diff --git a/src/main/java/org/distorted/examples/earth/EarthActivity.java b/src/main/java/org/distorted/examples/earth/EarthActivity.java
index 0ac31eb..292315b 100644
--- a/src/main/java/org/distorted/examples/earth/EarthActivity.java
+++ b/src/main/java/org/distorted/examples/earth/EarthActivity.java
@@ -39,6 +39,27 @@ public class EarthActivity extends Activity implements SeekBar.OnSeekBarChangeLi
 {
     private EffectName[] mEffectNames;
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    @Override
+    protected void onCreate(Bundle savedState)
+      {
+      super.onCreate(savedState);
+
+      setContentView(R.layout.earthlayout);
+
+      SeekBar levelBar = findViewById(R.id.earthInflateLevel);
+      levelBar.setOnSeekBarChangeListener(this);
+      levelBar.setProgress(50);
+
+      Spinner renderSpinner  = findViewById(R.id.earthSpinnerEffect);
+      renderSpinner.setOnItemSelectedListener(this);
+
+      ArrayAdapter<String> adapterBitmap = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, createEffectNames() );
+      adapterBitmap.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+      renderSpinner.setAdapter(adapterBitmap);
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     @Override
@@ -76,28 +97,6 @@ public class EarthActivity extends Activity implements SeekBar.OnSeekBarChangeLi
       DistortedLibrary.onDestroy();
       super.onDestroy();
       }
- 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    protected void onCreate(Bundle savedState)
-      {
-      super.onCreate(savedState);
-
-      setContentView(R.layout.earthlayout);
-
-      SeekBar levelBar = findViewById(R.id.earthInflateLevel);
-      levelBar.setOnSeekBarChangeListener(this);
-      levelBar.setProgress(50);
-
-      Spinner renderSpinner  = findViewById(R.id.earthSpinnerEffect);
-      renderSpinner.setOnItemSelectedListener(this);
-
-      ArrayAdapter<String> adapterBitmap = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, createEffectNames() );
-      adapterBitmap.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-      renderSpinner.setAdapter(adapterBitmap);
-      }
-
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -133,14 +132,6 @@ public class EarthActivity extends Activity implements SeekBar.OnSeekBarChangeLi
         }
       }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void onStartTrackingTouch(SeekBar bar) { }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void onStopTrackingTouch(SeekBar bar)  { }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
@@ -149,10 +140,6 @@ public class EarthActivity extends Activity implements SeekBar.OnSeekBarChangeLi
       mPick.setEffectMode(mEffectNames[pos]);
       }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void onNothingSelected(AdapterView<?> parent) { }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     public void Remove(View v)
@@ -211,4 +198,10 @@ public class EarthActivity extends Activity implements SeekBar.OnSeekBarChangeLi
 
       return effectStrings;
       }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void onStartTrackingTouch(SeekBar bar) { }
+    public void onStopTrackingTouch(SeekBar bar)  { }
+    public void onNothingSelected(AdapterView<?> parent) { }
 }
diff --git a/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java b/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
index 32c3abd..da7733e 100644
--- a/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
+++ b/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
@@ -85,7 +85,7 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
       }
     
     rot.setCount(0);
-    rot.makeRunNowFor(8000);
+    rot.setDuration(8000);
     rot.setMode(Dynamic.MODE_LOOP);
 
     mMove   = new Static3D(0,0,0);
diff --git a/src/main/java/org/distorted/examples/rubik/RubikCube.java b/src/main/java/org/distorted/examples/rubik/RubikCube.java
index efa5ec2..3355af2 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikCube.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikCube.java
@@ -221,7 +221,8 @@ class RubikCube
              if( belongsToRotation(x,y,z,vector,rotRow) )
                {
                mRotationAxis[x][y][z].set(axis);
-               mRotationAngle[x][y][z].makeRunNowFor(ROTATION_MILLISEC);
+               mRotationAngle[x][y][z].setDuration(ROTATION_MILLISEC);
+               mRotationAngle[x][y][z].resetToBeginning();
                mRotationAngle[x][y][z].setPoint(1,90.0f);
 
                if( first )
diff --git a/src/main/java/org/distorted/examples/wind/WindEffectsManager.java b/src/main/java/org/distorted/examples/wind/WindEffectsManager.java
index 80ddee4..6d4e8f6 100644
--- a/src/main/java/org/distorted/examples/wind/WindEffectsManager.java
+++ b/src/main/java/org/distorted/examples/wind/WindEffectsManager.java
@@ -131,9 +131,9 @@ class WindEffectsManager
     shearFactor.set2(tanAngle);
     scaleFactor.set1(1/(float)Math.sqrt(1+tanAngle*tanAngle));
 
-    windDynamic1.makeRunNowFor( wind > 0 ? 900 + 10000/wind : Long.MAX_VALUE);
-    windDynamic2.makeRunNowFor( wind > 0 ? 720 +  8000/wind : Long.MAX_VALUE);
-    windDynamic3.makeRunNowFor( wind > 0 ? 900 + 10000/wind : Long.MAX_VALUE);
+    windDynamic1.setDuration( wind > 0 ? 900 + 10000/wind : Long.MAX_VALUE);
+    windDynamic2.setDuration( wind > 0 ? 720 +  8000/wind : Long.MAX_VALUE);
+    windDynamic3.setDuration( wind > 0 ? 900 + 10000/wind : Long.MAX_VALUE);
 
     float wave2 = mHeight*( 0.05f + 0.002f*wind);
     windFactor21.set1(wave2);
diff --git a/src/main/res/layout/dynamicslayout.xml b/src/main/res/layout/dynamicslayout.xml
index e246b69..4f1224b 100644
--- a/src/main/res/layout/dynamicslayout.xml
+++ b/src/main/res/layout/dynamicslayout.xml
@@ -6,116 +6,123 @@
     android:gravity="fill_horizontal"
     android:orientation="vertical" >
 
-    <org.distorted.examples.dynamic.DynamicSurfaceView
-        android:id="@+id/dynamicSurfaceView"
-        android:layout_width="fill_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1" />
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="48dp">
 
-        <RadioGroup
-            android:id="@+id/radioGroup2"
+        <Button
+            android:id="@+id/dynamicButtonStart"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:gravity="fill_horizontal"
-            android:orientation="horizontal"
-            android:paddingBottom="5dp"
-            android:paddingTop="5dp"
-            android:weightSum="1.0" >
-
-            <RadioButton
-                android:id="@+id/dynamic1D"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight="0.25"
-                android:onClick="Dim1D"
-                android:text="@string/dim1D" />
-
-            <RadioButton
-                android:id="@+id/dynamic2D"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight="0.25"
-                android:checked="true"
-                android:onClick="Dim2D"
-                android:text="@string/dim2D" />
-
-            <RadioButton
-                android:id="@+id/dynamic3DXY"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight="0.25"
-                android:onClick="Dim3DXY"
-                android:text="@string/dim3DXY" />
-
-            <RadioButton
-                android:id="@+id/dynamic3DXZ"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight="0.25"
-                android:onClick="Dim3DXZ"
-                android:text="@string/dim3DXZ" />
-
-        </RadioGroup>
+            android:layout_height="match_parent"
+            android:layout_weight="0.5"
+            android:paddingLeft="10dp"
+            android:paddingRight="10dp"
+            android:onClick="Start"
+            android:text="@string/start" />
 
-        <RadioGroup
-            android:id="@+id/radioGroup1"
+        <Button
+            android:id="@+id/dynamicButtonReset"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:paddingRight="20dp" >
-
-            <RadioButton
-                android:id="@+id/dynamicLoopButton"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:checked="true"
-                android:onClick="Loop"
-                android:text="@string/loop" />
+            android:layout_height="match_parent"
+            android:layout_weight="0.5"
+            android:paddingLeft="10dp"
+            android:paddingRight="10dp"
+            android:onClick="Reset"
+            android:text="@string/reset" />
+    </LinearLayout>
 
-            <RadioButton
-                android:id="@+id/dynamicPathButton"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:checked="false"
-                android:onClick="Path"
-                android:text="@string/path" />
+    <org.distorted.examples.dynamic.DynamicSurfaceView
+        android:id="@+id/dynamicSurfaceView"
+        android:layout_width="fill_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1" />
 
-            <RadioButton
-                android:id="@+id/dynamicJumpButton"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:checked="false"
-                android:onClick="Jump"
-                android:text="@string/jump" />
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="48dp">
+
+        <Spinner
+            android:layout_width="0dp"
+            android:layout_height="50dp"
+            android:layout_weight="0.5"
+            android:id="@+id/dynamicSpinnerDimension"/>
+
+        <Spinner
+            android:layout_width="0dp"
+            android:layout_height="50dp"
+            android:layout_weight="0.5"
+            android:id="@+id/dynamicSpinnerMode"/>
 
-        </RadioGroup>
+    </LinearLayout>
 
     <LinearLayout
-        android:id="@+id/linearLayout1"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
         android:gravity="center|fill_horizontal"
         android:orientation="vertical">
 
-        <TextView
-            android:id="@+id/dynamicTextDuration"
-            android:layout_width="wrap_content"
+        <LinearLayout
+            android:layout_width="fill_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal"
-            android:layout_weight="15"
-            android:paddingLeft="10dp"
-            android:text="@string/duration"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="12sp" />
+            android:orientation="horizontal"
+            android:baselineAligned="false">
 
-        <SeekBar
-            android:id="@+id/dynamicSeekDuration"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_weight="15"
-            android:paddingLeft="5dp"
-            android:paddingRight="10dp" />
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="fill_parent"
+                android:layout_weight="0.5"
+                android:layout_gravity="center_vertical"
+                android:gravity="center|fill_horizontal"
+                android:orientation="vertical">
+
+                <TextView
+                    android:id="@+id/dynamicTextDuration"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:text="@string/duration"
+                    android:textAppearance="?android:attr/textAppearanceMedium"
+                    android:textSize="12sp" />
+
+                <SeekBar
+                    android:id="@+id/dynamicSeekDuration"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingStart="10dp"
+                    android:paddingEnd="10dp" />
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="fill_parent"
+                android:layout_weight="0.5"
+                android:layout_gravity="center_vertical"
+                android:gravity="center|fill_horizontal"
+                android:orientation="vertical">
+
+                <TextView
+                    android:id="@+id/dynamicTextCount"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:text="@string/count"
+                    android:textAppearance="?android:attr/textAppearanceMedium"
+                    android:textSize="12sp" />
+
+                <SeekBar
+                    android:id="@+id/dynamicSeekCount"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingStart="5dp"
+                    android:paddingEnd="10dp" />
+
+            </LinearLayout>
+
+        </LinearLayout>
 
         <TextView
             android:id="@+id/dynamicTextNoise"
@@ -123,7 +130,6 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:layout_weight="15"
-            android:paddingLeft="10dp"
             android:text="@string/noise"
             android:textAppearance="?android:attr/textAppearanceMedium"
             android:textSize="12sp" />
@@ -139,8 +145,8 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
-                android:paddingLeft="5dp"
-                android:paddingRight="10dp" />
+                android:paddingLeft="10dp"
+                android:paddingRight="5dp" />
 
             <SeekBar
                 android:id="@+id/dynamicSeekNoise1"
@@ -148,7 +154,7 @@
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
                 android:paddingLeft="5dp"
-                android:paddingRight="10dp" />
+                android:paddingRight="5dp" />
 
             <SeekBar
                 android:id="@+id/dynamicSeekNoise2"
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 2999951..81e0aa7 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -82,6 +82,7 @@
     <string name="effect_finished">FINISHED </string>
     <string name="scramble">Scramble</string>
     <string name="credits">Credits</string>
+    <string name="start">Start</string>
 
     <string name="quality0">Highest</string>
     <string name="quality1">High</string>
@@ -114,6 +115,9 @@
     <string name="inflate_placeholder">Inflate: %1$.2f</string>
     <string name="effect_id_placeholder">ID: %1$d</string>
     <string name="rubik_placeholder">Cube: %1$d Available Memory: %2$d MB</string>
+    <string name="duration_placeholder">Duration: %1$d s</string>
+    <string name="count_placeholder">Count: %1$.2f</string>
+    <string name="noise2_placeholder">Noise: %1$.2f %2$.2f %3$.2f</string>
 
     <string name="example_monalisa">Mona Lisa</string>
     <string name="example_monalisa_subtitle">The basics of Distortions.</string>
