Tetris for the RA8875, derived from another users implementation.

Dependencies:   RA8875

Fork of Tetris by Sergejs Popovs

Tetris, adapted to the RA8875 graphics library and display.

As currently implemented, this version is defined for the 800x480 display. A number of macros can adapt it for other screen resolutions.

Further, while presently configured for landscape mode, it should be fairly easy to reconfigure it for portrait mode.

Files at this revision

API Documentation at this revision

Comitter:
WiredHome
Date:
Sat Aug 18 22:20:38 2018 +0000
Parent:
6:d2aa47c92687
Child:
8:6e28bd30cfb4
Commit message:
Rescaled for 480x272, and improved the touch processing.

Changed in this revision

RA8875.lib Show annotated file Show diff for this revision Revisions of this file
Tetris/Block.cpp Show annotated file Show diff for this revision Revisions of this file
Tetris/Block.h Show annotated file Show diff for this revision Revisions of this file
Tetris/Define.h Show annotated file Show diff for this revision Revisions of this file
Tetris/Piece.cpp Show annotated file Show diff for this revision Revisions of this file
Tetris/playGround.cpp Show annotated file Show diff for this revision Revisions of this file
Tetris/playGround.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show diff for this revision Revisions of this file
--- a/RA8875.lib	Sat Mar 18 23:53:12 2017 +0000
+++ b/RA8875.lib	Sat Aug 18 22:20:38 2018 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/WiredHome/code/RA8875/#2ec78a50dc98
+http://mbed.org/users/WiredHome/code/RA8875/#ad2450fc3dc3
--- a/Tetris/Block.cpp	Sat Mar 18 23:53:12 2017 +0000
+++ b/Tetris/Block.cpp	Sat Aug 18 22:20:38 2018 +0000
@@ -8,13 +8,18 @@
 
 //  Constructor of the object. Gives the random form and
 //  defines the position on the field
-
+//
 Block::Block()
 {
+#if 0
+    srand(clock());
+    form = rand() % 7;
+#else
     srand (clock());
     if (nextForm > 6)
         nextForm = (rand() + 1) % 7;
     form = nextForm;
+#endif
     nextForm = rand() % 7;
     angle = rand() % 4;
     x = 4 + rand() % 2;
@@ -22,14 +27,14 @@
 }
 
 //  Destructor of an object
-
+//
 Block::~Block()
 {
 }
 
 //  Check possibility of rotating of a block and
 //  rotate it if it is possible
