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

Revision:
80:77210aa1ad9c
Parent:
79:0431b9fd3dc0
Child:
81:737dff75e013
--- a/main.cpp	Sat Nov 23 18:03:20 2019 +0000
+++ b/main.cpp	Thu Dec 26 16:47:58 2019 +0000
@@ -1,32 +1,375 @@
-#include "mbed.h"
-
-DigitalOut rgb_red(LED_RED, 1);       //     LED1 = LED_RED,  1 --> OFF, 0 --> ON
-DigitalOut rgb_blue(LED_BLUE, 1);     //     LED3 = LED_BLUE, 1 --> OFF, 0 --> ON
-DigitalOut rgb_green(PTE7,1);         //                      1 --> OFF, 0 --> ON
-
-void rgb_sel(int8_t idx) {
-
-switch(idx) {
-                case 0:
-                    rgb_red = 0; rgb_blue=1; rgb_green = 1;
-                    break;
-                case 1:
-                    rgb_red = 1; rgb_blue=0; rgb_green = 1;
-                    break;
-                case 2:
-                    rgb_red = 1; rgb_blue=1; rgb_green = 0;
-                    break;
-            }
-    
-}
-
-// main() runs in its own thread in the OS
-int main() {
-    int idx;
-    while (true) {
-        for(idx=0;idx<3;idx++) {
-            rgb_sel(idx);
-            wait(0.5);
-        }        
-    }
+/***************************************************************************//**
+ * @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();
+        }
+    }
 }
\ No newline at end of file