I simplified the library "ILI9225_TFT" provided by Arman Safikhani to better suit my needs in implementing a simple sliding puzzle game.
Diff: Effects.h
- Revision:
- 3:251e4d020501
diff -r cc93245bb6d0 -r 251e4d020501 Effects.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Effects.h Fri Apr 27 07:33:56 2018 +0000 @@ -0,0 +1,318 @@ +#include "ILI9225.h" +#include <time.h> + +//Initialize pins for MBED LPC1768: RST, RS, CS, SDI(MOSI), CLK(SCK), LED. +ILI9225 tft(P2_4, P2_3, P2_5, P0_9, P0_7, P0_6); +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); + +//Initialize pins for LPCXPRESSO LPC1769: RST, RS, CS, SDI(MOSI), CLK(SCK), LED. +//ILI9225 tft(P0_5, P0_10, P0_4, P0_18, P0_15, P0_16); + +//???b used out of 256kb available. +//uint16_t picture[13986] = {0}; + +uint16_t *picture = (uint16_t *)(0x2007C000); + +uint8_t puzzState[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15}; + +uint8_t cursorIndex = 0; //Refers to current index (-1 < cursorIndex < 16). + +Timer timer; //Timer used to implement wireless input +InterruptIn wirelessInput(p18); //Interrupt used to implement wireless input +float wirelessInput_Freq = 0; //Global variable used to implement wireless input + +void flip() { + //Convert period (in us) to frequency (Hz) + wirelessInput_Freq = (1/(float)timer.read_us())*1000000; + //Reset timer and wait for next interrupt + timer.reset(); +} + +int getPlayerInput(float freq) { + int specifier = (((int)freq) - (((int)freq)%1000))/1000; + wait_ms(1); + if(specifier == 1) { + //Turn on LED indicator(s): controller is in range. + led1 = led2 = led3 = led4 = 1; + return 0; + } + else if(specifier > 0 && specifier < 8) { + //Turn on LED indicator(s): controller is in range. + led1 = led2 = led3 = led4 = 1; + return specifier; + } + else { + //Turn off LED indicator(s): controller is NOT in range. + led1 = led2 = led3 = led4 = 0; + return 0; + } +} + +void printNumber(int x, int y, uint8_t number) { + //tft.fillRectangle(0, 0, 175, 91, COLOR_BLACK); + tft.setFont(Terminal12x16); + + if(number == 0) + tft.drawText(x, y, "0", COLOR_WHITE); + else if(number == 1) + tft.drawText(x, y, "1", COLOR_WHITE); + else if(number == 2) + tft.drawText(x, y, "2", COLOR_WHITE); + else if(number == 3) + tft.drawText(x, y, "3", COLOR_WHITE); + else if(number == 4) + tft.drawText(x, y, "4", COLOR_WHITE); + else if(number == 5) + tft.drawText(x, y, "5", COLOR_WHITE); + else if(number == 6) + tft.drawText(x, y, "6", COLOR_WHITE); + else if(number == 7) + tft.drawText(x, y, "7", COLOR_WHITE); + else if(number == 8) + tft.drawText(x, y, "8", COLOR_WHITE); + else if(number == 9) + tft.drawText(x, y, "9", COLOR_WHITE); + else if(number == 10) + tft.drawText(x, y, "10", COLOR_WHITE); + else if(number == 11) + tft.drawText(x, y, "11", COLOR_WHITE); + else if(number == 12) + tft.drawText(x, y, "12", COLOR_WHITE); + else if(number == 13) + tft.drawText(x, y, "13", COLOR_WHITE); + else if(number == 14) + tft.drawText(x, y, "14", COLOR_WHITE); + else if(number == 15) + tft.drawText(x, y, "15", COLOR_WHITE); + else + tft.drawText(x, y, "?", COLOR_WHITE); +} + +void printElementsInPicture() { + tft.fillRectangle(0, 0, 175, 91, COLOR_BLACK); + for(int i = 0; i < 16; i++) + printNumber((40*(i%4)) + 8, (20*((i - (i%4))/4)) + 8, puzzState[i]); +} + +//Put contents of pictureN at target index on GLCD specified by 'index'. +void printPictureN(int index, int N) { + int c = index%4; + int r = (index - c)/4; + + if(N > 13) { + tft.fillRectangle((39*c) + 11, (29*r) + 95, + (39*c) + 47, (29*r) + 121, COLOR_BLACK); + return; + } + for(int x = (39*c) + 11; x <= (39*c) + 47; x++) { + for(int y = (29*r) + 95; y <= (29*r) + 121; y++) + tft.drawPixel(x, y, picture[(999*N) + (4*y) + x]); + } +} + +void updatePuzzle() { + for(int N = 0; N < 16; N++) + printPictureN(N, puzzState[N]); +} + +int getNextPixel_index = 0; + +//**TODO** replace the contents of the following method with the code necessary +//to get the next pixel from the OV7670. The method, in its current state, is +//good for testing purposes. You should also be able to remove the +//'getNextPixel_index' variable if you correctly implement this new method. +uint16_t getNextPixel() { + uint16_t value = 0; + + int x, y; + + if(getNextPixel_index > 19199) { + getNextPixel_index = 0; + x = 0; + } + else + x = getNextPixel_index%160; + y = (getNextPixel_index - x)/160; + + //Is pixel in one of 4 outer pieces (corners)? + if((x >= 0 && x <= 40) && (y >= 0 && y <= 30)) //Upper left corner. + value = 65535; + if((x >= 119 && x <= 159) && (y >= 0 && y <= 30)) //Upper right corner. + value = 52428; + if((x >= 0 && x <= 40) && (y >= 89 && y <= 119)) //Lower left corner. + value = 13107; + if((x >= 119 && x <= 159) && (y >= 89 && y <= 119)) //Lower right corner. + value = 0; + + //Is pixel in one of 4 outer pieces (left and right)? + if((x >= 0 && x <= 40) && (y >= 31 && y <= 59)) //Upper left side. + value = 48059; + if((x >= 0 && x <= 40) && (y >= 60 && y <= 88)) //Lower left side. + value = 30583; + if((x >= 119 && x <= 159) && (y >= 31 && y <= 59)) //Upper right side. + value = 34952; + if((x >= 119 && x <= 159) && (y >= 60 && y <= 88)) //Lower right side. + value = 17476; + + //Is pixel in one of 4 outer pieces (top and bottom)? + if((x >= 41 && x <= 79) && (y >= 0 && y <= 30)) //Left top side. + value = 61166; + if((x >= 80 && x <= 118) && (y >= 0 && y <= 30)) //Right top side. + value = 56797; + if((x >= 41 && x <= 79) && (y >= 89 && y <= 119)) //Left bottom side. + value = 8738; + if((x >= 80 && x <= 118) && (y >= 89 && y <= 119)) //Right bottom side. + value = 0; + + //Is pixel in one of 4 inner pieces? + if((x >= 41 && x <= 79) && (y >= 31 && y <= 59)) //Upper left inner piece. + value = 43690; + if((x >= 80 && x <= 118) && (y >= 31 && y <= 59)) //Upper right inner piece. + value = 39321; + if((x >= 41 && x <= 79) && (y >= 60 && y <= 88)) //Lower left inner piece. + value = 26214; + if((x >= 80 && x <= 118) && (y >= 60 && y <= 88)) //Lower right inner piece. + value = 21845; + + getNextPixel_index++; + + return value; +} + +void handlePixel(int index, uint16_t pixel) { + int x = index%160; + int y = (index - x)/160; + if((x >= 3 && x <= 39) && (y >= 3 && y <= 29)) + picture[37*y + x - 114] = pixel; + else if((x >= 42 && x <= 78) && (y >= 3 && y <= 29)) + picture[37*y + x - 153 + 999] = pixel; + else if((x >= 81 && x <= 117) && (y >= 3 && y <= 29)) + picture[37*y + x - 192 + 1998] = pixel; + else if((x >= 120 && x <= 156) && (y >= 3 && y <= 29)) + picture[37*y + x - 231 + 2997] = pixel; + else if((x >= 3 && x <= 39) && (y >= 32 && y <= 58)) + picture[37*y + x - 1187 + 3996] = pixel; + else if((x >= 42 && x <= 78) && (y >= 32 && y <= 58)) + picture[37*y + x - 1226 + 4995] = pixel; + else if((x >= 81 && x <= 117) && (y >= 32 && y <= 58)) + picture[37*y + x - 1265 + 5994] = pixel; + else if((x >= 120 && x <= 156) && (y >= 32 && y <= 58)) + picture[37*y + x - 1304 + 6993] = pixel; + else if((x >= 3 && x <= 39) && (y >= 61 && y <= 87)) + picture[37*y + x - 2260 + 7992] = pixel; + else if((x >= 42 && x <= 78) && (y >= 61 && y <= 87)) + picture[37*y + x - 2299 + 8991] = pixel; + else if((x >= 81 && x <= 117) && (y >= 61 && y <= 87)) + picture[37*y + x - 2338 + 9990] = pixel; + else if((x >= 120 && x <= 156) && (y >= 61 && y <= 87)) + picture[37*y + x - 2377 + 10989] = pixel; + else if((x >= 3 && x <= 39) && (y >= 90 && y <= 116)) + picture[37*y + x - 3333 + 11988] = pixel; + else if((x >= 42 && x <= 78) && (y >= 90 && y <= 116)) + picture[37*y + x - 3372 + 12987] = pixel; +} + +//A utility function to swap 2 numbers +void swap(uint8_t *a, uint8_t *b) { + uint8_t temp = *a; + *a = *b; + *b = temp; +} + +void shuffleGridIndices() { + int n = sizeof(puzzState)/sizeof(puzzState[0]); + + //Use a different seed value so that we don't get same result each time we + //run this program. + srand(time(NULL)); + + //Start from the last element and swap one by one. We don't need to run for + //the first element, which is why i > 0. + for (int i = n-1; i > 0; i--) { + int j = rand()%(i+1); //Pick a random index b.w. 0 & i. + swap(&puzzState[i], &puzzState[j]); //Swap w| element @ random index. + } +} + +//This method puts a picture on the screen that is/was helpful during testing. +void putTestPicture() { + //Add 4 outer pieces (corners). + tft.fillRectangle(8, 92, 48, 122, 65535); //Upper left corner. + tft.fillRectangle(127, 92, 167, 122, 52428); //Upper right corner. + tft.fillRectangle(8, 181, 48, 211, 13107); //Lower left corner. + tft.fillRectangle(127, 181, 167, 211, 0); //Lower right corner. + + //Add 4 outer pieces (left and right). + tft.fillRectangle(8, 123, 48, 151, 48059); //Upper left side. + tft.fillRectangle(8, 152, 48, 180, 30583); //Lower left side. + tft.fillRectangle(127, 123, 167, 151, 34952); //Upper right side. + tft.fillRectangle(127, 152, 167, 180, 17476); //Lower right side. + + //Add 4 outer pieces (top and bottom). + tft.fillRectangle(49, 92, 87, 122, 61166); //Left top side. + tft.fillRectangle(88, 92, 126, 122, 56797); //Right top side. + tft.fillRectangle(49, 181, 87, 211, 8738); //Left bottom side. + tft.fillRectangle(88, 181, 126, 211, 0); //Right bottom side. + + //Add 4 inner pieces. + tft.fillRectangle(49, 123, 87, 151, 43690); //Upper left inner piece. + tft.fillRectangle(88, 123, 126, 151, 39321); //Upper right inner piece. + tft.fillRectangle(49, 152, 87, 180, 26214); //Lower left inner piece. + tft.fillRectangle(88, 152, 126, 180, 21845); //Lower right inner piece. +} + +void putGrid() { + tft.drawRectangle(8, 92, 167, 211, COLOR_WHITE); + tft.drawRectangle(9, 93, 166, 210, COLOR_WHITE); + + for(int r = 0; r < 4; r++) { + for(int c = 0; c < 4; c++) + tft.drawRectangle(39*c + 10, 29*r + 94, 39*c + 48, 29*r + 122, + COLOR_WHITE); + } +} + +void highlightGridIndex(uint8_t index, bool hasSelected) { + int c = index%4; + int r = (index - c)/4; + putGrid(); + if(hasSelected) //Red highlight means player has selected an index. + tft.drawRectangle(39*c + 10, 29*r + 94, 39*c + 48, 29*r + 122, + COLOR_RED); + if(!hasSelected) //Green highlight means player has not selected an index. + tft.drawRectangle(39*c + 10, 29*r + 94, 39*c + 48, 29*r + 122, + COLOR_GREEN); + cursorIndex = index; +} + +bool selectionMode_indexVerified(uint8_t index) { + //index must satisfy 2 characteristics for method to return true. + + //1) Target puzzle piece is NOT one of the 2 missing puzzle pieces. + if(puzzState[index] > 13) + return false; + + //2) Target puzzle piece is NOT locked on all 4 sides. + if(index - 4 > -1) { //NOT out of bounds above. + if(puzzState[index - 4] > 13) //Empty space above? + return true; + } + if(index + 4 < 16) { //NOT out of bounds below. + if(puzzState[index + 4] > 13) //Empty space below? + return true; + } + if((index%4) - 1 > -1) { //NOT out of bounds to the left. + if(puzzState[index - 1] > 13) //Empty space to the left? + return true; + } + if((index%4) + 1 < 4) { //NOT out of bounds to the right. + if(puzzState[index + 1] > 13) //Empty space to the right? + return true; + } + + return false; +} \ No newline at end of file