-
+//
 void Block::rotateLeft()
 {
     if ( !CheckRotateLeft() )   {
@@ -52,7 +57,7 @@
 
 //  Check possibility of moving the block and
 //  moves it if it is possible
-
+//
 void Block::moveLeft()
 {
     if ( !CheckLeft() )
@@ -69,18 +74,21 @@
 //  blocks on the field ( separately ).
 //  Returns 1 if it is not possible and
 //          0 if it is possible.
-
+//
 bool Block::CheckBottom()
 {
     int xx, yy;
+
     for ( xx = 0 ; xx < 5 ; xx++ ) {
         for (yy = 0 ; yy < 5 ; yy++ )  {
             if ( (Piece[form][angle][xx][yy] != 0)
-                    && (Field[y + yy - 1][x + xx - 2] != 0) &&
-                    ( y + yy - 1 > 0 ) )
+            && (Field[y + yy - 1][x + xx - 2] != 0) 
+            && ( y + yy - 1 > 0 ) ) {
                 return 1;
-            if ( (Piece[form][angle][xx][yy] != 0) && ( yy + y == MAXY + 1 ) )
+            } else if ( (Piece[form][angle][xx][yy] != 0) 
+            && ( yy + y == MAXY + 1 ) ) {
                 return 1;
+            }
         }
     }
     return 0;
@@ -90,18 +98,21 @@
 //  blocks on the field ( separately ).
 //  Returns 1 if it is not possible and
 //          0 if it is possible.
-
+//
 bool Block::CheckLeft()
 {
     int xx, yy;
+
     for ( xx = 0 ; xx < 5 ; xx++ ) {
         for (yy = 0 ; yy < 5 ; yy++ )  {
             if ( (Piece[form][angle][xx][yy] != 0)
-                    && (Field[y + yy - 2][x + xx - 3] != 0) &&
-                    ( y + yy - 3 > 0 ) )
+            && (Field[y + yy - 2][x + xx - 3] != 0) 
+            && ( y + yy - 3 > 0 ) ) {
                 return 1;
-            if ( (Piece[form][angle][xx][yy] != 0) && ( xx + x == 2 )  )
+            } else if ( (Piece[form][angle][xx][yy] != 0) 
+            && ( xx + x == 2 ) ) {
                 return 1;
+            }
         }
     }
     return 0;
@@ -111,18 +122,21 @@
 //  blocks on the field ( separately ).
 //  Returns 1 if it is not possible and
 //          0 if it is possible.
-
+//
 bool Block::CheckRight()
 {
     int xx, yy;
+
     for ( xx = 0 ; xx < 5 ; xx++ ) {
         for (yy = 0 ; yy < 5 ; yy++ )  {
             if ( (Piece[form][angle][xx][yy] != 0)
-                    && (Field[y + yy - 2][x + xx - 1] != 0) &&
-                    ( y + yy - 3 > 0 ) )
+            && (Field[y + yy - 2][x + xx - 1] != 0) 
+            && ( y + yy - 3 > 0 ) ) {
                 return 1;
-            if ( (Piece[form][angle][xx][yy] != 0) && ( xx + x == MAXX + 1 )  )
+            } else if ( (Piece[form][angle][xx][yy] != 0) 
+            && ( xx + x == MAXX + 1 )  ) {
                 return 1;
+            }
         }
     }
     return 0;
@@ -132,18 +146,21 @@
 //  blocks on the field ( separately ).
 //  Returns 1 if it is not possible and
 //          0 if it is possible.
-
+//
 bool Block::CheckRotateLeft()
 {
     int xx, yy;
+
     for ( xx = 0 ; xx < 5 ; xx++ ) {
         for (yy = 0 ; yy < 5 ; yy++ )  {
             if ( (Piece[form][( abs(angle - 1) ) % 4][xx][yy] != 0)
-                    && (Field[y + yy - 1][x + xx - 2] != 0) &&
-                    ( y + yy - 3 > 0 ) )
+            && (Field[y + yy - 1][x + xx - 2] != 0) 
+            && ( y + yy - 3 > 0 ) ) {
                 return 1;
-            if ( (Piece[form][( abs(angle + 1) ) % 4][xx][yy] != 0) && (( xx + x == 1 ) || ( xx + x == MAXX + 1 ))  )
+            } else if ( (Piece[form][( abs(angle + 1) ) % 4][xx][yy] != 0) 
+            && (( xx + x == 1 ) || ( xx + x == MAXX + 1 )) ) {
                 return 1;
+            }
         }
     }
     return 0;
@@ -153,18 +170,21 @@
 //  blocks on the field ( separately ).
 //  Returns 1 if it is not possible and
 //          0 if it is possible.
-
+//
 bool Block::CheckRotateRight()
 {
     int xx, yy;
+    
     for ( xx = 0 ; xx < 5 ; xx++ ) {
         for (yy = 0 ; yy < 5 ; yy++ )  {
             if ( (Piece[form][( abs(angle + 1) ) % 4][xx][yy] != 0)
-                    && (Field[y + yy - 1][x + xx - 2] != 0) &&
-                    ( y + yy - 3 > 0 ) )
+            && (Field[y + yy - 1][x + xx - 2] != 0) 
+            && ( y + yy - 3 > 0 ) ) {
                 return 1;
-            if ( (Piece[form][( abs(angle + 1) ) % 4][xx][yy] != 0) && (( xx + x == 1 ) || ( xx + x == MAXX + 2 ))  )
+            } else if ( (Piece[form][( abs(angle + 1) ) % 4][xx][yy] != 0) 
+            && (( xx + x == 1 ) || ( xx + x == MAXX + 2 )) ) {
                 return 1;
+            }
         }
     }
     return 0;
--- a/Tetris/Block.h	Sat Mar 18 23:53:12 2017 +0000
+++ b/Tetris/Block.h	Sat Aug 18 22:20:38 2018 +0000
@@ -6,12 +6,8 @@
 public:
     Block();
     ~Block();
-    int form;
-    int nextForm;
-    int angle;
-    int x;
-    int y;
-    bool Active;
+    void moveLeft();
+    void moveRight();
     void rotateLeft();
     void rotateRight();
     bool CheckBottom();
@@ -19,8 +15,13 @@
     bool CheckRight();
     bool CheckRotateLeft();
     bool CheckRotateRight();
-    void moveLeft();
-    void moveRight();
+
+    unsigned char form;
+    unsigned char nextForm;
+    unsigned char angle;
+    int x;
+    int y;
+    bool Active;
 };
 
 #endif
\ No newline at end of file
--- a/Tetris/Define.h	Sat Mar 18 23:53:12 2017 +0000
+++ b/Tetris/Define.h	Sat Aug 18 22:20:38 2018 +0000
@@ -1,6 +1,25 @@
 //
 //  GAME AND DESIGN PARAMETERS
 
+// Define this for 800x480 panel, undefine for 480x272
+//#define BIG_SCREEN
+
+// Define this for Cap touch panel, undefine for resistive
+//#define CAP_TOUCH
+
+#ifdef BIG_SCREEN
+    #define LCD_W 800
+    #define LCD_H 480
+    #define LCD_C 8         // color - bits per pixel
+    #define BL_NORM 25      // Backlight Normal setting (0 to 255)
+#else
+    #define LCD_W 480
+    #define LCD_H 272
+    #define LCD_C 8         // color - bits per pixel
+    #define BL_NORM 25      // Backlight Normal setting (0 to 255)
+#endif
+
+
 // Title
 //
 // Score       (orig)            
@@ -25,24 +44,28 @@
 #define TITLE_X             0
 #define TITLE_Y             0
 
-#define SCORE_X             200
-#define SCORE_Y             50
+#define SCORE_X             LCD_W/8
+#define SCORE_Y             LCD_H/6
 
+#define PACE_X              LCD_W/8
+#define PACE_Y              7*LCD_H/8
+
+// Block Counts
 #define MAXX                10
 #define MAXY                12
-#define BLOCK_SIZE          25
+#define BLOCK_SIZE          ((int)(LCD_H/20))
 #define SPEED               100
-#define SMALL_BLOCK_SIZE    8
 
-#define ORIGIN_X            350
-#define ORIGIN_Y            50
+#define ORIGIN_X            ((int)(LCD_W/2))
+#define ORIGIN_Y            ((int)(LCD_H/6))
 
 // Small Block
-#define SB_X        ORIGIN_X+(MAXX-2)*BLOCK_SIZE
-#define SB_Y        ORIGIN_Y+(MAXY+3)*BLOCK_SIZE
+#define SB_X        ORIGIN_X+(MAXX+3)*BLOCK_SIZE
+#define SB_Y        ORIGIN_Y+(2)*BLOCK_SIZE
+#define SB_SIZE     8
 
-#define ROT_LEFT    ORIGIN_X+0,ORIGIN_Y+0,                              ORIGIN_X+4*BLOCK_SIZE,ORIGIN_Y+3*BLOCK_SIZE
-#define ROT_RIGHT   ORIGIN_X+(MAXX-2)*BLOCK_SIZE,ORIGIN_Y+0,            ORIGIN_X+(MAXX+2)*BLOCK_SIZE,ORIGIN_Y+3*BLOCK_SIZE
+#define ROT_RIGHT   ORIGIN_X+0,ORIGIN_Y+0,                              ORIGIN_X+4*BLOCK_SIZE,ORIGIN_Y+3*BLOCK_SIZE
+#define ROT_LEFT    ORIGIN_X+(MAXX-2)*BLOCK_SIZE,ORIGIN_Y+0,            ORIGIN_X+(MAXX+2)*BLOCK_SIZE,ORIGIN_Y+3*BLOCK_SIZE
 #define MOV_LEFT    ORIGIN_X+0,ORIGIN_Y+4*BLOCK_SIZE,                   ORIGIN_X+4*BLOCK_SIZE,ORIGIN_Y+(MAXY-1)*BLOCK_SIZE
 #define MOV_RIGHT   ORIGIN_X+(MAXX-2)*BLOCK_SIZE,ORIGIN_Y+4*BLOCK_SIZE, ORIGIN_X+(MAXX+2)*BLOCK_SIZE,ORIGIN_Y+(MAXY-1)*BLOCK_SIZE
 #define DROP        ORIGIN_X+0,ORIGIN_Y+MAXY*BLOCK_SIZE,                ORIGIN_X+(MAXX+2)*BLOCK_SIZE,ORIGIN_Y+(MAXY+4)*BLOCK_SIZE
--- a/Tetris/Piece.cpp	Sat Mar 18 23:53:12 2017 +0000
+++ b/Tetris/Piece.cpp	Sat Aug 18 22:20:38 2018 +0000
@@ -8,223 +8,223 @@
 const int Piece [ 7 ][ 4 ][ 5 ][ 5 ] = {
     {
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, Blue, Blue, 0},
-            {0, 0, Blue, Blue, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Blue, Blue,   0},
+            {   0,   0, Blue, Blue,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, Blue, Blue, 0},
-            {0, 0, Blue, Blue, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Blue, Blue,   0},
+            {   0,   0, Blue, Blue,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, Blue, Blue, 0},
-            {0, 0, Blue, Blue, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Blue, Blue,   0},
+            {   0,   0, Blue, Blue,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, Blue, Blue, 0},
-            {0, 0, Blue, Blue, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Blue, Blue,   0},
+            {   0,   0, Blue, Blue,   0},
+            {   0,   0,   0,   0,   0}
         }
     },
 
 // I
     {
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {Green, Green, Green, Green, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {Green, Green, Green, Green,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, Green, 0, 0},
-            {0, 0, Green, 0, 0},
-            {0, 0, Green, 0, 0},
-            {0, 0, Green, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0, Green,   0,   0},
+            {   0,   0, Green,   0,   0},
+            {   0,   0, Green,   0,   0},
+            {   0,   0, Green,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {Green, Green, Green, Green, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {Green, Green, Green, Green,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, Green, 0, 0},
-            {0, 0, Green, 0, 0},
-            {0, 0, Green, 0, 0},
-            {0, 0, Green, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0, Green,   0,   0},
+            {   0,   0, Green,   0,   0},
+            {   0,   0, Green,   0,   0},
+            {   0,   0, Green,   0,   0},
+            {   0,   0,   0,   0,   0}
         }
     }
     ,
 // L
     {
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, Red, 0, 0},
-            {0, 0, Red, 0, 0},
-            {0, 0, Red, Red, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Red,   0,   0},
+            {   0,   0, Red,   0,   0},
+            {   0,   0, Red, Red,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {0, Red, Red, Red, 0},
-            {0, Red, 0, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {   0, Red, Red, Red,   0},
+            {   0, Red,   0,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, Red, Red, 0, 0},
-            {0, 0, Red, 0, 0},
-            {0, 0, Red, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0, Red, Red,   0,   0},
+            {   0,   0, Red,   0,   0},
+            {   0,   0, Red,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, Red, 0},
-            {0, Red, Red, Red, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0, Red,   0},
+            {   0, Red, Red, Red,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0}
         }
     },
 // L mirrored
     {
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, Yellow, 0, 0},
-            {0, 0, Yellow, 0, 0},
-            {0, Yellow, Yellow, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Yellow,   0,   0},
+            {   0,   0, Yellow,   0,   0},
+            {   0, Yellow, Yellow,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, Yellow, 0, 0, 0},
-            {0, Yellow, Yellow, Yellow, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0, Yellow,   0,   0,   0},
+            {   0, Yellow, Yellow, Yellow,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, Yellow, Yellow, 0},
-            {0, 0, Yellow, 0, 0},
-            {0, 0, Yellow, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Yellow, Yellow,   0},
+            {   0,   0, Yellow,   0,   0},
+            {   0,   0, Yellow,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {0, Yellow, Yellow, Yellow, 0},
-            {0, 0, 0, Yellow, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {   0, Yellow, Yellow, Yellow,   0},
+            {   0,   0,   0, Yellow,   0},
+            {   0,   0,   0,   0,   0}
         }
     },
 // N
     {
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, Orange, 0},
-            {0, 0, Orange, Orange, 0},
-            {0, 0, Orange, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0, Orange,   0},
+            {   0,   0, Orange, Orange,   0},
+            {   0,   0, Orange,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {0, Orange, Orange, 0, 0},
-            {0, 0, Orange, Orange, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {   0, Orange, Orange,   0,   0},
+            {   0,   0, Orange, Orange,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, Orange, 0, 0},
-            {0, Orange, Orange, 0, 0},
-            {0, Orange, 0, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Orange,   0,   0},
+            {   0, Orange, Orange,   0,   0},
+            {   0, Orange,   0,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
 
 
 
         {
-            {0, 0, 0, 0, 0},
-            {0, Orange, Orange, 0, 0},
-            {0, 0, Orange, Orange, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0, Orange, Orange,   0,   0},
+            {   0,   0, Orange, Orange,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0}
         }
     },
 // N mirrored
     {
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, GreenYellow, 0, 0},
-            {0, 0, GreenYellow, GreenYellow, 0},
-            {0, 0, 0, GreenYellow, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0, GreenYellow,   0,   0},
+            {   0,   0, GreenYellow, GreenYellow,   0},
+            {   0,   0,   0, GreenYellow,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, GreenYellow, GreenYellow, 0},
-            {0, GreenYellow, GreenYellow, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0, GreenYellow, GreenYellow,   0},
+            {   0, GreenYellow, GreenYellow,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, GreenYellow, 0, 0, 0},
-            {0, GreenYellow, GreenYellow, 0, 0},
-            {0, 0, GreenYellow, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0, GreenYellow,   0,   0,   0},
+            {   0, GreenYellow, GreenYellow,   0,   0},
+            {   0,   0, GreenYellow,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, GreenYellow, GreenYellow, 0},
-            {0, GreenYellow, GreenYellow, 0, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0, GreenYellow, GreenYellow,   0},
+            {   0, GreenYellow, GreenYellow,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0}
         }
     },
 // T
     {
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, Magenta, 0, 0},
-            {0, 0, Magenta, Magenta, 0},
-            {0, 0, Magenta, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Magenta,   0,   0},
+            {   0,   0, Magenta, Magenta,   0},
+            {   0,   0, Magenta,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0},
-            {0, Magenta, Magenta, Magenta, 0},
-            {0, 0, Magenta, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0},
+            {   0, Magenta, Magenta, Magenta,   0},
+            {   0,   0, Magenta,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, Magenta, 0, 0},
-            {0, Magenta, Magenta, 0, 0},
-            {0, 0, Magenta, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Magenta,   0,   0},
+            {   0, Magenta, Magenta,   0,   0},
+            {   0,   0, Magenta,   0,   0},
+            {   0,   0,   0,   0,   0}
         },
         {
-            {0, 0, 0, 0, 0},
-            {0, 0, Magenta, 0, 0},
-            {0, Magenta, Magenta, Magenta, 0},
-            {0, 0, 0, 0, 0},
-            {0, 0, 0, 0, 0}
+            {   0,   0,   0,   0,   0},
+            {   0,   0, Magenta,   0,   0},
+            {   0, Magenta, Magenta, Magenta,   0},
+            {   0,   0,   0,   0,   0},
+            {   0,   0,   0,   0,   0}
         }
     }
 };
