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

Committer:
batman52
Date:
Fri Dec 27 16:04:44 2019 +0000
Revision:
81:737dff75e013
Parent:
80:77210aa1ad9c
add use of touch sensor

Who changed what in which revision?

UserRevisionLine numberNew contents of line
batman52 80:77210aa1ad9c 1 /***************************************************************************//**
batman52 80:77210aa1ad9c 2 * @file gecko.cpp
batman52 80:77210aa1ad9c 3 * @brief class for creating a gecko-like object and keeps track of its momvement
batman52 80:77210aa1ad9c 4 *******************************************************************************
batman52 80:77210aa1ad9c 5 * @section License
batman52 80:77210aa1ad9c 6 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
batman52 80:77210aa1ad9c 7 *******************************************************************************
batman52 80:77210aa1ad9c 8 *
batman52 80:77210aa1ad9c 9 * Permission is granted to anyone to use this software for any purpose,
batman52 80:77210aa1ad9c 10 * including commercial applications, and to alter it and redistribute it
batman52 80:77210aa1ad9c 11 * freely, subject to the following restrictions:
batman52 80:77210aa1ad9c 12 *
batman52 80:77210aa1ad9c 13 * 1. The origin of this software must not be misrepresented; you must not
batman52 80:77210aa1ad9c 14 * claim that you wrote the original software.
batman52 80:77210aa1ad9c 15 * 2. Altered source versions must be plainly marked as such, and must not be
batman52 80:77210aa1ad9c 16 * misrepresented as being the original software.
batman52 80:77210aa1ad9c 17 * 3. This notice may not be removed or altered from any source distribution.
batman52 80:77210aa1ad9c 18 *
batman52 80:77210aa1ad9c 19 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
batman52 80:77210aa1ad9c 20 * obligation to support this Software. Silicon Labs is providing the
batman52 80:77210aa1ad9c 21 * Software "AS IS", with no express or implied warranties of any kind,
batman52 80:77210aa1ad9c 22 * including, but not limited to, any implied warranties of merchantability
batman52 80:77210aa1ad9c 23 * or fitness for any particular purpose or warranties against infringement
batman52 80:77210aa1ad9c 24 * of any proprietary rights of a third party.
batman52 80:77210aa1ad9c 25 *
batman52 80:77210aa1ad9c 26 * Silicon Labs will not be liable for any consequential, incidental, or
batman52 80:77210aa1ad9c 27 * special damages, or any other relief, or for any claim by any third party,
batman52 80:77210aa1ad9c 28 * arising from your use of this Software.
batman52 80:77210aa1ad9c 29 *
batman52 80:77210aa1ad9c 30 ******************************************************************************/
batman52 80:77210aa1ad9c 31
batman52 80:77210aa1ad9c 32 #include "gecko.h"
batman52 80:77210aa1ad9c 33
batman52 80:77210aa1ad9c 34 /* Number of pixels used in the Gecko head */
batman52 80:77210aa1ad9c 35 #define NPIXHEAD 16
batman52 80:77210aa1ad9c 36 /* Number of pixels used in one Gecko part */
batman52 80:77210aa1ad9c 37 #define NPARTPIXEL 21
batman52 80:77210aa1ad9c 38
batman52 80:77210aa1ad9c 39 /*
batman52 80:77210aa1ad9c 40 * Pixel map for a gecko part and head
batman52 80:77210aa1ad9c 41 * y-crd is encoded in the 4 most significant bits, x-crd is encoded in the 4 least significant bits
batman52 80:77210aa1ad9c 42 * The upper left corner of the part is assigned coordinates (x,y)=(0,0)
batman52 80:77210aa1ad9c 43 */
batman52 80:77210aa1ad9c 44
batman52 80:77210aa1ad9c 45 const uint8_t head_px_map[NPIXHEAD] = {0x03, 0x12, 0x14, 0x21, 0x25, 0x30, 0x32, 0x34, 0x36, 0x40, 0x46, 0x51, 0x55, 0x62, 0x63, 0x64};
batman52 80:77210aa1ad9c 46 const uint8_t gecko_px_map[NPARTPIXEL] = {0x02, 0x03, 0x04, 0x11, 0x15, 0x20, 0x23, 0x26, 0x30, 0x32, 0x33, 0x34, 0x36, 0x40, 0x43, 0x46, 0x51, 0x55, 0x62, 0x63, 0x64};
batman52 80:77210aa1ad9c 47
batman52 80:77210aa1ad9c 48 Gecko::Gecko():_length(3){
batman52 80:77210aa1ad9c 49 _head.init(3, 3, UP, head_px_map, NPIXHEAD);
batman52 80:77210aa1ad9c 50 _last = _length-1;
batman52 80:77210aa1ad9c 51 for (int i=0;i<_length;i++){
batman52 80:77210aa1ad9c 52 _position[i] = (_head.getY() + i +1)*BOARD_WIDTH + _head.getX();
batman52 80:77210aa1ad9c 53 }
batman52 80:77210aa1ad9c 54
batman52 80:77210aa1ad9c 55 }
batman52 80:77210aa1ad9c 56
batman52 80:77210aa1ad9c 57 void Gecko::move(ColorMemLCD &display, Direction dir){
batman52 80:77210aa1ad9c 58
batman52 80:77210aa1ad9c 59 // Remove the last part of the gecko
batman52 80:77210aa1ad9c 60 this->removePart(display, this->getX(_last)*STEPSIZE + BOARDERWIDTH/2, (this->getY(_last)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
batman52 80:77210aa1ad9c 61
batman52 80:77210aa1ad9c 62 // Remove head
batman52 80:77210aa1ad9c 63 _head.remove(display);
batman52 80:77210aa1ad9c 64
batman52 80:77210aa1ad9c 65 // Update the part next to the head
batman52 80:77210aa1ad9c 66 _head.setDir(dir);
batman52 80:77210aa1ad9c 67 _position[_last] = _head.getY()*BOARD_WIDTH + _head.getX();
batman52 80:77210aa1ad9c 68
batman52 80:77210aa1ad9c 69 switch(dir){
batman52 80:77210aa1ad9c 70 case UP:
batman52 80:77210aa1ad9c 71 if (_head.getY() == 0)
batman52 80:77210aa1ad9c 72 {
batman52 80:77210aa1ad9c 73 _head.setY(BOARD_HEIGHT-1);
batman52 80:77210aa1ad9c 74 }
batman52 80:77210aa1ad9c 75 else
batman52 80:77210aa1ad9c 76 {
batman52 80:77210aa1ad9c 77 _head.setY(_head.getY() - 1);
batman52 80:77210aa1ad9c 78 }
batman52 80:77210aa1ad9c 79 break;
batman52 80:77210aa1ad9c 80 case DOWN:
batman52 80:77210aa1ad9c 81 if ( _head.getY() == (BOARD_HEIGHT-1))
batman52 80:77210aa1ad9c 82 {
batman52 80:77210aa1ad9c 83 _head.setY(0);
batman52 80:77210aa1ad9c 84 }
batman52 80:77210aa1ad9c 85 else
batman52 80:77210aa1ad9c 86 {
batman52 80:77210aa1ad9c 87 _head.setY(_head.getY() + 1);
batman52 80:77210aa1ad9c 88 }
batman52 80:77210aa1ad9c 89 break;
batman52 80:77210aa1ad9c 90 case RIGHT:
batman52 80:77210aa1ad9c 91 if (_head.getX() == (BOARD_WIDTH-1))
batman52 80:77210aa1ad9c 92 {
batman52 80:77210aa1ad9c 93 _head.setX(0);
batman52 80:77210aa1ad9c 94 }
batman52 80:77210aa1ad9c 95 else
batman52 80:77210aa1ad9c 96 {
batman52 80:77210aa1ad9c 97 _head.setX(_head.getX() + 1);
batman52 80:77210aa1ad9c 98 }
batman52 80:77210aa1ad9c 99 break;
batman52 80:77210aa1ad9c 100 case LEFT:
batman52 80:77210aa1ad9c 101 if (_head.getX() == 0)
batman52 80:77210aa1ad9c 102 {
batman52 80:77210aa1ad9c 103 _head.setX(BOARD_WIDTH-1);
batman52 80:77210aa1ad9c 104 }
batman52 80:77210aa1ad9c 105 else
batman52 80:77210aa1ad9c 106 {
batman52 80:77210aa1ad9c 107 _head.setX(_head.getX() - 1);
batman52 80:77210aa1ad9c 108 }
batman52 80:77210aa1ad9c 109 break;
batman52 80:77210aa1ad9c 110 }
batman52 80:77210aa1ad9c 111
batman52 80:77210aa1ad9c 112 // Draw the parts of the gecko which have been moved
batman52 80:77210aa1ad9c 113 _head.draw(display);
batman52 80:77210aa1ad9c 114 this->drawPart(display, this->getX(_last)*STEPSIZE + BOARDERWIDTH/2, (this->getY(_last)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
batman52 80:77210aa1ad9c 115
batman52 80:77210aa1ad9c 116 // Update the index of the last part
batman52 80:77210aa1ad9c 117 if (_last == 0){
batman52 80:77210aa1ad9c 118 _last += _length;
batman52 80:77210aa1ad9c 119 }
batman52 80:77210aa1ad9c 120 _last -= 1;
batman52 80:77210aa1ad9c 121 }
batman52 80:77210aa1ad9c 122
batman52 80:77210aa1ad9c 123 void Gecko::draw(ColorMemLCD &display) const{
batman52 80:77210aa1ad9c 124 _head.draw(display);
batman52 80:77210aa1ad9c 125
batman52 80:77210aa1ad9c 126 // Loop over indices of all parts of the gecko
batman52 80:77210aa1ad9c 127 for (uint8_t i=0;i<_length;i++){
batman52 80:77210aa1ad9c 128 this->drawPart(display, this->getX(i)*STEPSIZE + BOARDERWIDTH/2, (this->getY(i)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
batman52 80:77210aa1ad9c 129 }
batman52 80:77210aa1ad9c 130 }
batman52 80:77210aa1ad9c 131
batman52 80:77210aa1ad9c 132 bool Gecko::selfCollision() const{
batman52 80:77210aa1ad9c 133 /* Check if some pixels have the same coordinate */
batman52 80:77210aa1ad9c 134 for (int i=0;i<_length;i++)
batman52 80:77210aa1ad9c 135 {
batman52 80:77210aa1ad9c 136 if ((_head.getX()==this->getX(i)) && (_head.getY()==this->getY(i))){
batman52 80:77210aa1ad9c 137 return true;
batman52 80:77210aa1ad9c 138 }
batman52 80:77210aa1ad9c 139 }
batman52 80:77210aa1ad9c 140 return false;
batman52 80:77210aa1ad9c 141 }
batman52 80:77210aa1ad9c 142
batman52 80:77210aa1ad9c 143 void Gecko::increaseLength(ColorMemLCD &display, Direction dir)
batman52 80:77210aa1ad9c 144 {
batman52 80:77210aa1ad9c 145 if ((_length + 1)> MAXLENGTH) return;
batman52 80:77210aa1ad9c 146
batman52 80:77210aa1ad9c 147 // Store the tail of the gecko
batman52 80:77210aa1ad9c 148 uint8_t tempPos = _position[_last] ;
batman52 80:77210aa1ad9c 149
batman52 80:77210aa1ad9c 150 // Move the gecko
batman52 80:77210aa1ad9c 151 this->move(display, dir);
batman52 80:77210aa1ad9c 152
batman52 80:77210aa1ad9c 153 uint8_t temp[MAXLENGTH];
batman52 80:77210aa1ad9c 154
batman52 80:77210aa1ad9c 155 // Copy the front of the gecko
batman52 80:77210aa1ad9c 156 for (uint8_t i = _last + 1;i<_length;i++)
batman52 80:77210aa1ad9c 157 {
batman52 80:77210aa1ad9c 158 temp[i] = _position[i];
batman52 80:77210aa1ad9c 159 }
batman52 80:77210aa1ad9c 160
batman52 80:77210aa1ad9c 161 // Insert the "old" tail
batman52 80:77210aa1ad9c 162 _position[_last + 1] = tempPos;
batman52 80:77210aa1ad9c 163
batman52 80:77210aa1ad9c 164 // Insert the front of the gecko
batman52 80:77210aa1ad9c 165 for (uint8_t i = _last + 1;i<_length;i++)
batman52 80:77210aa1ad9c 166 {
batman52 80:77210aa1ad9c 167 _position[i+1] = temp[i];
batman52 80:77210aa1ad9c 168 }
batman52 80:77210aa1ad9c 169
batman52 80:77210aa1ad9c 170 // Draw last part of the gecko
batman52 80:77210aa1ad9c 171 this->drawPart(display, this->getX(_last+1)*STEPSIZE + BOARDERWIDTH/2, (this->getY(_last+1)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
batman52 80:77210aa1ad9c 172
batman52 80:77210aa1ad9c 173
batman52 80:77210aa1ad9c 174 // Update length and position of last
batman52 80:77210aa1ad9c 175 _length += 1;
batman52 80:77210aa1ad9c 176 _last += 1;
batman52 80:77210aa1ad9c 177 }
batman52 80:77210aa1ad9c 178
batman52 80:77210aa1ad9c 179 bool Gecko::headOccupiesTile(uint8_t x_ref, uint8_t y_ref) const{
batman52 80:77210aa1ad9c 180 return ((x_ref == _head.getX()) && (y_ref == _head.getY()));
batman52 80:77210aa1ad9c 181 }
batman52 80:77210aa1ad9c 182
batman52 80:77210aa1ad9c 183 bool Gecko::occupiesTile(uint8_t x_ref, uint8_t y_ref) const{
batman52 80:77210aa1ad9c 184 if ( (x_ref == _head.getX()) && (y_ref == _head.getY()) ){
batman52 80:77210aa1ad9c 185 return true;
batman52 80:77210aa1ad9c 186 }
batman52 80:77210aa1ad9c 187
batman52 80:77210aa1ad9c 188 for (uint8_t i=0;i<_length;i++)
batman52 80:77210aa1ad9c 189 {
batman52 80:77210aa1ad9c 190 if ((x_ref == this->getX(i)) && (y_ref == this->getY(i)) )
batman52 80:77210aa1ad9c 191 {
batman52 80:77210aa1ad9c 192 return true;
batman52 80:77210aa1ad9c 193 }
batman52 80:77210aa1ad9c 194 }
batman52 80:77210aa1ad9c 195 return false;
batman52 80:77210aa1ad9c 196 }
batman52 80:77210aa1ad9c 197
batman52 80:77210aa1ad9c 198 void Gecko::drawPart(ColorMemLCD &display, uint8_t x, uint8_t y) const
batman52 80:77210aa1ad9c 199 {
batman52 80:77210aa1ad9c 200 //
batman52 80:77210aa1ad9c 201 // x and y denotes the coordinates of the top left corner
batman52 80:77210aa1ad9c 202 // Assumes that x and y are given such that the entire part is on the screen
batman52 80:77210aa1ad9c 203
batman52 80:77210aa1ad9c 204 #if(MULTI_UPDATE)
batman52 80:77210aa1ad9c 205 display.window( BOARDERWIDTH/2, y, LCD_DISP_WIDTH - BOARDERWIDTH/2, STEPSIZE );
batman52 80:77210aa1ad9c 206 #endif
batman52 80:77210aa1ad9c 207
batman52 80:77210aa1ad9c 208 for (int i=0;i<NPARTPIXEL;i++){
batman52 80:77210aa1ad9c 209 display.pixel(x + static_cast<uint8_t>(gecko_px_map[i] & 0xF), y + static_cast<uint8_t>( (gecko_px_map[i] >> 4) & 0xF), FOREGROUND_COLOR);
batman52 80:77210aa1ad9c 210 }
batman52 80:77210aa1ad9c 211
batman52 80:77210aa1ad9c 212 #if(MULTI_UPDATE)
batman52 80:77210aa1ad9c 213 display.update();
batman52 80:77210aa1ad9c 214 #endif
batman52 80:77210aa1ad9c 215
batman52 80:77210aa1ad9c 216 }
batman52 80:77210aa1ad9c 217
batman52 80:77210aa1ad9c 218 void Gecko::removePart(ColorMemLCD &display, uint8_t x, uint8_t y) const
batman52 80:77210aa1ad9c 219 {
batman52 80:77210aa1ad9c 220
batman52 80:77210aa1ad9c 221 // x and y denotes the coordinates of the top left corner
batman52 80:77210aa1ad9c 222 // Assumes that x and y are given such that the part is on the screen
batman52 80:77210aa1ad9c 223
batman52 80:77210aa1ad9c 224 #if(MULTI_UPDATE)
batman52 80:77210aa1ad9c 225 display.window( BOARDERWIDTH/2, y, LCD_DISP_WIDTH - BOARDERWIDTH/2, STEPSIZE );
batman52 80:77210aa1ad9c 226 #endif
batman52 80:77210aa1ad9c 227
batman52 80:77210aa1ad9c 228 for (int i=0;i<NPARTPIXEL;i++){
batman52 80:77210aa1ad9c 229 display.pixel(x + static_cast<uint8_t>(gecko_px_map[i] & 0xF), y + static_cast<uint8_t>( (gecko_px_map[i] >> 4) & 0xF), BACKGROUND_COLOR);
batman52 80:77210aa1ad9c 230 }
batman52 80:77210aa1ad9c 231
batman52 80:77210aa1ad9c 232 #if(MULTI_UPDATE)
batman52 80:77210aa1ad9c 233 display.update();
batman52 80:77210aa1ad9c 234 #endif
batman52 80:77210aa1ad9c 235
batman52 80:77210aa1ad9c 236 }
batman52 80:77210aa1ad9c 237
batman52 80:77210aa1ad9c 238 uint8_t Gecko::getX(uint8_t indx) const{
batman52 80:77210aa1ad9c 239 return _position[indx] - BOARD_WIDTH*(_position[indx]/BOARD_WIDTH);
batman52 80:77210aa1ad9c 240 }
batman52 80:77210aa1ad9c 241
batman52 80:77210aa1ad9c 242 uint8_t Gecko::getY(uint8_t indx) const{
batman52 80:77210aa1ad9c 243 return _position[indx]/BOARD_WIDTH;
batman52 80:77210aa1ad9c 244 }
batman52 80:77210aa1ad9c 245
batman52 80:77210aa1ad9c 246