I simplified the library "ILI9225_TFT" provided by Arman Safikhani to better suit my needs in implementing a simple sliding puzzle game.

Revision:
3:251e4d020501
diff -r cc93245bb6d0 -r 251e4d020501 States.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/States.h	Fri Apr 27 07:33:56 2018 +0000
@@ -0,0 +1,193 @@
+#include "Fonts.h"
+
+//STATE 0
+//GLCD Displays the start screen - encouraging the player to start the game
+//by displaying the message "PRESS SELECT TO START".
+//
+//Player must press the SELECT button to trigger the next STATE.
+void greetingScreen() {
+    tft.clear();
+    tft.setFont(Terminal12x16);
+    tft.drawText(60, 40, "PRESS", COLOR_RED);
+    tft.drawText(54, 65, "SELECT", COLOR_RED);
+    tft.drawText(77, 90, "TO", COLOR_RED);
+    tft.drawText(60, 115, "START", COLOR_RED);
+    
+    while(1) {
+        if(getPlayerInput(wirelessInput_Freq) == 6) //SELECT -> 6
+            return;
+    }
+}
+
+//STATE 1
+//GLCD encourages player to take a picture of something by displaying the
+//message "SELECT TO TAKE PICTURE".
+//
+//Player must press the SELECT button to take a picture and trigger the next
+//STATE.
+void takePicture() {
+    tft.clear();
+    tft.setFont(Terminal12x16);
+    tft.drawText(54, 40, "SELECT", COLOR_RED);
+    tft.drawText(77, 65, "TO", COLOR_RED);
+    tft.drawText(65, 90, "TAKE", COLOR_RED);
+    tft.drawText(50, 115, "PICTURE", COLOR_RED);
+    
+    while(1) {
+        if(getPlayerInput(wirelessInput_Freq) == 6) { //SELECT -> 6
+            for(int index = 0; index < 19200; index++)
+                handlePixel(index, getNextPixel());
+            return;
+        }
+    }
+}
+
+//STATE 2
+//GLCD will display the picture taken in STATE 1 @ the bottom of the screen.
+//
+//Player input is ignored during this STATE.
+void previewPicture() {
+    tft.clear();
+    updatePuzzle();
+}
+
+//STATE 3
+//GLCD will display the message "SELECT > ACCEPT" atop "OR" atop
+//"CANCEL > RETAKE" at the top of the screen.
+//
+//Player may press SELECT to continue (STATE 4) w| picture or CANCEL to retake
+//the picture (STATE 1).
+bool confirmPicture() {
+    tft.fillRectangle(0, 0, 175, 91, COLOR_BLACK);
+    tft.setFont(Terminal12x16);
+    tft.drawText(4, 8, "SELECT > ACCEPT", COLOR_RED);
+    tft.drawText(77, 33, "OR", COLOR_RED);
+    tft.drawText(4, 58, "CANCEL > RETAKE", COLOR_RED);
+    //printElementsInPicture();
+    
+    while(1) {
+        if(getPlayerInput(wirelessInput_Freq) == 6) //SELECT -> 6
+            return true; //Confirm the picture by returning true
+        else if(getPlayerInput(wirelessInput_Freq) == 7) //CANCEL -> 7
+            return false; //Retake the picture by returning false
+    }
+}
+
+//STATE 4
+//GLCD will display the message "LOADING" and keeps it there until the
+//LPC1769 has finished shuffling the pieces in the background. When it is done,
+//it will black out the screen, populate the 4x4 grid with the puzzle pieces,
+//and start the player off at index 0 of the puzzle grid.
+//Remark: 2 out of 16 of the puzzle pieces will be missing. There were 3 reasons
+//that led us to this design choice:
+//1) We had to remove, at the very least, 1 puzzle piece to make a classic
+//sliding puzzle game.
+//2) We desired that the sizeof(picture) << 32kB but we still wanted a colored
+//image (i.e., 16 bit aray element) so we needed to get rid of 2 pieces to reach
+//our goal.
+//3) If puzzle piece positions for a classic sliding puzzle game are generated
+//completely randomly then they are only solvable 50% of the time based off
+//whether there is an even amount of permutations. There are applicable methods
+//for only generating solvable puzzles but another (and easier) solution is to
+//just remove a second puzzle piece.
+//
+//The player's button presses are ignored during this time.
+void shufflePuzzle() {
+    tft.clear();
+    tft.setFont(Terminal12x16);
+    tft.drawText(47, 40, "LOADING", COLOR_RED);
+
+    shuffleGridIndices();
+
+    tft.clear();
+    updatePuzzle();
+    cursorIndex = 0;
+    highlightGridIndex(cursorIndex, false);
+}
+
+//STATE 5
+//We wait for the player to press SELECT. If the player presses SELECT we must
+//verify 2 characteristics about the target piece before we may trigger STATE 6:
+//1) Target puzzle piece is NOT one of the 2 missing puzzle pieces.
+//2) Target puzzle piece is NOT locked on all 4 sides.
+//
+//At this point, the player is able to use the UP, DOWN, LEFT, and RIGHT buttons
+//to move around their cursor until they find a piece that they want to swap
+//for another piece. While their cursor is hovering over the target piece, they
+//would press SELECT to "grab it". The cursor is green in this state.
+uint8_t selectionMode() {
+    highlightGridIndex(cursorIndex, false);
+    //printElementsInPicture();
+    while(1) {
+        if(getPlayerInput(wirelessInput_Freq) == 6) { //SELECT -> 6
+            if(selectionMode_indexVerified(cursorIndex)) //& index verified
+                return cursorIndex;
+        }
+        else if(getPlayerInput(wirelessInput_Freq) == 2 //UP -> 2
+            && cursorIndex - 4 > -1)
+            highlightGridIndex(cursorIndex - 4, false);
+        else if(getPlayerInput(wirelessInput_Freq) == 3 //DOWN -> 3
+            && cursorIndex + 4 < 16)
+            highlightGridIndex(cursorIndex + 4, false);
+        else if(getPlayerInput(wirelessInput_Freq) == 4 //LEFT -> 4
+            && ((cursorIndex%4) - 1) > -1)
+            highlightGridIndex(cursorIndex - 1, false);
+        else if(getPlayerInput(wirelessInput_Freq) == 5 //RIGHT -> 5
+            && ((cursorIndex%4) + 1) < 4)
+            highlightGridIndex(cursorIndex + 1, false);
+    }
+}
+
+//STATE 6
+//If player presses UP, DOWN, LEFT, or RIGHT, we verify that target index is an
+//empty space before making the move and triggering STATE 5. A piece may only be
+//moved 1 index position and it may only be moved to 1 of the 2 missing puzzle
+//piece indices.
+//
+//Only UP, DOWN, LEFT, RIGHT, and CANCEL are monitored during this state.
+//Pressing CANCEL, at any time, would restore us back to STATE 5 and no swapping
+//would occur. The cursor is red in this state.
+void selectedMode(uint8_t selectedIndex) {
+    highlightGridIndex(selectedIndex, true);
+
+    while(1) {
+        if(getPlayerInput(wirelessInput_Freq) == 7) //CANCEL -> 7
+            return;
+        if(getPlayerInput(wirelessInput_Freq) == 2 //UP -> 2
+            && selectedIndex - 4 > -1) {
+            if(puzzState[selectedIndex - 4] > 13) { //Empty space above?
+                swap(&puzzState[selectedIndex], &puzzState[selectedIndex - 4]);
+                updatePuzzle();
+                cursorIndex = selectedIndex - 4;
+                return;
+            }
+        }
+        if(getPlayerInput(wirelessInput_Freq) == 3 //DOWN -> 3
+            && selectedIndex + 4 < 16) {
+            if(puzzState[selectedIndex + 4] > 13) { //Empty space below?
+                swap(&puzzState[selectedIndex], &puzzState[selectedIndex + 4]);
+                updatePuzzle();
+                cursorIndex = selectedIndex + 4;
+                return;
+            }
+        }
+        if(getPlayerInput(wirelessInput_Freq) == 4 //LEFT -> 4
+            && ((selectedIndex%4) - 1) > -1) {
+            if(puzzState[selectedIndex - 1] > 13) { //Empty space to the left?
+                swap(&puzzState[selectedIndex], &puzzState[selectedIndex - 1]);
+                updatePuzzle();
+                cursorIndex = selectedIndex - 1;
+                return;
+            }
+        }
+        if(getPlayerInput(wirelessInput_Freq) == 5 //RIGHT -> 5
+            && ((selectedIndex%4) + 1) < 4) {
+            if(puzzState[selectedIndex + 1] > 13) { //Empty space to the right?
+                swap(&puzzState[selectedIndex], &puzzState[selectedIndex + 1]);
+                updatePuzzle();
+                cursorIndex = selectedIndex + 1;
+                return;
+            }
+        }
+    }
+}
\ No newline at end of file