\ No newline at end of file
--- a/Tetris/playGround.cpp	Sat Mar 18 23:53:12 2017 +0000
+++ b/Tetris/playGround.cpp	Sat Aug 18 22:20:38 2018 +0000
@@ -8,31 +8,12 @@
 #include "Define.h"
 #include <ctime>
 
-// Define this for 800x480 panel, undefine for 480x272
-#define BIG_SCREEN
-
-// Define this for Cap touch panel, undefine for resistive
-#define CAP_TOUCH
-
 #ifdef CAP_TOUCH
 RA8875 TFT(p5,p6,p7,p12,NC, p9,p10,p13, "tft"); // SPI:{MOSI,MISO,SCK,/ChipSelect,/reset}, I2C:{SDA,SCL,/IRQ}, name
 #else
 RA8875 TFT(p5,p6,p7,p12,NC, "tft");             // SPI:{MOSI,MISO,SCK,/ChipSelect,/reset}, name
 #endif
 
-#ifdef BIG_SCREEN
-    #define LCD_W 800
-    #define LCD_H 480
-    #define LCD_C 8         // color - bits per pixel
-    #define BL_NORM 25      // Backlight Normal setting (0 to 255)
-#else
-    #define LCD_W 480
-    #define LCD_H 272
-    #define LCD_C 8         // color - bits per pixel
-    #define BL_NORM 25      // Backlight Normal setting (0 to 255)
-#endif
-
-
 // Hot-Spots
 static const rect_t Drop   = { DROP };
 static const rect_t rLeft  = { ROT_LEFT };
