void setup_display(void) { // initialize the LCD display // tft.init(); // tft.initR(INITR_BLACKTAB); // initialize a S6D02A1S chip, black tab tft.setRotation(1); tft.fillScreen(BLACK); //BLACK); //tft.fillRect(0, pos, 160, 128-pos, BLACK); // erase old string tft.setCursor(0, 119); tft.setTextColor(WHITE); tft.setTextWrap(true); // tft.print("DD4WH SDR 5.00"); // Show mid screen tune position tft.drawFastVLine(pos_centre_f, 0,pos+1, RED); //WHITE); // tft.drawFastHLine(0, pos,79, YELLOW);// WHITE); //tft.drawFastHLine(81, pos,79, YELLOW); // draw S-Meter layout tft.drawFastHLine (pos_x_smeter, pos_y_smeter-1, 9*s_w, WHITE); tft.drawFastHLine (pos_x_smeter, pos_y_smeter+3, 9*s_w, WHITE); tft.fillRect(pos_x_smeter, pos_y_smeter-3, 2, 2, WHITE); tft.fillRect(pos_x_smeter+8*s_w, pos_y_smeter-3, 2, 2, WHITE); tft.fillRect(pos_x_smeter+2*s_w, pos_y_smeter-3, 2, 2, WHITE); tft.fillRect(pos_x_smeter+4*s_w, pos_y_smeter-3, 2, 2, WHITE); tft.fillRect(pos_x_smeter+6*s_w, pos_y_smeter-3, 2, 2, WHITE); tft.fillRect(pos_x_smeter+7*s_w, pos_y_smeter-4, 2, 3, WHITE); tft.fillRect(pos_x_smeter+3*s_w, pos_y_smeter-4, 2, 3, WHITE); tft.fillRect(pos_x_smeter+5*s_w, pos_y_smeter-4, 2, 3, WHITE); tft.fillRect(pos_x_smeter+s_w, pos_y_smeter-4, 2, 3, WHITE); tft.fillRect(pos_x_smeter+9*s_w, pos_y_smeter-4, 2, 3, WHITE); tft.drawFastHLine (pos_x_smeter+9*s_w, pos_y_smeter-1, 3*s_w*2+2, GREEN); tft.drawFastHLine (pos_x_smeter+9*s_w, pos_y_smeter+3, 3*s_w*2+2, GREEN); tft.fillRect(pos_x_smeter+11*s_w, pos_y_smeter-4, 2, 3, GREEN); tft.fillRect(pos_x_smeter+13*s_w, pos_y_smeter-4, 2, 3, GREEN); tft.fillRect(pos_x_smeter+15*s_w, pos_y_smeter-4, 2, 3, GREEN); tft.drawFastVLine (pos_x_smeter-1, pos_y_smeter-1, 5, WHITE); tft.drawFastVLine (pos_x_smeter+15*s_w+2, pos_y_smeter-1, 5, GREEN); tft.setCursor(pos_x_smeter - 4, pos_y_smeter - 13); tft.setTextColor(WHITE); tft.setTextWrap(true); tft.print("S 1"); tft.setCursor(pos_x_smeter + 28, pos_y_smeter - 13); tft.print("3"); tft.setCursor(pos_x_smeter + 48, pos_y_smeter - 13); tft.print("5"); tft.setCursor(pos_x_smeter + 68, pos_y_smeter - 13); tft.print("7"); tft.setCursor(pos_x_smeter + 88, pos_y_smeter - 13); tft.print("9"); tft.setCursor(pos_x_smeter + 120, pos_y_smeter - 13); tft.print("+20dB"); } // end void setupdisplay
void testfillrects(uint16_t color1, uint16_t color2) { tft.fillScreen(ST7735_BLACK); for (int16_t x=tft.width()-1; x > 6; x-=6) { tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1); tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2); } }
void show_bandfilter(String bandfiltername, boolean highlight) { // show band tft.fillRect(0, 108, 40, 18, BLACK); // erase old string tft.setFont(&FreeSans9pt7b); if (highlight) { tft.setTextColor(YELLOW); } else { tft.setTextColor(WHITE); } tft.setCursor(0, 125); tft.print(bandfiltername); }
// show radio mode void show_radiomode(String mode, boolean highlight) { tft.fillRect(106, 108, 54, 18, BLACK); // erase old string tft.setFont(&FreeSans9pt7b); if (highlight) { tft.setTextColor(YELLOW); } else { tft.setTextColor(WHITE); } tft.setCursor(106, 125); tft.print(mode); }
// show frequency void show_frequency(long int freq, boolean highlight) { uint8_t offsetx = 0; tft.setFont(&FreeSans12pt7b); char string[80]; // print format stuff sprintf(string, "%d.%03d.%03d", freq / 1000000, (freq - freq / 1000000 * 1000000) / 1000, freq % 1000 ); if (freq < 10000000) offsetx = 13; tft.fillRect(pos_x_freq, pos_y_freq - 17, 120, 18, BLACK); tft.setCursor(pos_x_freq + offsetx, pos_y_freq); if (highlight) { tft.setTextColor(YELLOW); } else { tft.setTextColor(WHITE); } tft.print(string); }
void draw_map_screen() { #ifdef DEBUG // Want to display a small message saying that we are redrawing the map! tft.fillRect(78, 148, 50, 12, GREEN); tft.setTextSize(1); tft.setTextColor(MAGENTA); tft.setCursor(80, 150); tft.setTextSize(1); tft.println("DRAWING..."); #endif lcd_image_draw(&map_tiles[current_map_num], &tft , screen_map_x, screen_map_y , 0, 0, 128, 160); }
void show_waterfall(void) { // experimental waterfall display for CW - // this should probably be on a faster timer since it needs to run as fast as possible to catch CW edges // FFT bins are 22khz/128=171hz wide // cw peak should be around 11.6khz - static uint16_t waterfall[80]; // array for simple waterfall display static uint8_t w_index=0,w_avg; waterfall[w_index]=0; for (uint8_t y=66;y<67;++y) // sum of bin powers near cursor - usb only waterfall[w_index]+=(uint8_t)(abs(myFFT.output[y])); // store bin power readings in circular buffer waterfall[w_index]|= (waterfall[w_index]<<5 |waterfall[w_index]<<11); // make it colorful int8_t p=w_index; for (uint8_t x=158;x>0;x-=2) { tft.fillRect(x,65,2,4,waterfall[p]); if (--p<0 ) p=79; } if (++w_index >=80) w_index=0; }
void show_s_meter_layout() { tft.drawFastHLine (pos_x_smeter, pos_y_smeter - 1, 9 * s_w, WHITE); tft.drawFastHLine (pos_x_smeter, pos_y_smeter + 3, 9 * s_w, WHITE); tft.fillRect(pos_x_smeter, pos_y_smeter - 3, 2, 2, WHITE); tft.fillRect(pos_x_smeter + 8 * s_w, pos_y_smeter - 3, 2, 2, WHITE); tft.fillRect(pos_x_smeter + 2 * s_w, pos_y_smeter - 3, 2, 2, WHITE); tft.fillRect(pos_x_smeter + 4 * s_w, pos_y_smeter - 3, 2, 2, WHITE); tft.fillRect(pos_x_smeter + 6 * s_w, pos_y_smeter - 3, 2, 2, WHITE); tft.fillRect(pos_x_smeter + 7 * s_w, pos_y_smeter - 4, 2, 3, WHITE); tft.fillRect(pos_x_smeter + 3 * s_w, pos_y_smeter - 4, 2, 3, WHITE); tft.fillRect(pos_x_smeter + 5 * s_w, pos_y_smeter - 4, 2, 3, WHITE); tft.fillRect(pos_x_smeter + s_w, pos_y_smeter - 4, 2, 3, WHITE); tft.fillRect(pos_x_smeter + 9 * s_w, pos_y_smeter - 4, 2, 3, WHITE); tft.drawFastHLine (pos_x_smeter + 9 * s_w, pos_y_smeter - 1, 3 * s_w * 2 + 2, GREEN); tft.drawFastHLine (pos_x_smeter + 9 * s_w, pos_y_smeter + 3, 3 * s_w * 2 + 2, GREEN); tft.fillRect(pos_x_smeter + 11 * s_w, pos_y_smeter - 4, 2, 3, GREEN); tft.fillRect(pos_x_smeter + 13 * s_w, pos_y_smeter - 4, 2, 3, GREEN); tft.fillRect(pos_x_smeter + 15 * s_w, pos_y_smeter - 4, 2, 3, GREEN); tft.drawFastVLine (pos_x_smeter - 1, pos_y_smeter - 1, 5, WHITE); tft.drawFastVLine (pos_x_smeter + 15 * s_w + 2, pos_y_smeter - 1, 5, GREEN); tft.setFont(); tft.setCursor(pos_x_smeter - 4, pos_y_smeter - 13); tft.setTextColor(WHITE); tft.setTextWrap(true); tft.print("S 1"); tft.setCursor(pos_x_smeter + 28, pos_y_smeter - 13); tft.print("3"); tft.setCursor(pos_x_smeter + 48, pos_y_smeter - 13); tft.print("5"); tft.setCursor(pos_x_smeter + 68, pos_y_smeter - 13); tft.print("7"); tft.setCursor(pos_x_smeter + 88, pos_y_smeter - 13); tft.print("9"); tft.setCursor(pos_x_smeter + 120, pos_y_smeter - 13); tft.print("+20dB"); }
void status_msg(char *msg) { // messages are strings, so we assume constant, and if they are the // same pointer then the contents are the same. You can force by // setting prev_status_msg = 0 const uint16_t msg_text_height = 10; const uint16_t msg_window_height = msg_text_height+2; if ( prev_status_msg != msg ) { prev_status_msg = msg; tft.fillRect(0, display_window_height - msg_window_height, display_window_width, msg_window_height, GREEN); tft.setTextSize(1); tft.setTextColor(MAGENTA); tft.setCursor(0, display_window_height - msg_text_height); tft.setTextSize(1); // 10 pixels high tft.println(msg); } }
int main() { // Initialize arduino, serial communication, lcd screen, buttons (and // internal pull-up resistors), LED pins, and SD card. init(); Serial.begin(9600); Serial3.begin(9600); while(Serial3.available()) {Serial3.read();} // Clean the Serial line tft.initR(INITR_BLACKTAB); pinMode(SEL, INPUT); digitalWrite(SEL, HIGH); pinMode(Button1, INPUT); digitalWrite(Button1, HIGH); for (int i = 0; i < 10; ++i) { pinMode(i + 22, OUTPUT); } int click; // This will be used to continue from the Title Screen Serial.print("Initializing SD card..."); if (!SD.begin(SD_CS)) { Serial.println("failed!"); } Serial.println("OK!"); // do the auto calibration of the cursor (found in Cursor.cpp) Initialize_Cursor(); while(true) { // draw the title screen, and set the turn pin to neutral (blue) lcd_image_draw(&Images[title], &tft, 0, 0, 0, 0, 128, 160 ); digitalWrite(bluePin, HIGH); while (true) { // leave the title page with a joystick button press. click = digitalRead(SEL); if (!click) {break;} } // draw a black screen tft.fillScreen(0); // draw the border image (note that the numbers (0-9) and // letters (A-J) are just for appearance and aren't actually used by // the program). lcd_image_draw(&Images[border], &tft, 0, 0, 0, 0, 128, 128 ); // initialize My_Ocean so that each value is 0 (water) for( int i=0; i<100; i++ ) { My_Ocean[i] = 0; } // initialize Their_Ocean so that each value is 1 (miss). This needs to // be nonzero for the first drawing of the screen (occurs on line 47 // of Place_Ships.cpp) and will be set to 0 after. for( int i=0; i<100; i++ ) { Their_Ocean[i] = 1; } //==================== Initialization complete ================= // Allows a player to place their ships My_Ships = Place_Ships(My_Ocean, Their_Ocean); // set Their_Ocean so that each value is 0 (water). for( int i=0; i<100; i++ ) { Their_Ocean[i] = 0; } // One arduino should read high, and the other should read low // (see wiring instructions for more detail). This determines who // gets the first turn. bool Turn = digitalRead(13); // Initialize the number of ships remaining for each player to 5. // can be set to 1 for a "debug" mode to see the victory/reset more // quickly. int Mine_Alive = 5; int Their_Alive = 5; // Turn on all the LED's initially (because all 10 ships should be // alive). for (int i = 0; i < 10; i++) { digitalWrite(22+i , HIGH); } // Connect to opponent. One arduino writes 'R' for ready, then waits // to receive a response. The other waits to read 'R' first, then // writes it. Write_Message("Connecting..."); if( Turn == 1 ) { Serial3.write('R'); while( Serial3.read() !='R' ) {} } else { while( Serial3.read() !='R' ) {} Serial3.write('R'); } //==================== Ready to communicate/play =============== // Loop until either player has no ships left. while((Mine_Alive != 0) && (Their_Alive != 0)) { // My turn if( Turn == 1 ) { // draw a red square in the top left corner (because we will // view what we know of Their_Ocean). tft.fillRect(0, 0, 8, 8, 0xF800); // Make the LED green because it is our turn. digitalWrite(redPin, LOW); digitalWrite(greenPin, HIGH); digitalWrite(bluePin, LOW); // Draw Their_Ocean Draw_Screen(Their_Ocean, My_Ocean); // Indicate our turn at the bottom of the screen Write_Message("Your Turn"); // Call Fire. It will return one (decrementing Their_Alive) // if it sinks a ship. Their_Alive = Their_Alive - Fire(Their_Ocean); // change turns Turn = 0; } else if( Turn == 0 ) { // draw a green square in the top left corner (because we will // view our own ships (My_Ocean). tft.fillRect(0, 0, 8, 8, 0x07E0); // Make the LED red because it is their turn. digitalWrite(redPin, HIGH); digitalWrite(greenPin, LOW); digitalWrite(bluePin, LOW); // draw My_Ocean Draw_Screen(My_Ocean, Their_Ocean); // Indicate their turn at the bottom of the screen Write_Message("Opponent's turn"); // Call Get_Shot_At. It will return one (and will decrement // Mine_Alive) if a ship is sunk. Mine_Alive = Mine_Alive-Get_Shot_At(My_Ocean, My_Ships); // change turns Turn = 1; } // update the LEDs based on the number of ships left alive. The // Green LEDS represent the number of ships you have alive while // the Red ones do the same for the other players ships. for (int i = 5; i > 0; i--) { if (Their_Alive >= i) { digitalWrite(21 + 2*i , HIGH); } else { digitalWrite(21 + 2*i , LOW); } } for (int i = 5; i > 0; i--) { if (Mine_Alive >= i) { digitalWrite(20 + 2*i , HIGH); } else { digitalWrite(20 + 2*i , LOW); } } } // The delays help everything to sync up with the sound effects. delay(2000); if( Mine_Alive > 0 ) { // The number sent to the 'Victory_Cascade()' is to indicate which // set of LEDS are to be cascaded based on which player is the // winner of the game. The spaces in the message are in place to // avoid the word in the messages being cut off Write_Message("You won! Please hold joystick button to play again."); Sound_Victory(); Victory_Cascade(22); } else { delay(3000); Write_Message("You lost! Please holdjoystick button to play again."); Victory_Cascade(23); } } Serial3.end(); Serial.end(); return 0; // End of function }
// show frequency void show_frequency(long int freq) { tft.setTextSize(2); tft.setTextColor(WHITE); uint8_t zaehler; uint8_t digits[10]; zaehler = 8; while (zaehler--) { digits[zaehler] = ExtractDigit (freq, zaehler); // Serial.print(digits[zaehler]); // Serial.print("."); // 7: 10Mhz, 6: 1Mhz, 5: 100khz, 4: 10khz, 3: 1khz, 2: 100Hz, 1: 10Hz, 0: 1Hz } // Serial.print("xxxxxxxxxxxxx"); zaehler = 8; while (zaehler--) { // counts from 7 to 0 if (zaehler < 6) sch = 7; // (khz) if (zaehler < 3) sch = 14; // (Hz) if (digits[zaehler] != digits_old[zaehler] || !freq_flag) { // digit has changed (or frequency is displayed for the first time after power on) if (zaehler == 7) { sch = 0; tft.setCursor(pos_x_frequency + font_width * (8-zaehler) + sch,pos_y_frequency); // set print position tft.fillRect(pos_x_frequency + font_width * (8-zaehler) + sch,pos_y_frequency, font_width,16,BLACK); // delete old digit if (digits[7] != 0) tft.print(digits[zaehler]); // write new digit in white } if (zaehler == 6) { sch = 0; tft.setCursor(pos_x_frequency + font_width * (8-zaehler) + sch,pos_y_frequency); // set print position tft.fillRect(pos_x_frequency + font_width * (8-zaehler) + sch,pos_y_frequency, font_width,16,BLACK); // delete old digit if (digits[6]!=0 || digits[7] != 0) tft.print(digits[zaehler]); // write new digit in white } if (zaehler == 5) { sch = 7; tft.setCursor(pos_x_frequency + font_width * (8-zaehler) + sch,pos_y_frequency); // set print position tft.fillRect(pos_x_frequency + font_width * (8-zaehler) + sch,pos_y_frequency, font_width,16,BLACK); // delete old digit if (digits[5] != 0 || digits[6]!=0 || digits[7] != 0) tft.print(digits[zaehler]); // write new digit in white } if (zaehler < 5) { // print the digit tft.setCursor(pos_x_frequency + font_width * (8-zaehler) + sch,pos_y_frequency); // set print position tft.fillRect(pos_x_frequency + font_width * (8-zaehler) + sch,pos_y_frequency, font_width,16,BLACK); // delete old digit tft.print(digits[zaehler]); // write new digit in white } digits_old[zaehler] = digits[zaehler]; } } tft.setTextSize(1); if (digits[7] == 0 && digits[6] == 0) tft.fillRect(pos_x_frequency + font_width * 3,pos_y_frequency + 11, 3, 3, BLACK); else tft.fillRect(pos_x_frequency + font_width * 3,pos_y_frequency + 11, 3, 3, YELLOW); tft.fillRect(pos_x_frequency + font_width * 7 -4, pos_y_frequency + 11, 3, 3, YELLOW); if (!freq_flag) { tft.setCursor(pos_x_frequency + font_width * 9 + 16,pos_y_frequency + 7); // set print position tft.setTextColor(GREEN); tft.print("Hz"); } freq_flag = 1; tft.setTextColor(WHITE); } // END VOID SHOW-FREQUENCY
void show_bandwidth (int M, long int FU, long int FL) { tft.drawFastHLine(0,pos+1,160, BLACK); // erase old indicator tft.drawFastHLine(0,pos+2,160, BLACK); // erase old indicator tft.drawFastHLine(0,pos+3,160, BLACK); // erase old indicator tft.drawFastHLine(0,pos,160, BLACK); // erase old indicator bwhelp = FU /100; int leU = bwhelp*16/spectrum_span; bwhelp = FL /100; int leL = bwhelp*16/spectrum_span; float kHz = (FU + FL) / 1000.0; switch (M) { case 0: //AM tft.fillRect(4, pos_y_frequency-3, 32, 8, BLACK); // erase old string tft.setTextColor(GREEN); tft.setCursor(4, pos_y_frequency-3); tft.print("AM"); break; case 3: //DSB tft.fillRect(4, pos_y_frequency-3, 32, 8, BLACK); // erase old string tft.setTextColor(GREEN); tft.setCursor(4, pos_y_frequency-3); tft.print("DSB"); break; case 4: //StereoAM tft.fillRect(4, pos_y_frequency-3, 32, 8, BLACK); // erase old string tft.setTextColor(GREEN); tft.setCursor(4, pos_y_frequency-3); tft.print("SteAM"); break; case 2: //LSB tft.fillRect(4, pos_y_frequency-3, 32, 8, BLACK); // erase old string tft.setTextColor(GREEN); tft.setCursor(4, pos_y_frequency-3); tft.print("LSB"); break; case 1: //USB tft.fillRect(4, pos_y_frequency-3, 32, 8, BLACK); // erase old string tft.setTextColor(GREEN); tft.setCursor(4, pos_y_frequency-3); tft.print("USB"); break; } // end switch //print bandwidth ! tft.fillRect(4, pos_y_frequency+7, 32, 8, BLACK); // erase old string tft.setCursor(4, pos_y_frequency+7); sprintf(string,"%02.1fk",kHz); tft.print(string); tft.setTextColor(WHITE); // set text color to white for other print routines not to get confused ;-) // draw upper sideband indicator tft.drawFastHLine(pos_centre_f, pos+1, leU, RED); tft.drawFastHLine(pos_centre_f, pos+2, leU, RED); tft.drawFastHLine(pos_centre_f, pos+3, leU, RED); tft.drawFastHLine(pos_centre_f, pos, leU, RED); // draw lower sideband indicator left = pos_centre_f - leL; tft.drawFastHLine(left+1, pos+1, leL, RED); tft.drawFastHLine(left+1, pos+2, leL, RED); tft.drawFastHLine(left+1,pos+3, leL, RED); tft.drawFastHLine(left+1,pos, leL, RED); tft.fillRect(pos_centre_f + 160/spectrum_span * 5, pos, 2, 3, YELLOW); // erase old string tft.fillRect(pos_centre_f + 160/spectrum_span * 10, pos, 2, 4, YELLOW); // erase old string tft.fillRect(pos_centre_f - 160/spectrum_span * 5, pos, 2, 3, YELLOW); // erase old string tft.fillRect(pos_centre_f - 160/spectrum_span * 10, pos, 2, 4, YELLOW); // erase old string tft.fillRect(pos_centre_f - 160/spectrum_span * 15, pos, 2, 3, YELLOW); // erase old string tft.fillRect(pos_centre_f + 160/spectrum_span * 15, pos, 2, 3, YELLOW); // erase old string tft.fillRect(pos_centre_f - 160/spectrum_span * 20, pos, 2, 4, YELLOW); // erase old string tft.fillRect(pos_centre_f - 160/spectrum_span * 25, pos, 2, 3, YELLOW); // erase old string tft.fillRect(pos_centre_f - 160/spectrum_span * 30, pos, 2, 4, YELLOW); // erase old string }
// show signal strength void show_signalstrength(String s) { tft.setFont(&FreeSans9pt7b); tft.fillRect(12, 72, 40, 14, BLACK); tft.setCursor(0, 85); tft.print(s); }
void loop() { // Though counter-intuitive, game creation cannot be in setup because of varying arduino boot times and boot gibberish if (!gameCreated) { drawGUI(); while(!waitUntil(JOYSTICK_BUTTON_PIN, false)); if (!startNetwork()) { tft.fillScreen(ST7735_BLACK); // we must clear all conflicting messages from screen tft.setCursor(0,0); dualPrint("Network connection failed!"); dualPrint("Please ensure:"); dualPrint("1) both arduinos are connected"); dualPrint("2) both parties pressed the joystick"); dualPrint("If both are true, consult someone who"); dualPrint("looks like he knows what he's talking about"); dualPrint("Reset both Arduinos to try again"); while(1); } /* Extensibility Goal: * Enable colour selection here, time permissible */ gameCreated = true; } if (!gameStarted) { setSpawns(&player1, &player2); setColour(&player1, &player2); tft.fillScreen(ST7735_BLACK); startCountdown(); gameStarted = true; } winner = gameOver(&player1.currentPosition, &player2.currentPosition); if (winner) { tft.setCursor(0, 80); String message; switch (winner) { case -1: message = "YOU SUPER TIE"; break; case 1: message = "YOU SUPER WIN"; player1.score++; break; case 2: message = "YOU SUPER LOSE"; player2.score++; break; } tft.println(message); tft.println("SCORES:"); tft.print("You: "); tft.print(player1.score); tft.print(" | Him: "); tft.println(player2.score); tft.println("Again? <Press Joystick>"); waitUntil(JOYSTICK_BUTTON_PIN, LOW); memset(&wallPositions, 0, 2560); // 2560 is a magic number because size_ts were acting unexpectedly gameStarted = false; tft.fillScreen(ST7735_BLACK); } else { // add a wall ad draw car at current position addWallPosition(player1.currentPosition); addWallPosition(player2.currentPosition); tft.fillRect(player1.currentPosition.x, player1.currentPosition.y, 2, 2, player1.colour); tft.fillRect(player2.currentPosition.x, player2.currentPosition.y, 2, 2, player2.colour); movement_t newDirection = getJoystickInput(); if (validInput(newDirection, player1.direction)) player1.direction = newDirection; sendDeltas(&player1.direction); receiveDeltas(&player2.direction); player1.currentPosition.x += player1.direction.x; player1.currentPosition.y += player1.direction.y; player2.currentPosition.x += player2.direction.x; player2.currentPosition.y += player2.direction.y; delay(75); // this is how we control the game speed /* Extensibility Goal: * Find a more efficient and reliable way of controlling game speed. * Implement it, and allow it to be customized */ } }
int main() { // SETUP init(); Serial.begin(9600); tft.initR(INITR_BLACKTAB); // initialize screen // Setting the joystick button and LEDs pinMode(JOYSTICK_BUTTON, INPUT); digitalWrite(JOYSTICK_BUTTON, HIGH); // Initialize the SD card Serial.print("Initializing SD card..."); if (!SD.begin(SD_CS)) { Serial.println("failed!"); while(true) {} // something is wrong } else {Serial.println("OK!");} // More initialization Serial.print("Initializing Raw SD card..."); if (!card.init(SPI_HALF_SPEED, SD_CS)) { Serial.println("failed!"); while(true) {} // something is wrong } else {Serial.println("OK!");} // Create states for different modes // C1 for Mode 1 - MENU screen // C2 for Mode 2 - Snake Game // C3 for Mode 3 - GAME OVER screen // C4 for Mode 4 - Choose level // C5 for Mode 5 - PAUSE screen typedef enum {C1 = 1, C2, C3, C4, C5, ERR} State; State state = C1; int select, snakelength; while (state!=ERR) { if (state == C1) { /// ====== MODE 1 - MENU ====== /// Serial.println("Currently in Mode 1"); snakelength = 1; init_vert = analogRead(JOYSTICK_VERT); init_horiz = analogRead(JOYSTICK_HORIZ); // preparations for the game - to not overlap with the pause menu q = q_create(720); i = 64; // x component j = 80; // y component q_add(q,i,j); // load into the queue random_x = food_x(); // load x coordinate of food piece random_y = food_y(); // load y coordinate of food piece pausedirection = 0; // set paused direction to 0 // reset grid to 0 for (int a = 0; a < 24; a++) { for (int b = 0; b < 30; b++) { grid[a][b] = 0; } } // display main menu snake(); tft.setTextSize(2); while(true) { // alternate highlighting of START unsigned long time = millis()%1000; int a = time%1000; if ((a<17)) { tft.setCursor(34, 83); tft.fillRoundRect(30,80,65,20,5,WHITE); tft.setTextColor(RED); tft.print("START"); } else if ((a>500) && (a<520)) { tft.setCursor(34, 83); tft.fillRoundRect(30,80,65,20,5,RED); tft.setTextColor(WHITE); tft.print("START"); } // Read the Joystick - HIGH if not pressed, LOW otherwise select = digitalRead(JOYSTICK_BUTTON); if (select == LOW) { break; } } state = C4; } else if (state == C2) { /// ====== MODE 2 - SNAKE GAME ====== /// Serial.println("Currently in Mode 2"); delay(50); soundsetup(); //setting up sound pin // print the background tft.fillScreen(DARKRED); tft.fillRect(4,5,120,150,DARKGRN); // print the snake int x,y; x = q_frontx(q); y = q_fronty(q); tft.fillRect(x,y,5,5, WHITE); //Bringing the food in, outside while loop first. tft.fillRect(random_x, random_y, 5, 5, YELLOW); // do auto calibration int px, py; int lastmove; // read beginning direction chosen by user if (pausedirection == 0) { direction = read_direction(); } else { direction = pausedirection; } lastmove = direction; while (true) { // to direct movement // (without going in reverse direction of previous movement) // up if (direction == 1) { if (lastmove == 2) { direction = 2; j = j-5; } else { j = j+5; } q_add(q,i,j); } // down else if (direction == 2) { if (lastmove == 1) { direction = 1; j = j+5; } else { j = j-5; } q_add(q,i,j); } // right else if (direction == 3) { if (lastmove == 4) { direction = 4; i = i-5; } else { i = i+5; } q_add(q,i,j); } // left else if (direction == 4) { if (lastmove == 3) { direction = 3; i = i+5; } else { i = i-5; } q_add(q,i,j); } // if the direction is changed, store the new direction & last move int new_direc = read_direction(); if ((new_direc != direction) && (new_direc != 0)) { lastmove = direction; direction = new_direc; } // if the snake hits a piece of food, the food vanishes and gets replaced if ((i == random_x) && (j == random_y)) { // snake grows by 4 squares, except for the first time // this allows for it to end up as a max of 720 in the queue if (snakelength == 1) { q_add(q,i,j); q_add(q,i,j); q_add(q,i,j); snakelength += 3; } else { q_add(q,i,j); q_add(q,i,j); q_add(q,i,j); q_add(q,i,j); snakelength += 4; } if (snakelength < 720) { random_x = food_x(); random_y = food_y(); // if the snake is already there, find a new spot for the food while (grid[random_x/5][random_y/5-1] == 1) { random_x = food_x(); random_y = food_y(); } // print the new food tft.fillRect(random_x, random_y, 5, 5, YELLOW); } } // if the snake runs over itself if ((snakelength > 1) && (grid[i/5][j/5-1] == 1)) { delay(450); // pause when snake runs into itself int m = 0; soundLoop(); while(m < 6000) { int rand_x = dissolve_x(); int rand_y = dissolve_y(); tft.fillRect(rand_x, rand_y, 5, 5, BLACK); m++; } state = C3; break; } px = q_frontx(q); py = q_fronty(q); // reprint the snake if there is movement if ((i != px) || (j != py)) { tft.fillRect(i,j,5,5, WHITE); grid[i/5][j/5-1] = 1; // snake body is in grid tft.fillRect(px,py,5,5,DARKGRN); grid[px/5][py/5-1] = 0; // snake body is no longer in grid q_remove(q); // take away from the queue delay(speed); // controls the speed of the snake } // if any of the borders are hit if ((i < 4)||(j < 5)||(i > 119)||(j > 150)) { delay(450); // pause when border is hit // dissolve the screen int m = 0; soundLoop(); while(m < 6000) { int rand_x = dissolve_x(); int rand_y = dissolve_y(); tft.fillRect(rand_x, rand_y, 5, 5, BLACK); m++; } //~ delay(250); state = C3; break; } // Read the Joystick - HIGH if not pressed, LOW otherwise select = digitalRead(JOYSTICK_BUTTON); if (select == LOW) { state = C5; break; } } } else if (state == C3) { /// ====== MODE 3 - GAME OVER ====== /// Serial.println("Currently in Mode 3"); q_destroy(q); // clear the queue tft.fillScreen(BLACK); tft.fillRoundRect(5,20,118,25,5,RED); tft.setCursor(10, 25); tft.setTextColor(BLACK); tft.setTextSize(2); tft.setTextWrap(true); tft.print("GAME OVER"); tft.print("\n"); tft.setCursor(10, 55); tft.setTextColor(RED); tft.setTextSize(1.5); if (snakelength >= 720) { snakelength = 720; tft.print("YOU WON! CONGRATZ"); } else { tft.print(" Oh no! You hit something!"); } tft.setCursor(10, 80); tft.setTextColor(WHITE); tft.setTextSize(1); tft.print("Length of Snake:"); tft.print(snakelength); tft.setCursor(10, 100); tft.print("Press the joystick to return to main menu"); // Read the Joystick - HIGH if not pressed, LOW otherwise while (true) { select = digitalRead(JOYSTICK_BUTTON); if (select == LOW) { break; } } state = C1; } else if (state == C4) { /// ====== MODE 4 - CHOOSE LEVEL ====== /// Serial.println("Currently in Mode 4"); // printing // snake display snake(); // difficulty levels tft.setTextSize(2); tft.setTextColor(WHITE); easy(RED); tft.setTextColor(RED); medium(WHITE); hard(WHITE); int selection = 1; int oldselection; while(true) { // read direction from the user for updating selection oldselection = selection; vertical = analogRead(JOYSTICK_VERT); // will be 0-1023 delay(100); // scroll down if (vertical > init_vert + 200) { selection++; if (selection > 3) { selection = 0; } } // scroll up else if (vertical < init_vert - 200) { selection--; if (selection < 0) { selection = 3; } } if (selection != oldselection) { update(selection); } // Read the Joystick - HIGH if not pressed, LOW otherwise select = digitalRead(JOYSTICK_BUTTON); if (select == LOW) { Serial.print("made selection: "); Serial.println(selection); if (selection == 1) {speed = 225;} else if (selection == 2) {speed = 150;} else if (selection == 3) {speed = 75;} break; } } state = C2; } else if (state == C5) { /// ====== MODE 5 - PAUSE MENU ====== /// Serial.println("Currently in Mode 5"); pausedirection = direction; // printing snake and pause snake(); tft.setTextSize(2); tft.setCursor(34, 73); tft.fillRoundRect(30,70,65,20,5,WHITE); tft.setTextColor(RED); tft.print("Pause"); while(true) { // Read the Joystick - HIGH if not pressed, LOW otherwise select = digitalRead(JOYSTICK_BUTTON); if (select == LOW) { break; } } // reset grid to 0 for (int a = 0; a < 24; a++) { for (int b = 0; b < 30; b++) { grid[a][b] = 0; } } state = C2; } //if not any of this: else { Serial.println("There has been an error"); state = ERR; } } Serial.end(); return 0; }
void show_tunestep(String S) { // show band char string[80]; tft.fillRect(pos_x_tunestep, pos_y_tunestep, 60, 8, BLACK); // erase old string tft.setTextColor(WHITE); tft.setCursor(pos_x_tunestep, pos_y_tunestep); tft.print(S); }