![](/media/cache/profiles/dream_vangogh.jpg.50x50_q85.jpg)
NXP Rapid IoT prototyping kit port of Silabs "hungry gecko" smake-like game. https://os.mbed.com/teams/SiliconLabs/code/Hungry_gecko/
Dependencies: lib_sx9500 GraphicsDisplay ColorMemLCD Large_fonts
See a detailed description of this project on Hackster.io . https://www.hackster.io/marcomerli/riotwear-snake-ca6dfc
main.cpp
- Committer:
- batman52
- Date:
- 2019-12-26
- Revision:
- 80:77210aa1ad9c
- Parent:
- 79:0431b9fd3dc0
- Child:
- 81:737dff75e013
File content as of revision 80:77210aa1ad9c:
/***************************************************************************//** * @file main.cpp * @brief Demo program for game Hungry Gecko ******************************************************************************* * @section License * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b> ******************************************************************************* * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no * obligation to support this Software. Silicon Labs is providing the * Software "AS IS", with no express or implied warranties of any kind, * including, but not limited to, any implied warranties of merchantability * or fitness for any particular purpose or warranties against infringement * of any proprietary rights of a third party. * * Silicon Labs will not be liable for any consequential, incidental, or * special damages, or any other relief, or for any claim by any third party, * arising from your use of this Software. * ******************************************************************************/ // #include "LS013B7DH03.h" #include "gecko.h" #include "food.h" #include "settings.h" // Rapid IoT LCD stuff #include "ColorMemLCD.h" #include "string" #include "Prototype24x27.h" #include "Prototype_num21x25.h" #include "meirio_num11x14.h" /**************************** Define I/O **************************************/ /* LEDS */ DigitalOut led_blue(LED_BLUE, 1); // 1 = OFF DigitalOut led_red(LED_RED, 1); /* Rapid IoT Buttons */ // InterruptIn in(PTA4); InterruptIn in(PTE28); InterruptIn inB1(PTE9); // InterruptIn SW1(PTE8); // DigitalIn SW3(PTE10); // DigitalIn SW4(PTE28); DigitalOut lcd_light(PTE12, 1); // 1 = ON, 0 = OFF ColorMemLCD display( PTB22, PTB23, PTB21, PTB20, PTD15, PTD9, "TFT"); /**************************** Define Timers ***********************************/ // LowPowerTicker ticker; Ticker ticker; /**************************** Global variables ********************************/ /* Flag that is set to true when the display is refreshed */ volatile bool refreshed = false; /* Flag that is set to true by the ticker. Makes the gecko move at regular time intervals */ volatile bool updateDisplay = true; /* A flag that ensures the controller to only read one click per frame */ volatile bool PBenabled = true; /* Direction in which the gecko moves */ Direction dir = UP; uint8_t score = 0; /**************************** Define callback handlers ************************/ void tickerCallback(void); /* Push button handlers */ void in_handler_B0(); void in_handler_B1(); /* Define game modes */ typedef enum { PLAY, STOP } Modes; /* Set the game mode */ Modes mode = PLAY; void in_handler_B0() { /* Only change the direction if push button is enabled */ if (PBenabled) { switch (dir) { case (UP): dir = LEFT; break; case (DOWN): dir = RIGHT; break; case (RIGHT): dir = UP; break; case (LEFT): dir = DOWN; break; } PBenabled = false; } } void in_handler_B1() { /* Only change the direction if push button is enabled */ if (PBenabled) { switch (dir) { case UP: dir = RIGHT; break; case DOWN: dir = LEFT; break; case RIGHT: dir = DOWN; break; case LEFT: dir = UP; break; } PBenabled = false; } } /* Callback functions */ #define POLLING_LOOP 3 void pollingUpdate(void) { static uint8_t idx = POLLING_LOOP; idx--; if(idx==0) { display.polling(); idx = POLLING_LOOP; led_blue = !led_blue; } } void tickerCallback(void) { updateDisplay = true; /* Enable push buttons if the display is refreshed */ PBenabled = refreshed; led_red = !led_red; } void refreshCallback(void) { refreshed = true; } /**************************** Fill the boarder ********************************/ void fillEdge(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color) { #if(MULTI_UPDATE) display.window(x,y,w,h); #endif display.fill (x,y,w,h, color); #if(MULTI_UPDATE) display.update(); #endif } void fillBoarder(){ // fill score header fillEdge(0, 0, DISPLAY_WIDTH, TOPEDGE*STEPSIZE, FOREGROUND_COLOR); // Fill right edge fillEdge(DISPLAY_WIDTH - (BOARDERWIDTH/2), TOPEDGE*STEPSIZE + BOARDERWIDTH/2, 1, BOARD_HEIGHT*STEPSIZE, FOREGROUND_COLOR); for (uint8_t i=0;i<=BOARD_HEIGHT;i++){ for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2);j++){ display.pixel(BOARD_WIDTH*STEPSIZE + BOARDERWIDTH/2 +j, (i+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black); } } // Fill bottom edge fillEdge(BOARDERWIDTH/2, (BOARD_HEIGHT+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2, BOARD_WIDTH*STEPSIZE, 1, FOREGROUND_COLOR); for (uint8_t i=0;i<=BOARD_WIDTH;i++){ for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2);j++){ display.pixel(i*STEPSIZE + BOARDERWIDTH/2 +j, (BOARD_HEIGHT+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black); } } // Fill left edge fillEdge(BOARDERWIDTH/2, TOPEDGE*STEPSIZE + BOARDERWIDTH/2, 1, BOARD_HEIGHT*STEPSIZE, Black); for (uint8_t i=0;i<=BOARD_HEIGHT;i++){ for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2 - 1);j++){ // display.pixel(j, (i+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black); display.pixel(j, (i+TOPEDGE)*STEPSIZE + j, Black); } } // Fill top edge fillEdge(BOARDERWIDTH/2, TOPEDGE*STEPSIZE + BOARDERWIDTH/2 - 1, BOARD_WIDTH*STEPSIZE, 1, Black); for (uint8_t i=0;i<=BOARD_WIDTH;i++){ for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2 - 1);j++){ // display.pixel(i*STEPSIZE + BOARDERWIDTH/2 + j, TOPEDGE*STEPSIZE + j, Black); display.pixel(i*STEPSIZE + j, TOPEDGE*STEPSIZE + j, Black); } } } void display_clear_all(void) { display.foreground(FOREGROUND_COLOR); display.background(BACKGROUND_COLOR); #if(MULTI_UPDATE) int j; int Divide = 8; // separate for 8 windows to save memory int Block = LCD_DISP_HEIGHT / Divide; for(j = 0 ; j <Divide ; j++) { display.window(0, j*Block, LCD_DISP_WIDTH, Block); display.cls(); display.update(); } #else display.window(0, 0, LCD_DISP_WIDTH, LCD_DISP_HEIGHT); display.cls(); display.update(); #endif } void display_score(void) { int j = 0; int Block = 27; // Text Font height; display.foreground(White); display.background(Black); #if(MULTI_UPDATE) display.window(0, j*Block, LCD_DISP_WIDTH, Block); #else display.window(0, 0, LCD_DISP_WIDTH, LCD_DISP_HEIGHT); #endif display.fill(0,0,LCD_DISP_WIDTH, Block, Black); display.locate(4, j*Block); display.printf("Score: %02d", score); #if(MULTI_UPDATE) display.update(); #else // reduce buffer window size to game area for faster refresh rate display.window(BOARDERWIDTH/2, TOPEDGE*STEPSIZE + BOARDERWIDTH/2, BOARD_WIDTH * STEPSIZE, BOARD_HEIGHT * STEPSIZE); #endif display.foreground(FOREGROUND_COLOR); display.background(BACKGROUND_COLOR); } #define GAME_OVER_X 40 void display_game_over(void) { int j = 3; int Block = 27; // Text Font height: 6 lines of text display.window(0, j*Block, LCD_DISP_WIDTH, Block); display.locate(GAME_OVER_X, j*Block); display.printf("GAME"); display.update(); j++; display.window(0, j*Block, LCD_DISP_WIDTH, Block); display.locate(GAME_OVER_X, j*Block); display.printf("OVER!"); display.update(); } /**************************** MAIN ********************************************/ int main() { /* Initialize pushbutton handlers */ in.fall(in_handler_B0); inB1.fall(in_handler_B1); /* Enable the LCD */ display.command_AllClear(); display.set_font( (unsigned char*)Prototype24x27 ); #if TICKER_EN /* Start generating the 3Hz call */ ticker.attach(&tickerCallback, 0.3333f); #endif /* Reset the LCD to a blank state. (All white) */ display_clear_all(); fillBoarder(); display_score(); Gecko gck; Food fd; gck.draw(display); fd.draw(display); /* Push update to the display */ display.update(); /* Main loop */ while (1) { #if(TICKER_EN) sleep(); #else wait(0.2); #endif // update button status refreshCallback(); #if(!TICKER_EN) tickerCallback(); #endif if (updateDisplay && refreshed && (mode==PLAY)) { updateDisplay = false; refreshed = false; pollingUpdate(); gck.move(display, dir); if (fd.isEaten(gck)) { fd.reset(display, gck); gck.increaseLength(display, dir); /* Redraw gecko */ gck.draw(display); /* Update the score */ score++; display_score(); } if (gck.selfCollision()) { mode = STOP; gck.move(display, dir); display_game_over(); } /* Update display */ refreshed = false; display.update(); } } }