@@ -40,10 +21,23 @@
 static const rect_t mLeft  = { MOV_LEFT };
 static const rect_t mRight = { MOV_RIGHT };
 static const rect_t Replay = { REPLAY };
+static const point_t orig  = {ORIGIN_X,ORIGIN_Y};
+static const point_t sb_orig = {SB_X, SB_Y};
+// Convert cell coordinates to a rectangle location
+//
+rect_t CellPosToRect(int x, int y, point_t o = orig, int bs = BLOCK_SIZE) {
+    rect_t r;
+    
+    r.p1.x = o.x + bs * (x + 1);
+    r.p1.y = o.y + bs * (y + 0);
+    r.p2.x = o.x + bs * (x + 2);
+    r.p2.y = o.y + bs * (y + 1);
+    return r;
+}
 
 //  Draws Field on the screen. Draw both black and colored blocks
 //  It does delete everything on the PlayGround what shouldn't be there
-
+//
 void drawMap()
 {
     int y, x;
@@ -51,39 +45,34 @@
     for ( y = 0 ; y < MAXY ; y++ ) {
         for ( x = 0 ; x < MAXX ; x++ ) {
             if ( Field[y][x] != 0 ) {
-                TFT.fillrect(ORIGIN_X + BLOCK_SIZE * ( x + 1 ), ORIGIN_Y + BLOCK_SIZE * y,
-                             ORIGIN_X + BLOCK_SIZE * ( x + 2 ), ORIGIN_Y + BLOCK_SIZE * ( y + 1 ),
-                             Field[y][x]);
-                TFT.rect(ORIGIN_X + BLOCK_SIZE * ( x + 1 ), ORIGIN_Y + BLOCK_SIZE * y,
-                         ORIGIN_X + BLOCK_SIZE * ( x + 2 ), ORIGIN_Y + BLOCK_SIZE * ( y + 1 ),
-                         White );
+                rect_t r = CellPosToRect(x,y);
+                TFT.fillrect(r, Field[y][x]);
+                TFT.rect(r, White );
             }
         }
     }
 }
 
+
 //  Draws Field on the screen. Draw only colored blocks
 //  It doesn't delete anything on the playground what shouldn't be there
-
+//
 void drawMapV2()
 {
     int y , x;
 
     for ( y = 0 ; y < MAXY ; y++ ) {
         for ( x = 0 ; x < MAXX ; x++ ) {
-            TFT.fillrect(ORIGIN_X + BLOCK_SIZE * ( x + 1 ), ORIGIN_Y + BLOCK_SIZE * y,
-                         ORIGIN_X + BLOCK_SIZE * ( x + 2 ), ORIGIN_Y + BLOCK_SIZE * ( y + 1 ),
-                         Field[y][x]);
+            rect_t r = CellPosToRect(x,y);
+            TFT.fillrect(r, Field[y][x]);
             if ( Field[y][x] != 0 )
-                TFT.rect(ORIGIN_X + BLOCK_SIZE * ( x + 1 ), ORIGIN_Y + BLOCK_SIZE * y,
-                         ORIGIN_X + BLOCK_SIZE * ( x + 2 ), ORIGIN_Y + BLOCK_SIZE * ( y + 1 ),
-                         White );
+                TFT.rect(r, White );
         }
     }
 }
 
 //  Draws NewBlock on the playground. 
-
+//
 void drawBlock(Block NewBlock)
 {
     int ix , iy , x , y;
@@ -92,19 +81,16 @@
     for ( ix = x - 2 ; ix < x + 2 ; ix++ ) {
         for ( iy = y - 2 ; iy < y + 2 ; iy++ ) {
             if ( Piece[NewBlock.form][NewBlock.angle][ix - x + 2][iy - y + 2] != 0 ) {
-                TFT.fillrect(ORIGIN_X + BLOCK_SIZE * ( ix + 1 ), ORIGIN_Y + BLOCK_SIZE * iy,
-                             ORIGIN_X + BLOCK_SIZE * ( ix + 2 ), ORIGIN_Y + BLOCK_SIZE * ( iy + 1 ),
-                             Piece[NewBlock.form][NewBlock.angle][ix - x + 2][iy - y + 2]);
-                TFT.rect(ORIGIN_X + BLOCK_SIZE * ( ix + 1 ), ORIGIN_Y + BLOCK_SIZE * iy,
-                         ORIGIN_X + BLOCK_SIZE * ( ix + 2 ), ORIGIN_Y + BLOCK_SIZE * ( iy + 1 ),
-                         White );
+                rect_t r = CellPosToRect(ix,iy);
+                TFT.fillrect(r, Piece[NewBlock.form][NewBlock.angle][ix - x + 2][iy - y + 2]);
+                TFT.rect(r, White );
             }
         }
     }
 }
 
 //  Removes NewBlock from the playground. 
-
+//
 void clrBlock(Block NewBlock)
 {
     int ix , iy , x , y;
@@ -113,34 +99,41 @@
     for ( ix = x - 2 ; ix < x + 2 ; ix++ ) {
         for ( iy = y - 2 ; iy < y + 2 ; iy++ ) {
             if ( Piece[NewBlock.form][NewBlock.angle][ix - x + 2][iy - y + 2] != 0 ) {
-                TFT.fillrect(ORIGIN_X + BLOCK_SIZE * ( ix + 1 ), ORIGIN_Y + BLOCK_SIZE * iy,
-                             ORIGIN_X + BLOCK_SIZE * ( ix + 2 ), ORIGIN_Y + BLOCK_SIZE * ( iy + 1 ),
-                             Black );
+                rect_t r = CellPosToRect(ix,iy);
+                TFT.fillrect(r, Black );
             }
         }
     }
 }
 
+
 //  Draws Purple frame around playground
-
+//
 void drawFrame()
 {
     int x, y;
-    for ( y = 0 ; y < (MAXY + 1) * BLOCK_SIZE ; y += BLOCK_SIZE ) {
-        TFT.fillrect(ORIGIN_X + 0, ORIGIN_Y + y, ORIGIN_X + BLOCK_SIZE, ORIGIN_Y + y + BLOCK_SIZE, Purple );
-        TFT.rect(ORIGIN_X + 0, ORIGIN_Y + y, ORIGIN_X + BLOCK_SIZE, ORIGIN_Y + y + BLOCK_SIZE, DarkGray );
-        TFT.fillrect(ORIGIN_X + (MAXX + 1) * BLOCK_SIZE, ORIGIN_Y + y, ORIGIN_X + (MAXX + 2) * BLOCK_SIZE, ORIGIN_Y + y + BLOCK_SIZE, Purple );
-        TFT.rect(ORIGIN_X + (MAXX + 1) * BLOCK_SIZE, ORIGIN_Y + y, ORIGIN_X + (MAXX + 2) * BLOCK_SIZE, ORIGIN_Y + y + BLOCK_SIZE, DarkGray );
+
+    for ( y = 0 ; y < (MAXY) ; y++ ) {
+        rect_t r = CellPosToRect(-1,y);
+
+        TFT.fillrect(r, Purple );
+        TFT.rect(r, DarkGray );
+        r = CellPosToRect(MAXX,y);
+        TFT.fillrect(r, Purple );
+        TFT.rect(r, DarkGray );
     }
-    for ( x = 0 ; x < (MAXX + 2) * BLOCK_SIZE ; x += BLOCK_SIZE ) {
-        TFT.fillrect(ORIGIN_X + x, ORIGIN_Y + MAXY * BLOCK_SIZE, ORIGIN_X + x + BLOCK_SIZE, ORIGIN_Y + (MAXY + 1) * BLOCK_SIZE, Purple );
-        TFT.rect(ORIGIN_X + x, ORIGIN_Y + MAXY * BLOCK_SIZE, ORIGIN_X + x + BLOCK_SIZE, ORIGIN_Y + (MAXY + 1) * BLOCK_SIZE, DarkGray );
+    for ( x = -1 ; x < (MAXX + 1) ; x++ ) {
+        rect_t r = CellPosToRect(x,MAXY);
+
+        TFT.fillrect(r, Purple );
+        TFT.rect(r, DarkGray );
     }
 }
 
+
 //  Initializes screen parameters, sets orentation, background,
 //  fonts and cleans screen.
-
+//
 void TFTInit()
 {
     TFT.init(LCD_W,LCD_H,LCD_C);
@@ -149,6 +142,7 @@
     TFT.SetOrientation();
 }
 
+
 void ReInitGame() {
     TFT.foreground(White);
     TFT.background(Black);
@@ -171,19 +165,23 @@
             Field[y][x] = 0;
         }
     }
+    drawFrame();
+    drawMap();
 }
 
+
 void gameOver(int score)
 {
     drawScore(score);
     TFT.fillrect(Replay, Blue);
     TFT.rect(Replay, White);
-    TFT.SetTextCursor(Replay.p1.x+15,(Replay.p1.y+Replay.p2.y)/2-TFT.fontheight()/2);
     TFT.foreground(White);
     TFT.background(Blue);
-    TFT.puts("Replay");
+    TFT.SetTextCursor((Replay.p1.x+Replay.p2.x)/2-7*TFT.fontwidth()/2,(Replay.p1.y+Replay.p2.y)/2-TFT.fontheight()/2);
+    TFT.puts("Replay?");
 }
 
+
 bool ReplayTouched() {
     point_t p;
     
@@ -193,6 +191,14 @@
         return false;
 }
 
+void drawPeriod(int period)
+{
+    TFT.SelectUserFont(BPG_Arial10x10);
+    TFT.SetTextCursor(PACE_X, PACE_Y);
+    TFT.foreground(Brown);
+    TFT.printf("Pace : %i", period);    
+}
+
 void drawScore(int score)
 {
     TFT.SelectUserFont(BPG_Arial20x20);
@@ -206,55 +212,38 @@
 //  Returns         :   0 for dropping object down
 //                      1 for moving object to the right
 //                      2 for moving object to the left
-//                      3 for rotating object counter-clockwise
-//                      4 for rotating objec clockwise
-int getGesture()
+//                      3 for rotating objec clockwise
+//                      4 for rotating object counter-clockwise
+//                      13 for ignore
+gesture_t getGesture(point_t p)
 {
-    point_t p;
-    clock_t start_s = clock();
-    int flag = 0;
-    while( !flag ) {
-        p.x=0;
-        p.y=0;
-        TouchCode_t t = TFT.TouchCode();
-        if ( t == touch || t == held ) {
-            p = TFT.TouchCoordinates();            // read analog pos.
-            flag = 1;
-        } else if ( start_s > 10 )
-            return 13;
+    gesture_t gesture = ignore;
+
+    if (TFT.Intersect(Drop,p) ) {      // below the bottom to drop
+        gesture = drop;
+    } else if (TFT.Intersect(rLeft, p) ) {
+        return spin_ccw;
+    } else if (TFT.Intersect(rRight, p) ) {
+        return spin_cw;
+    } else if (TFT.Intersect(mLeft, p) ) {
+        return move_left;
+    } else if (TFT.Intersect(mRight, p) ) {
+        return move_right;
     }
-    if ( TFT.Intersect(Drop,p) ) {      // below the bottom to drop
-        return 0 ;
-    } else if ( TFT.Intersect(rLeft, p) ) {
-        return 3;
-    } else if ( TFT.Intersect(rRight, p) ) {
-        return 4;
-    } else if ( TFT.Intersect(mLeft, p) ) {
-        return 2;
-    } else if ( TFT.Intersect(mRight, p) ) {
-        return 1;
-    }
-    return 13;         //13 = IGNORE
+    return gesture;
 }
 
-//  Returns status of screen. If it was touched returns true, else false
 
-bool TouchStatus()
-{
-    if ( TFT.TouchPanelReadable() )
-        return true;
-    return false;
-}
 
 //  Moves NewBlock acording the gesture was read by function getGesture.
-
-Block doGest(Block NewBlock)
+//
+Block doGest(Block NewBlock, point_t p)
 {
     static bool lockout = false;
-    int gest = getGesture();
-    if ( gest != 13 ) {
+    gesture_t gest = getGesture(p);
+    if ( gest != ignore ) {
         switch ( gest ) {
-            case 0: {
+            case drop: {
                 while ( !NewBlock.CheckBottom() ) {
                     NewBlock.y++;
                 }
@@ -263,26 +252,24 @@
                 lockout = false;
                 break;
             }
-            case 1: {
+            case move_right: {
                 NewBlock.moveRight();
                 lockout = false;
                 break;
             }
-            case 2: {
+            case move_left: {
                 NewBlock.moveLeft();
                 lockout = false;
                 break;
             }
-            case 3: {
+            case spin_ccw: {
                 if (!lockout) {
-                    lockout = true;
                     NewBlock.rotateLeft();
                 }
                 break;
             }
-            case 4: {
+            case spin_cw: {
                 if (!lockout) {
-                    lockout = true;
                     NewBlock.rotateRight();
                 }
                 break;
@@ -295,36 +282,34 @@
 }
 
 
-//  Draws the next block on the bottom of the screen. 
-//  Block is sized of SMALL_BLOCK_SIZED
+//  Draws the next block on the screen. 
+//  Block is sized of SB_SIZE
 
 void drawNextBlock(Block NewBlock)
 {
     int ix, iy;
 
-    for ( ix = - 2 ; ix < 2 ; ix++ ) {
-        for ( iy = - 2 ; iy < 2 ; iy++ ) {
-            rect_t r;
+    for ( ix = 0 ; ix < 4 ; ix++ ) {
+        for ( iy = 0 ; iy < 4 ; iy++ ) {
+            rect_t r = CellPosToRect(ix,iy, sb_orig, SB_SIZE);
 
-            r.p1.x = SB_X - 2 * SMALL_BLOCK_SIZE + SMALL_BLOCK_SIZE * ( ix + 1 );
-            r.p1.y = SB_Y - 2 * SMALL_BLOCK_SIZE + SMALL_BLOCK_SIZE * iy;
-            r.p2.x = SB_X - 2 * SMALL_BLOCK_SIZE + SMALL_BLOCK_SIZE * ( ix + 2 );
-            r.p2.y = SB_Y - 2 * SMALL_BLOCK_SIZE + SMALL_BLOCK_SIZE * ( iy + 1 );
-            if ( Piece[NewBlock.nextForm][NewBlock.angle][ix + 2][iy + 2] != 0 ) {
-                TFT.fillrect(r, Piece[NewBlock.nextForm][NewBlock.angle][ix + 2][iy + 2]);
+            if ( Piece[NewBlock.nextForm][NewBlock.angle][ix][iy] != 0 ) {
+                TFT.fillrect(r, Piece[NewBlock.nextForm][NewBlock.angle][ix][iy]);
                 TFT.rect(r, White );
             }
         }
     }
 }
 
+
+//  Clear the Next Block indicator
+//
 void clrNextBlock(Block NewBlock)
 {
+    rect_t r0 = CellPosToRect(0,0, sb_orig, SB_SIZE);
+    rect_t r1 = CellPosToRect(3,3, sb_orig, SB_SIZE);
     rect_t r;
-    
-    r.p1.x = SB_X - 2 * SMALL_BLOCK_SIZE + SMALL_BLOCK_SIZE * ( -2 + 1 );
-    r.p1.y = SB_Y - 2 * SMALL_BLOCK_SIZE + SMALL_BLOCK_SIZE * -2;
-    r.p2.x = SB_X - 2 * SMALL_BLOCK_SIZE + SMALL_BLOCK_SIZE * ( 1 + 2 );
-    r.p2.y = SB_Y - 2 * SMALL_BLOCK_SIZE + SMALL_BLOCK_SIZE * ( 1 + 1 );
+    r.p1 = r0.p1;
+    r.p2 = r1.p2;
     TFT.fillrect( r, Black );
 }
--- a/Tetris/playGround.h	Sat Mar 18 23:53:12 2017 +0000
+++ b/Tetris/playGround.h	Sat Aug 18 22:20:38 2018 +0000
@@ -1,9 +1,25 @@
+#ifndef PLAYGROUND_H
+#define PLAYGROUND_H
+
+
 #include "mbed.h"
 #include "RA8875.h"
 #include "Block.h"
 #include "Define.h"
 #include "Field.h"
 
+typedef enum {
+    drop = 0,
+    move_right = 1,
+    move_left = 2,
+    spin_cw = 3,
+    spin_ccw = 4,
+    ignore = 13
+} gesture_t;
+
+extern RA8875 TFT;
+extern RawSerial pc;
+
 void TFTInit();
 void ReInitGame();
 bool ReplayTouched();
@@ -12,10 +28,12 @@
 void drawBlock(Block NewBlock);
 void drawFrame();
 void clrBlock(Block NewBlock);
-int getGesture();
-bool TouchStatus();
-Block doGest(Block NewBlock);
+gesture_t getGesture();
+Block doGest(Block NewBlock, point_t p);
 void gameOver(int score);
 void drawScore(int score);
+void drawPeriod(int period);
 void drawNextBlock(Block NewBlock);
-void clrNextBlock(Block NewBlock);
\ No newline at end of file
+void clrNextBlock(Block NewBlock);
+
+#endif // PLAYGROUND_H
--- a/main.cpp	Sat Mar 18 23:53:12 2017 +0000
+++ b/main.cpp	Sat Aug 18 22:20:38 2018 +0000
@@ -10,18 +10,70 @@
 #include <ctime>
 #include "playGround.h"
 
-Serial pc(USBTX, USBRX);    // Not required for display
+LocalFileSystem local("local");
+RawSerial pc(USBTX, USBRX);    // Not required for display
+Timer tSinceTouch;
+
+// Calibrate the resistive touch screen, and store the data on the
+// local file system.
+//
+void CalibrateTS(void)
+{
+    FILE * fh;
+    tpMatrix_t matrix;
+    RetCode_t r;
+    Timer testperiod;
+ 
+    r = TFT.TouchPanelCalibrate("Calibrate the touch panel", &matrix);
+    if (r == noerror) {
+        fh = fopen("/local/tpcal.cfg", "wb");
+        if (fh) {
+            fwrite(&matrix, sizeof(tpMatrix_t), 1, fh);
+            fclose(fh);
+            printf("  tp cal written.\r\n");
+            TFT.cls();
+        } else {
+            printf("  couldn't open tpcal file.\r\n");
+        }
+    } else {
+        printf("error return: %d\r\n", r);
+    }
+    TFT.cls();
+}
+
+// Try to load a previous resistive touch screen calibration from storage. If it
+// doesn't exist, activate the touch screen calibration process.
+//
+void InitTS(void)
+{
+    FILE * fh;
+    tpMatrix_t matrix;
+
+    fh = fopen("/local/tpcal.cfg", "rb");
+    if (fh) {
+        fread(&matrix, sizeof(tpMatrix_t), 1, fh);
+        fclose(fh);
+        TFT.TouchPanelSetMatrix(&matrix);
+        printf("  tp cal loaded.\r\n");
+    } else {
+        CalibrateTS();
+    }
+}
+
 
 int main()
 {
     int score = 0;
     int period = SPEED;
-    bool flag;
+    bool bottomedOut;
     clock_t start_s;
     pc.baud(460800);    //I like a snappy terminal, so crank it up!
     pc.printf("\r\nTetris - Build " __DATE__ " " __TIME__ "\r\n");
     int playState = 0;  // 0=init, 1=newBlock, 2=game over
     TFTInit();
+    #ifndef CAP_TOUCH
+    InitTS();               // resistive touch calibration
+    #endif
 
     while (1) {
         switch (playState) {
@@ -29,31 +81,60 @@
                 score = 0;
                 period = SPEED;
                 ReInitGame();
-                drawFrame();
-                drawMap();
-                playState++;
+                playState = 10;
                 // break;   // fall thru
             }
-            case 1: {
+            case 10: {
                 Block NewBlock;
-                flag = false;
+                bottomedOut = false;
                 drawScore(score);
+                drawPeriod(period);
                 drawNextBlock(NewBlock);
-                while( !flag ) {
+                while( !bottomedOut ) {
                     drawMap();
                     drawBlock(NewBlock);
                     start_s = clock();
-                    while( start_s + period > clock() ) {
-                        if ( TouchStatus() )    {
-                            clrBlock(NewBlock);
-                            NewBlock = doGest(NewBlock);
-                            drawBlock(NewBlock);
-                            wait_ms(80);
+                    while( (clock() - start_s) < period ) {
+                        point_t p;
+                        TouchCode_t panel = TFT.TouchPanelReadable(&p);
+                        switch (panel) {
+                            case touch:
+                                //printf("Touch %4d (%d,%d)\r\n", panel, p.x, p.y);
+                                tSinceTouch.start();
+                                clrBlock(NewBlock);
+                                NewBlock = doGest(NewBlock, p);
+                                drawBlock(NewBlock);
+                                break;
+                            case held:
+                                if (tSinceTouch.read_ms() > 300) {
+                                    tSinceTouch.reset();
+                                    tSinceTouch.start();
+                                    clrBlock(NewBlock);
+                                    NewBlock = doGest(NewBlock, p);
+                                    drawBlock(NewBlock);
+                                    //printf("Held  %4d (%d,%d)\r\n", tSinceTouch.read_ms(), p.x,p.y);
+                                } else {
+                                    p.x = 0; p.y = 0;
+                                    //printf("held  %4d (%d,%d)\r", tSinceTouch.read_ms(), p.x,p.y);
+                                }
+                                break;
+                            case release:
+                                //printf("\r\nstop - release\r\n");
+                                tSinceTouch.stop();
+                                break;
+                            case no_touch:
+                                //printf("stop - no_touch\r\n");
+                                tSinceTouch.stop();
+                                break;
+                            default:
+                                //printf("\r\nstop - dunno\r\n");
+                                tSinceTouch.stop();
+                                break;
                         }
                     }
                     if ( NewBlock.CheckBottom() ) {
                         saveToField(NewBlock);
-                        flag = true;
+                        bottomedOut = true;
                     } else {
                         clrBlock(NewBlock);
                         NewBlock.y += 1;
@@ -65,12 +146,12 @@
                     period = SPEED - score / 50;
                 clrNextBlock(NewBlock);
                 if ( checkGameOver() ) {
-                    playState++;
+                    playState = 20;
                     gameOver(score);
                 }
                 break;
             }
-            case 2: {
+            case 20: {
                 if (ReplayTouched()) {
                     playState = 0;     // restart
                     break;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Sat Aug 18 22:20:38 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#f8b140f8d7cb226e41486c5df66ac4f3ce699219
--- a/mbed.bld	Sat Mar 18 23:53:12 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/f9eeca106725
\ No newline at end of file