My ELEC2645 joystick project Tetris Game NAME: JIANWEI CHEN SID: 200879849
Dependencies: N5110 SDFileSystem mbed
main.cpp@2:f427089e2bfa, 2016-04-26 (annotated)
- Committer:
- cjw851102
- Date:
- Tue Apr 26 00:14:57 2016 +0000
- Revision:
- 2:f427089e2bfa
- Parent:
- 1:2a758565f691
- Child:
- 3:5494a0fb3a33
game finish
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
cjw851102 | 0:12a1972fa0d0 | 1 | #include "mbed.h" |
cjw851102 | 0:12a1972fa0d0 | 2 | #include "Patterns.h" |
cjw851102 | 0:12a1972fa0d0 | 3 | #include "N5110.h" |
cjw851102 | 0:12a1972fa0d0 | 4 | |
cjw851102 | 1:2a758565f691 | 5 | #define DIRECTION_TOLERANCE 0.05 |
cjw851102 | 1:2a758565f691 | 6 | |
cjw851102 | 0:12a1972fa0d0 | 7 | //VCC, SCE, RST, D/C, MOSI,SCLK, LED |
cjw851102 | 0:12a1972fa0d0 | 8 | N5110 lcd(PTE26,PTA0,PTC4,PTD0,PTD2,PTD1,PTC3); |
cjw851102 | 1:2a758565f691 | 9 | AnalogIn yPot(PTB2); |
cjw851102 | 1:2a758565f691 | 10 | AnalogIn xPot(PTB3); |
cjw851102 | 1:2a758565f691 | 11 | DigitalIn button(PTB11); |
cjw851102 | 0:12a1972fa0d0 | 12 | Patterns patterns; |
cjw851102 | 1:2a758565f691 | 13 | |
cjw851102 | 1:2a758565f691 | 14 | Ticker game; |
cjw851102 | 1:2a758565f691 | 15 | void game_isr(); |
cjw851102 | 1:2a758565f691 | 16 | volatile int g_game_flag = 0; |
cjw851102 | 1:2a758565f691 | 17 | |
cjw851102 | 0:12a1972fa0d0 | 18 | void drawPattern(int type,int rotation,int x,int y,int fill); // draw pattern at (x,y), fill = 0 white, fill = 1 black |
cjw851102 | 0:12a1972fa0d0 | 19 | |
cjw851102 | 0:12a1972fa0d0 | 20 | void left_collisionDetect(); |
cjw851102 | 0:12a1972fa0d0 | 21 | int left_collision_flag = 0; |
cjw851102 | 0:12a1972fa0d0 | 22 | |
cjw851102 | 0:12a1972fa0d0 | 23 | void right_collisionDetect(); |
cjw851102 | 0:12a1972fa0d0 | 24 | int right_collision_flag = 0; |
cjw851102 | 0:12a1972fa0d0 | 25 | |
cjw851102 | 2:f427089e2bfa | 26 | void bottom_collisionDetect(); |
cjw851102 | 2:f427089e2bfa | 27 | int bottom_collision_flag = 0; |
cjw851102 | 2:f427089e2bfa | 28 | |
cjw851102 | 2:f427089e2bfa | 29 | void top_collisionDetect(); |
cjw851102 | 2:f427089e2bfa | 30 | int top_collision_flag = 0; |
cjw851102 | 0:12a1972fa0d0 | 31 | |
cjw851102 | 2:f427089e2bfa | 32 | void rotation_collisionDetect(); |
cjw851102 | 2:f427089e2bfa | 33 | int rotation_collision_flag = 0; |
cjw851102 | 2:f427089e2bfa | 34 | |
cjw851102 | 2:f427089e2bfa | 35 | void fastmove_bottom_collisionDetect(); |
cjw851102 | 2:f427089e2bfa | 36 | int fastmove_bottom_collision_flag = 0; |
cjw851102 | 0:12a1972fa0d0 | 37 | |
cjw851102 | 0:12a1972fa0d0 | 38 | struct Position { |
cjw851102 | 0:12a1972fa0d0 | 39 | float x; |
cjw851102 | 0:12a1972fa0d0 | 40 | float y; |
cjw851102 | 0:12a1972fa0d0 | 41 | int type; |
cjw851102 | 0:12a1972fa0d0 | 42 | int rotation; |
cjw851102 | 0:12a1972fa0d0 | 43 | }; |
cjw851102 | 0:12a1972fa0d0 | 44 | typedef struct Position position; |
cjw851102 | 0:12a1972fa0d0 | 45 | |
cjw851102 | 1:2a758565f691 | 46 | position pos; |
cjw851102 | 0:12a1972fa0d0 | 47 | |
cjw851102 | 0:12a1972fa0d0 | 48 | void init_game(); |
cjw851102 | 1:2a758565f691 | 49 | int typeArray[100]; |
cjw851102 | 1:2a758565f691 | 50 | int rotationArray[100]; |
cjw851102 | 0:12a1972fa0d0 | 51 | |
cjw851102 | 0:12a1972fa0d0 | 52 | int pattern_buffer[6][6]; |
cjw851102 | 0:12a1972fa0d0 | 53 | void get_pattern(int type, int rotatin); |
cjw851102 | 0:12a1972fa0d0 | 54 | |
cjw851102 | 0:12a1972fa0d0 | 55 | void scan(); |
cjw851102 | 0:12a1972fa0d0 | 56 | int buffer[84][48]; |
cjw851102 | 0:12a1972fa0d0 | 57 | |
cjw851102 | 1:2a758565f691 | 58 | // create enumerated type (0,1,2,3 etc. for direction) |
cjw851102 | 1:2a758565f691 | 59 | // could be extended for diagonals etc. |
cjw851102 | 1:2a758565f691 | 60 | enum DirectionName { |
cjw851102 | 1:2a758565f691 | 61 | UP, |
cjw851102 | 1:2a758565f691 | 62 | DOWN, |
cjw851102 | 1:2a758565f691 | 63 | LEFT, |
cjw851102 | 1:2a758565f691 | 64 | RIGHT, |
cjw851102 | 1:2a758565f691 | 65 | CENTRE, |
cjw851102 | 1:2a758565f691 | 66 | UNKNOWN |
cjw851102 | 1:2a758565f691 | 67 | }; |
cjw851102 | 1:2a758565f691 | 68 | // struct for Joystick |
cjw851102 | 1:2a758565f691 | 69 | typedef struct JoyStick Joystick; |
cjw851102 | 1:2a758565f691 | 70 | struct JoyStick { |
cjw851102 | 2:f427089e2bfa | 71 | double x; // current x value |
cjw851102 | 2:f427089e2bfa | 72 | double x0; // 'centred' x value |
cjw851102 | 2:f427089e2bfa | 73 | double y; // current y value |
cjw851102 | 2:f427089e2bfa | 74 | double y0; // 'centred' y value |
cjw851102 | 1:2a758565f691 | 75 | int button; // button state (assume pull-down used, so 1 = pressed, 0 = unpressed) |
cjw851102 | 1:2a758565f691 | 76 | DirectionName direction; // current direction |
cjw851102 | 1:2a758565f691 | 77 | }; |
cjw851102 | 1:2a758565f691 | 78 | // create struct variable |
cjw851102 | 1:2a758565f691 | 79 | Joystick joystick; |
cjw851102 | 1:2a758565f691 | 80 | void calibrateJoystick(); |
cjw851102 | 1:2a758565f691 | 81 | void updateJoystick(); |
cjw851102 | 1:2a758565f691 | 82 | |
cjw851102 | 2:f427089e2bfa | 83 | void cancelLine();// if one line is filled, cancel it and add the score |
cjw851102 | 2:f427089e2bfa | 84 | int score=0; |
cjw851102 | 2:f427089e2bfa | 85 | |
cjw851102 | 2:f427089e2bfa | 86 | void finishAnimation(); |
cjw851102 | 2:f427089e2bfa | 87 | |
cjw851102 | 2:f427089e2bfa | 88 | int xOld; |
cjw851102 | 2:f427089e2bfa | 89 | int typeCount = 0; |
cjw851102 | 2:f427089e2bfa | 90 | int nextTypeCount; |
cjw851102 | 2:f427089e2bfa | 91 | |
cjw851102 | 0:12a1972fa0d0 | 92 | int main() |
cjw851102 | 0:12a1972fa0d0 | 93 | { |
cjw851102 | 0:12a1972fa0d0 | 94 | wait(2.0); // short delay for power to settle |
cjw851102 | 0:12a1972fa0d0 | 95 | lcd.init(); |
cjw851102 | 0:12a1972fa0d0 | 96 | lcd.normalMode(); // normal colour mode |
cjw851102 | 1:2a758565f691 | 97 | lcd.setBrightness(1.0); // put LED backlight on 100% |
cjw851102 | 0:12a1972fa0d0 | 98 | init_game(); |
cjw851102 | 1:2a758565f691 | 99 | game.attach(&game_isr,0.4); |
cjw851102 | 1:2a758565f691 | 100 | lcd.refresh(); |
cjw851102 | 0:12a1972fa0d0 | 101 | |
cjw851102 | 2:f427089e2bfa | 102 | |
cjw851102 | 1:2a758565f691 | 103 | calibrateJoystick(); |
cjw851102 | 0:12a1972fa0d0 | 104 | |
cjw851102 | 1:2a758565f691 | 105 | |
cjw851102 | 0:12a1972fa0d0 | 106 | while (1) { |
cjw851102 | 0:12a1972fa0d0 | 107 | |
cjw851102 | 1:2a758565f691 | 108 | if(g_game_flag==1) { |
cjw851102 | 1:2a758565f691 | 109 | g_game_flag = 0; |
cjw851102 | 1:2a758565f691 | 110 | pos.type = typeArray[typeCount]; |
cjw851102 | 2:f427089e2bfa | 111 | nextTypeCount=typeCount+1; |
cjw851102 | 2:f427089e2bfa | 112 | if (nextTypeCount>99) { |
cjw851102 | 2:f427089e2bfa | 113 | nextTypeCount=0; |
cjw851102 | 2:f427089e2bfa | 114 | } |
cjw851102 | 2:f427089e2bfa | 115 | drawPattern(typeArray[nextTypeCount],0,55,41,1);// draw next pattern |
cjw851102 | 2:f427089e2bfa | 116 | if (pos.y >= -5) { // clear previous pattern |
cjw851102 | 1:2a758565f691 | 117 | drawPattern(pos.type,pos.rotation,xOld,pos.y-1,0); |
cjw851102 | 1:2a758565f691 | 118 | } |
cjw851102 | 1:2a758565f691 | 119 | updateJoystick(); |
cjw851102 | 2:f427089e2bfa | 120 | top_collisionDetect(); |
cjw851102 | 2:f427089e2bfa | 121 | if (top_collision_flag == 1) { |
cjw851102 | 2:f427089e2bfa | 122 | finishAnimation(); |
cjw851102 | 2:f427089e2bfa | 123 | lcd.clear(); |
cjw851102 | 2:f427089e2bfa | 124 | char scoreBuffer[14]; |
cjw851102 | 2:f427089e2bfa | 125 | sprintf(scoreBuffer,"%d",score); |
cjw851102 | 2:f427089e2bfa | 126 | lcd.printString("SCORE IS: ",10,2); |
cjw851102 | 2:f427089e2bfa | 127 | lcd.printString(scoreBuffer,35,3); |
cjw851102 | 2:f427089e2bfa | 128 | lcd.refresh(); |
cjw851102 | 2:f427089e2bfa | 129 | break; |
cjw851102 | 2:f427089e2bfa | 130 | } |
cjw851102 | 1:2a758565f691 | 131 | switch(joystick.direction) { |
cjw851102 | 1:2a758565f691 | 132 | case UP: |
cjw851102 | 2:f427089e2bfa | 133 | rotation_collisionDetect(); |
cjw851102 | 2:f427089e2bfa | 134 | if(rotation_collision_flag == 0) { |
cjw851102 | 2:f427089e2bfa | 135 | pos.rotation++; |
cjw851102 | 2:f427089e2bfa | 136 | if (pos.rotation>3) { |
cjw851102 | 2:f427089e2bfa | 137 | pos.rotation=0; |
cjw851102 | 2:f427089e2bfa | 138 | } |
cjw851102 | 2:f427089e2bfa | 139 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); |
cjw851102 | 2:f427089e2bfa | 140 | } else {// if collision |
cjw851102 | 2:f427089e2bfa | 141 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); |
cjw851102 | 2:f427089e2bfa | 142 | } |
cjw851102 | 1:2a758565f691 | 143 | break; |
cjw851102 | 1:2a758565f691 | 144 | case DOWN: |
cjw851102 | 2:f427089e2bfa | 145 | fastmove_bottom_collisionDetect(); |
cjw851102 | 2:f427089e2bfa | 146 | if (fastmove_bottom_collision_flag == 0) { |
cjw851102 | 2:f427089e2bfa | 147 | pos.y +=4; |
cjw851102 | 2:f427089e2bfa | 148 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); |
cjw851102 | 2:f427089e2bfa | 149 | } else { |
cjw851102 | 2:f427089e2bfa | 150 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); |
cjw851102 | 2:f427089e2bfa | 151 | } |
cjw851102 | 1:2a758565f691 | 152 | break; |
cjw851102 | 1:2a758565f691 | 153 | case RIGHT: |
cjw851102 | 1:2a758565f691 | 154 | right_collisionDetect(); |
cjw851102 | 1:2a758565f691 | 155 | /* |
cjw851102 | 1:2a758565f691 | 156 | for (int i=0; i<=5; i++) { |
cjw851102 | 1:2a758565f691 | 157 | for (int j=0; j<=5; j++) { |
cjw851102 | 1:2a758565f691 | 158 | if(right_boundary[i][j] ==1) { |
cjw851102 | 1:2a758565f691 | 159 | lcd.setPixel(i,j); |
cjw851102 | 1:2a758565f691 | 160 | } |
cjw851102 | 1:2a758565f691 | 161 | } |
cjw851102 | 1:2a758565f691 | 162 | } |
cjw851102 | 1:2a758565f691 | 163 | */ |
cjw851102 | 1:2a758565f691 | 164 | if( right_collision_flag == 0) { |
cjw851102 | 1:2a758565f691 | 165 | pos.x +=2; |
cjw851102 | 1:2a758565f691 | 166 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); |
cjw851102 | 1:2a758565f691 | 167 | } else { |
cjw851102 | 1:2a758565f691 | 168 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); |
cjw851102 | 1:2a758565f691 | 169 | } |
cjw851102 | 1:2a758565f691 | 170 | break; |
cjw851102 | 1:2a758565f691 | 171 | case LEFT: |
cjw851102 | 1:2a758565f691 | 172 | left_collisionDetect(); |
cjw851102 | 1:2a758565f691 | 173 | if( left_collision_flag == 0) { |
cjw851102 | 1:2a758565f691 | 174 | pos.x -=2; |
cjw851102 | 1:2a758565f691 | 175 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); |
cjw851102 | 1:2a758565f691 | 176 | } else { |
cjw851102 | 1:2a758565f691 | 177 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); |
cjw851102 | 1:2a758565f691 | 178 | } |
cjw851102 | 1:2a758565f691 | 179 | break; |
cjw851102 | 1:2a758565f691 | 180 | case CENTRE: |
cjw851102 | 1:2a758565f691 | 181 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); |
cjw851102 | 1:2a758565f691 | 182 | break; |
cjw851102 | 1:2a758565f691 | 183 | case UNKNOWN: |
cjw851102 | 1:2a758565f691 | 184 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); |
cjw851102 | 1:2a758565f691 | 185 | break; |
cjw851102 | 1:2a758565f691 | 186 | } |
cjw851102 | 1:2a758565f691 | 187 | |
cjw851102 | 1:2a758565f691 | 188 | xOld = pos.x; |
cjw851102 | 2:f427089e2bfa | 189 | bottom_collisionDetect(); |
cjw851102 | 2:f427089e2bfa | 190 | if (bottom_collision_flag == 0) { |
cjw851102 | 1:2a758565f691 | 191 | pos.y++; |
cjw851102 | 1:2a758565f691 | 192 | } else { |
cjw851102 | 2:f427089e2bfa | 193 | drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);// fix pattern |
cjw851102 | 2:f427089e2bfa | 194 | cancelLine(); |
cjw851102 | 2:f427089e2bfa | 195 | pos.x = 10; |
cjw851102 | 2:f427089e2bfa | 196 | pos.y = -6; |
cjw851102 | 2:f427089e2bfa | 197 | pos.rotation=0; |
cjw851102 | 2:f427089e2bfa | 198 | drawPattern(typeArray[nextTypeCount],pos.rotation,55,41,0);// clear the old next pattern |
cjw851102 | 2:f427089e2bfa | 199 | typeCount ++; |
cjw851102 | 2:f427089e2bfa | 200 | if (typeCount >99) { |
cjw851102 | 2:f427089e2bfa | 201 | typeCount = 0; |
cjw851102 | 2:f427089e2bfa | 202 | } |
cjw851102 | 1:2a758565f691 | 203 | } |
cjw851102 | 2:f427089e2bfa | 204 | |
cjw851102 | 1:2a758565f691 | 205 | } |
cjw851102 | 1:2a758565f691 | 206 | lcd.refresh(); |
cjw851102 | 0:12a1972fa0d0 | 207 | } |
cjw851102 | 0:12a1972fa0d0 | 208 | |
cjw851102 | 0:12a1972fa0d0 | 209 | } |
cjw851102 | 0:12a1972fa0d0 | 210 | |
cjw851102 | 0:12a1972fa0d0 | 211 | void init_game() |
cjw851102 | 0:12a1972fa0d0 | 212 | { |
cjw851102 | 1:2a758565f691 | 213 | pos.x = 10; |
cjw851102 | 1:2a758565f691 | 214 | pos.y = -6; |
cjw851102 | 2:f427089e2bfa | 215 | pos.rotation=0; |
cjw851102 | 1:2a758565f691 | 216 | for(int i=0; i<=99; i++) { |
cjw851102 | 1:2a758565f691 | 217 | typeArray[i] = rand()%7; |
cjw851102 | 1:2a758565f691 | 218 | rotationArray[i] = rand()%5; |
cjw851102 | 1:2a758565f691 | 219 | } |
cjw851102 | 1:2a758565f691 | 220 | lcd.drawLine(30,0,30,47,1); |
cjw851102 | 1:2a758565f691 | 221 | lcd.printString("Level:",42,0); |
cjw851102 | 1:2a758565f691 | 222 | lcd.printString("easy",42,1); |
cjw851102 | 1:2a758565f691 | 223 | lcd.printString("Score:",42,2); |
cjw851102 | 2:f427089e2bfa | 224 | lcd.printString("0",42,3); |
cjw851102 | 1:2a758565f691 | 225 | lcd.printString("Next:",42,4); |
cjw851102 | 1:2a758565f691 | 226 | |
cjw851102 | 0:12a1972fa0d0 | 227 | } |
cjw851102 | 0:12a1972fa0d0 | 228 | |
cjw851102 | 0:12a1972fa0d0 | 229 | void get_pattern(int type, int rotation) |
cjw851102 | 0:12a1972fa0d0 | 230 | { |
cjw851102 | 0:12a1972fa0d0 | 231 | for(int i=0; i<=5; i++) { |
cjw851102 | 0:12a1972fa0d0 | 232 | for(int j=0; j<=5; j++) { |
cjw851102 | 0:12a1972fa0d0 | 233 | pattern_buffer[i][j] = patterns.getPatterns(type,rotation,j,i); // return pattern[type][rotation][y][x]; |
cjw851102 | 0:12a1972fa0d0 | 234 | } |
cjw851102 | 0:12a1972fa0d0 | 235 | } |
cjw851102 | 0:12a1972fa0d0 | 236 | } |
cjw851102 | 0:12a1972fa0d0 | 237 | |
cjw851102 | 0:12a1972fa0d0 | 238 | void scan() |
cjw851102 | 0:12a1972fa0d0 | 239 | { |
cjw851102 | 0:12a1972fa0d0 | 240 | for (int i=0; i<=83; i++) { |
cjw851102 | 0:12a1972fa0d0 | 241 | for (int j=0; j<=47; j++) { |
cjw851102 | 0:12a1972fa0d0 | 242 | if(lcd.getPixel(i,j)) { |
cjw851102 | 0:12a1972fa0d0 | 243 | buffer[i][j] = 1; |
cjw851102 | 0:12a1972fa0d0 | 244 | } else { |
cjw851102 | 0:12a1972fa0d0 | 245 | buffer[i][j] = 0; |
cjw851102 | 0:12a1972fa0d0 | 246 | } |
cjw851102 | 0:12a1972fa0d0 | 247 | } |
cjw851102 | 0:12a1972fa0d0 | 248 | } |
cjw851102 | 0:12a1972fa0d0 | 249 | } |
cjw851102 | 0:12a1972fa0d0 | 250 | |
cjw851102 | 0:12a1972fa0d0 | 251 | |
cjw851102 | 0:12a1972fa0d0 | 252 | void drawPattern(int type,int rotation,int x,int y,int fill) |
cjw851102 | 0:12a1972fa0d0 | 253 | { |
cjw851102 | 0:12a1972fa0d0 | 254 | get_pattern(type,rotation); |
cjw851102 | 0:12a1972fa0d0 | 255 | for(int i=x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square |
cjw851102 | 0:12a1972fa0d0 | 256 | for(int j=y; j <= y+5; j++) { |
cjw851102 | 1:2a758565f691 | 257 | if (j>=0) { |
cjw851102 | 1:2a758565f691 | 258 | if(pattern_buffer[i-x][j-y]==1) { |
cjw851102 | 1:2a758565f691 | 259 | if (fill==0) { |
cjw851102 | 2:f427089e2bfa | 260 | if (j<=47 && i>=0) { |
cjw851102 | 1:2a758565f691 | 261 | lcd.clearPixel(i,j); |
cjw851102 | 1:2a758565f691 | 262 | } |
cjw851102 | 1:2a758565f691 | 263 | } else if (fill==1) { |
cjw851102 | 2:f427089e2bfa | 264 | if (j<=47 && i>=0) { |
cjw851102 | 1:2a758565f691 | 265 | lcd.setPixel(i,j); |
cjw851102 | 1:2a758565f691 | 266 | } |
cjw851102 | 1:2a758565f691 | 267 | } |
cjw851102 | 0:12a1972fa0d0 | 268 | } |
cjw851102 | 0:12a1972fa0d0 | 269 | } |
cjw851102 | 0:12a1972fa0d0 | 270 | } |
cjw851102 | 0:12a1972fa0d0 | 271 | } |
cjw851102 | 0:12a1972fa0d0 | 272 | } |
cjw851102 | 0:12a1972fa0d0 | 273 | |
cjw851102 | 0:12a1972fa0d0 | 274 | void left_collisionDetect() |
cjw851102 | 0:12a1972fa0d0 | 275 | { |
cjw851102 | 2:f427089e2bfa | 276 | int left_boundary[6][6]; |
cjw851102 | 1:2a758565f691 | 277 | get_pattern(pos.type,pos.rotation); |
cjw851102 | 2:f427089e2bfa | 278 | |
cjw851102 | 0:12a1972fa0d0 | 279 | // get the left boundary pattern |
cjw851102 | 1:2a758565f691 | 280 | for (int j=0; j<=5; j++) { // |
cjw851102 | 1:2a758565f691 | 281 | for (int i=0; i<=5; i++) { |
cjw851102 | 0:12a1972fa0d0 | 282 | if (pattern_buffer[i][j]==1) { |
cjw851102 | 0:12a1972fa0d0 | 283 | left_boundary[i][j]=1; |
cjw851102 | 1:2a758565f691 | 284 | for(int k=i+1; k<=5; k++) { |
cjw851102 | 0:12a1972fa0d0 | 285 | left_boundary[k][j] = 0; |
cjw851102 | 0:12a1972fa0d0 | 286 | } |
cjw851102 | 1:2a758565f691 | 287 | break; |
cjw851102 | 0:12a1972fa0d0 | 288 | } else { |
cjw851102 | 0:12a1972fa0d0 | 289 | left_boundary[i][j]=0; |
cjw851102 | 0:12a1972fa0d0 | 290 | } |
cjw851102 | 0:12a1972fa0d0 | 291 | } |
cjw851102 | 0:12a1972fa0d0 | 292 | } |
cjw851102 | 0:12a1972fa0d0 | 293 | |
cjw851102 | 0:12a1972fa0d0 | 294 | //check left collision |
cjw851102 | 1:2a758565f691 | 295 | int x = pos.x; |
cjw851102 | 1:2a758565f691 | 296 | int y = pos.y; |
cjw851102 | 1:2a758565f691 | 297 | if (x<0) { |
cjw851102 | 1:2a758565f691 | 298 | left_collision_flag = 1; |
cjw851102 | 1:2a758565f691 | 299 | } else { |
cjw851102 | 1:2a758565f691 | 300 | for(int i=x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square |
cjw851102 | 1:2a758565f691 | 301 | for(int j=y; j <= y+5; j++) { |
cjw851102 | 1:2a758565f691 | 302 | if(left_boundary[i-x][j-y]==1) { |
cjw851102 | 1:2a758565f691 | 303 | if(i == 0) { |
cjw851102 | 1:2a758565f691 | 304 | left_collision_flag = 1; |
cjw851102 | 1:2a758565f691 | 305 | break; |
cjw851102 | 2:f427089e2bfa | 306 | } else if (lcd.getPixel(i-1,j)) { |
cjw851102 | 1:2a758565f691 | 307 | left_collision_flag = 1; |
cjw851102 | 1:2a758565f691 | 308 | break; |
cjw851102 | 1:2a758565f691 | 309 | } else { |
cjw851102 | 1:2a758565f691 | 310 | left_collision_flag = 0; |
cjw851102 | 0:12a1972fa0d0 | 311 | } |
cjw851102 | 0:12a1972fa0d0 | 312 | } |
cjw851102 | 2:f427089e2bfa | 313 | } |
cjw851102 | 2:f427089e2bfa | 314 | if (left_collision_flag == 1) { |
cjw851102 | 2:f427089e2bfa | 315 | break; |
cjw851102 | 0:12a1972fa0d0 | 316 | } |
cjw851102 | 0:12a1972fa0d0 | 317 | } |
cjw851102 | 0:12a1972fa0d0 | 318 | } |
cjw851102 | 0:12a1972fa0d0 | 319 | } |
cjw851102 | 0:12a1972fa0d0 | 320 | |
cjw851102 | 1:2a758565f691 | 321 | |
cjw851102 | 0:12a1972fa0d0 | 322 | void right_collisionDetect() |
cjw851102 | 0:12a1972fa0d0 | 323 | { |
cjw851102 | 0:12a1972fa0d0 | 324 | int right_boundary[6][6]; |
cjw851102 | 1:2a758565f691 | 325 | get_pattern(pos.type,pos.rotation); |
cjw851102 | 0:12a1972fa0d0 | 326 | // get the left boundary pattern |
cjw851102 | 1:2a758565f691 | 327 | for (int j=0; j<=5; j++) { |
cjw851102 | 1:2a758565f691 | 328 | for (int i=5; i>=0; i--) { |
cjw851102 | 0:12a1972fa0d0 | 329 | if (pattern_buffer[i][j]==1) { |
cjw851102 | 0:12a1972fa0d0 | 330 | right_boundary[i][j]=1; |
cjw851102 | 0:12a1972fa0d0 | 331 | for(int k=i-1; k>=0; k--) { |
cjw851102 | 0:12a1972fa0d0 | 332 | right_boundary[k][j] = 0; |
cjw851102 | 0:12a1972fa0d0 | 333 | } |
cjw851102 | 1:2a758565f691 | 334 | break; |
cjw851102 | 0:12a1972fa0d0 | 335 | } else { |
cjw851102 | 0:12a1972fa0d0 | 336 | right_boundary[i][j]=0; |
cjw851102 | 0:12a1972fa0d0 | 337 | } |
cjw851102 | 0:12a1972fa0d0 | 338 | } |
cjw851102 | 0:12a1972fa0d0 | 339 | } |
cjw851102 | 0:12a1972fa0d0 | 340 | |
cjw851102 | 0:12a1972fa0d0 | 341 | //check left collision |
cjw851102 | 1:2a758565f691 | 342 | int x = pos.x; |
cjw851102 | 1:2a758565f691 | 343 | int y = pos.y; |
cjw851102 | 0:12a1972fa0d0 | 344 | for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square |
cjw851102 | 0:12a1972fa0d0 | 345 | for(int j=y; j <= y+5; j++) { |
cjw851102 | 0:12a1972fa0d0 | 346 | if(right_boundary[i-x][j-y]==1) { |
cjw851102 | 1:2a758565f691 | 347 | if(j>=0) { |
cjw851102 | 1:2a758565f691 | 348 | if(i >= 29) { |
cjw851102 | 1:2a758565f691 | 349 | right_collision_flag = 1; |
cjw851102 | 1:2a758565f691 | 350 | break; |
cjw851102 | 2:f427089e2bfa | 351 | } else if (lcd.getPixel(i+1,j)) { |
cjw851102 | 1:2a758565f691 | 352 | right_collision_flag = 1; |
cjw851102 | 1:2a758565f691 | 353 | break; |
cjw851102 | 1:2a758565f691 | 354 | } else { |
cjw851102 | 1:2a758565f691 | 355 | right_collision_flag = 0; |
cjw851102 | 0:12a1972fa0d0 | 356 | } |
cjw851102 | 0:12a1972fa0d0 | 357 | } |
cjw851102 | 0:12a1972fa0d0 | 358 | } |
cjw851102 | 2:f427089e2bfa | 359 | } |
cjw851102 | 2:f427089e2bfa | 360 | if (right_collision_flag == 1) { |
cjw851102 | 2:f427089e2bfa | 361 | break; |
cjw851102 | 0:12a1972fa0d0 | 362 | } |
cjw851102 | 0:12a1972fa0d0 | 363 | |
cjw851102 | 0:12a1972fa0d0 | 364 | } |
cjw851102 | 0:12a1972fa0d0 | 365 | } |
cjw851102 | 0:12a1972fa0d0 | 366 | |
cjw851102 | 0:12a1972fa0d0 | 367 | void bottom_collisionDetect() |
cjw851102 | 0:12a1972fa0d0 | 368 | { |
cjw851102 | 2:f427089e2bfa | 369 | int bot_boundary[6][6]; |
cjw851102 | 1:2a758565f691 | 370 | get_pattern(pos.type,pos.rotation); |
cjw851102 | 0:12a1972fa0d0 | 371 | // get the left boundary pattern |
cjw851102 | 1:2a758565f691 | 372 | for (int i=0; i<=5; i++) { |
cjw851102 | 1:2a758565f691 | 373 | for (int j=5; j>=0; j--) { |
cjw851102 | 0:12a1972fa0d0 | 374 | if (pattern_buffer[i][j]==1) { |
cjw851102 | 0:12a1972fa0d0 | 375 | bot_boundary[i][j]=1; |
cjw851102 | 2:f427089e2bfa | 376 | for(int k=j-1; k>=0; k--) { |
cjw851102 | 0:12a1972fa0d0 | 377 | bot_boundary[i][k] = 0; |
cjw851102 | 0:12a1972fa0d0 | 378 | } |
cjw851102 | 2:f427089e2bfa | 379 | break; |
cjw851102 | 0:12a1972fa0d0 | 380 | } else { |
cjw851102 | 0:12a1972fa0d0 | 381 | bot_boundary[i][j]=0; |
cjw851102 | 0:12a1972fa0d0 | 382 | } |
cjw851102 | 0:12a1972fa0d0 | 383 | } |
cjw851102 | 0:12a1972fa0d0 | 384 | } |
cjw851102 | 0:12a1972fa0d0 | 385 | |
cjw851102 | 0:12a1972fa0d0 | 386 | //check left collision |
cjw851102 | 1:2a758565f691 | 387 | int x = pos.x; |
cjw851102 | 1:2a758565f691 | 388 | int y = pos.y; |
cjw851102 | 0:12a1972fa0d0 | 389 | for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square |
cjw851102 | 2:f427089e2bfa | 390 | for(int j=y+5; j >= y; j--) { |
cjw851102 | 2:f427089e2bfa | 391 | if (j>=-1) { |
cjw851102 | 2:f427089e2bfa | 392 | if(bot_boundary[i-x][j-y]==1) { |
cjw851102 | 2:f427089e2bfa | 393 | if(j >= 47) { |
cjw851102 | 2:f427089e2bfa | 394 | bottom_collision_flag = 1; |
cjw851102 | 2:f427089e2bfa | 395 | break; |
cjw851102 | 2:f427089e2bfa | 396 | } else if (lcd.getPixel(i,j+1)) { |
cjw851102 | 2:f427089e2bfa | 397 | bottom_collision_flag = 1; |
cjw851102 | 2:f427089e2bfa | 398 | break; |
cjw851102 | 2:f427089e2bfa | 399 | } else { |
cjw851102 | 2:f427089e2bfa | 400 | bottom_collision_flag = 0; |
cjw851102 | 2:f427089e2bfa | 401 | } |
cjw851102 | 2:f427089e2bfa | 402 | } |
cjw851102 | 2:f427089e2bfa | 403 | } else { |
cjw851102 | 2:f427089e2bfa | 404 | bottom_collision_flag = 0; |
cjw851102 | 2:f427089e2bfa | 405 | } |
cjw851102 | 2:f427089e2bfa | 406 | } |
cjw851102 | 2:f427089e2bfa | 407 | if( bottom_collision_flag == 1) { |
cjw851102 | 2:f427089e2bfa | 408 | break; |
cjw851102 | 2:f427089e2bfa | 409 | } |
cjw851102 | 2:f427089e2bfa | 410 | } |
cjw851102 | 2:f427089e2bfa | 411 | } |
cjw851102 | 2:f427089e2bfa | 412 | |
cjw851102 | 2:f427089e2bfa | 413 | void rotation_collisionDetect() |
cjw851102 | 2:f427089e2bfa | 414 | { |
cjw851102 | 2:f427089e2bfa | 415 | int rotation = pos.rotation+1; |
cjw851102 | 2:f427089e2bfa | 416 | if (rotation>3) { |
cjw851102 | 2:f427089e2bfa | 417 | rotation=0; |
cjw851102 | 2:f427089e2bfa | 418 | } |
cjw851102 | 2:f427089e2bfa | 419 | get_pattern(pos.type,rotation); |
cjw851102 | 2:f427089e2bfa | 420 | |
cjw851102 | 2:f427089e2bfa | 421 | //check |
cjw851102 | 2:f427089e2bfa | 422 | int x = pos.x; |
cjw851102 | 2:f427089e2bfa | 423 | int y = pos.y; |
cjw851102 | 2:f427089e2bfa | 424 | for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square |
cjw851102 | 0:12a1972fa0d0 | 425 | for(int j=y; j <= y+5; j++) { |
cjw851102 | 2:f427089e2bfa | 426 | if(pattern_buffer[i-x][j-y]==1) { |
cjw851102 | 2:f427089e2bfa | 427 | if(i<0) { |
cjw851102 | 2:f427089e2bfa | 428 | rotation_collision_flag = 1; |
cjw851102 | 2:f427089e2bfa | 429 | } else if(lcd.getPixel(i,j)) { |
cjw851102 | 2:f427089e2bfa | 430 | rotation_collision_flag = 1; |
cjw851102 | 2:f427089e2bfa | 431 | break; |
cjw851102 | 1:2a758565f691 | 432 | } else { |
cjw851102 | 2:f427089e2bfa | 433 | rotation_collision_flag = 0; |
cjw851102 | 0:12a1972fa0d0 | 434 | } |
cjw851102 | 0:12a1972fa0d0 | 435 | } |
cjw851102 | 0:12a1972fa0d0 | 436 | } |
cjw851102 | 2:f427089e2bfa | 437 | if (rotation_collision_flag == 1) { |
cjw851102 | 2:f427089e2bfa | 438 | break; |
cjw851102 | 2:f427089e2bfa | 439 | } |
cjw851102 | 2:f427089e2bfa | 440 | } |
cjw851102 | 2:f427089e2bfa | 441 | } |
cjw851102 | 0:12a1972fa0d0 | 442 | |
cjw851102 | 2:f427089e2bfa | 443 | void top_collisionDetect() |
cjw851102 | 2:f427089e2bfa | 444 | { |
cjw851102 | 2:f427089e2bfa | 445 | if (pos.y==-6) { |
cjw851102 | 2:f427089e2bfa | 446 | bottom_collisionDetect(); |
cjw851102 | 2:f427089e2bfa | 447 | if (bottom_collision_flag == 1) { |
cjw851102 | 2:f427089e2bfa | 448 | top_collision_flag = 1; |
cjw851102 | 2:f427089e2bfa | 449 | } else { |
cjw851102 | 2:f427089e2bfa | 450 | top_collision_flag = 0; |
cjw851102 | 2:f427089e2bfa | 451 | } |
cjw851102 | 2:f427089e2bfa | 452 | } |
cjw851102 | 2:f427089e2bfa | 453 | } |
cjw851102 | 2:f427089e2bfa | 454 | |
cjw851102 | 2:f427089e2bfa | 455 | void fastmove_bottom_collisionDetect() |
cjw851102 | 2:f427089e2bfa | 456 | { |
cjw851102 | 2:f427089e2bfa | 457 | int bot_boundary[6][6]; |
cjw851102 | 2:f427089e2bfa | 458 | get_pattern(pos.type,pos.rotation); |
cjw851102 | 2:f427089e2bfa | 459 | // get the left boundary pattern |
cjw851102 | 2:f427089e2bfa | 460 | for (int i=0; i<=5; i++) { |
cjw851102 | 2:f427089e2bfa | 461 | for (int j=5; j>=0; j--) { |
cjw851102 | 2:f427089e2bfa | 462 | if (pattern_buffer[i][j]==1) { |
cjw851102 | 2:f427089e2bfa | 463 | bot_boundary[i][j]=1; |
cjw851102 | 2:f427089e2bfa | 464 | for(int k=j-1; k>=0; k--) { |
cjw851102 | 2:f427089e2bfa | 465 | bot_boundary[i][k] = 0; |
cjw851102 | 2:f427089e2bfa | 466 | } |
cjw851102 | 2:f427089e2bfa | 467 | break; |
cjw851102 | 2:f427089e2bfa | 468 | } else { |
cjw851102 | 2:f427089e2bfa | 469 | bot_boundary[i][j]=0; |
cjw851102 | 2:f427089e2bfa | 470 | } |
cjw851102 | 2:f427089e2bfa | 471 | } |
cjw851102 | 2:f427089e2bfa | 472 | } |
cjw851102 | 2:f427089e2bfa | 473 | |
cjw851102 | 2:f427089e2bfa | 474 | //check left collision |
cjw851102 | 2:f427089e2bfa | 475 | int x = pos.x; |
cjw851102 | 2:f427089e2bfa | 476 | int y = pos.y; |
cjw851102 | 2:f427089e2bfa | 477 | for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square |
cjw851102 | 2:f427089e2bfa | 478 | for(int j=y+5; j >= y; j--) { |
cjw851102 | 2:f427089e2bfa | 479 | if (j>=-1) { |
cjw851102 | 2:f427089e2bfa | 480 | if(bot_boundary[i-x][j-y]==1) { |
cjw851102 | 2:f427089e2bfa | 481 | if(j >= 47) { |
cjw851102 | 2:f427089e2bfa | 482 | fastmove_bottom_collision_flag = 1; |
cjw851102 | 2:f427089e2bfa | 483 | break; |
cjw851102 | 2:f427089e2bfa | 484 | } else if (lcd.getPixel(i,j+4)) { |
cjw851102 | 2:f427089e2bfa | 485 | fastmove_bottom_collision_flag = 1; |
cjw851102 | 2:f427089e2bfa | 486 | break; |
cjw851102 | 2:f427089e2bfa | 487 | } else { |
cjw851102 | 2:f427089e2bfa | 488 | fastmove_bottom_collision_flag = 0; |
cjw851102 | 2:f427089e2bfa | 489 | } |
cjw851102 | 2:f427089e2bfa | 490 | } |
cjw851102 | 2:f427089e2bfa | 491 | } else { |
cjw851102 | 2:f427089e2bfa | 492 | fastmove_bottom_collision_flag = 0; |
cjw851102 | 2:f427089e2bfa | 493 | } |
cjw851102 | 2:f427089e2bfa | 494 | } |
cjw851102 | 2:f427089e2bfa | 495 | if( fastmove_bottom_collision_flag == 1) { |
cjw851102 | 2:f427089e2bfa | 496 | break; |
cjw851102 | 2:f427089e2bfa | 497 | } |
cjw851102 | 0:12a1972fa0d0 | 498 | } |
cjw851102 | 1:2a758565f691 | 499 | } |
cjw851102 | 1:2a758565f691 | 500 | |
cjw851102 | 1:2a758565f691 | 501 | void game_isr() |
cjw851102 | 1:2a758565f691 | 502 | { |
cjw851102 | 1:2a758565f691 | 503 | g_game_flag = 1; |
cjw851102 | 1:2a758565f691 | 504 | } |
cjw851102 | 1:2a758565f691 | 505 | |
cjw851102 | 1:2a758565f691 | 506 | // read default positions of the joystick to calibrate later readings |
cjw851102 | 1:2a758565f691 | 507 | void calibrateJoystick() |
cjw851102 | 1:2a758565f691 | 508 | { |
cjw851102 | 1:2a758565f691 | 509 | button.mode(PullDown); |
cjw851102 | 1:2a758565f691 | 510 | // must not move during calibration |
cjw851102 | 1:2a758565f691 | 511 | joystick.x0 = xPot; // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly) |
cjw851102 | 1:2a758565f691 | 512 | joystick.y0 = yPot; |
cjw851102 | 1:2a758565f691 | 513 | } |
cjw851102 | 1:2a758565f691 | 514 | |
cjw851102 | 1:2a758565f691 | 515 | void updateJoystick() |
cjw851102 | 1:2a758565f691 | 516 | { |
cjw851102 | 1:2a758565f691 | 517 | // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred) |
cjw851102 | 1:2a758565f691 | 518 | joystick.x = xPot - joystick.x0; |
cjw851102 | 1:2a758565f691 | 519 | joystick.y = yPot - joystick.y0; |
cjw851102 | 1:2a758565f691 | 520 | // read button state |
cjw851102 | 1:2a758565f691 | 521 | joystick.button = button; |
cjw851102 | 1:2a758565f691 | 522 | |
cjw851102 | 1:2a758565f691 | 523 | // calculate direction depending on x,y values |
cjw851102 | 1:2a758565f691 | 524 | // tolerance allows a little lee-way in case joystick not exactly in the stated direction |
cjw851102 | 1:2a758565f691 | 525 | if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { |
cjw851102 | 1:2a758565f691 | 526 | joystick.direction = CENTRE; |
cjw851102 | 1:2a758565f691 | 527 | } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { |
cjw851102 | 1:2a758565f691 | 528 | joystick.direction = UP; |
cjw851102 | 1:2a758565f691 | 529 | } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { |
cjw851102 | 1:2a758565f691 | 530 | joystick.direction = DOWN; |
cjw851102 | 1:2a758565f691 | 531 | } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { |
cjw851102 | 1:2a758565f691 | 532 | joystick.direction = RIGHT; |
cjw851102 | 1:2a758565f691 | 533 | } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { |
cjw851102 | 1:2a758565f691 | 534 | joystick.direction = LEFT; |
cjw851102 | 1:2a758565f691 | 535 | } else { |
cjw851102 | 1:2a758565f691 | 536 | joystick.direction = UNKNOWN; |
cjw851102 | 1:2a758565f691 | 537 | } |
cjw851102 | 1:2a758565f691 | 538 | |
cjw851102 | 2:f427089e2bfa | 539 | } |
cjw851102 | 2:f427089e2bfa | 540 | |
cjw851102 | 2:f427089e2bfa | 541 | void cancelLine() |
cjw851102 | 2:f427089e2bfa | 542 | { |
cjw851102 | 2:f427089e2bfa | 543 | // int linePattern[30][2]; //the pixel setting for one line(30x2 square) |
cjw851102 | 2:f427089e2bfa | 544 | int count; |
cjw851102 | 2:f427089e2bfa | 545 | for(int j=0; j<=46; j+=2) { |
cjw851102 | 2:f427089e2bfa | 546 | for(int i=0; i<=29; i++) { |
cjw851102 | 2:f427089e2bfa | 547 | if (lcd.getPixel(i,j)==0||lcd.getPixel(i,j+1)==0) { |
cjw851102 | 2:f427089e2bfa | 548 | count=0; |
cjw851102 | 2:f427089e2bfa | 549 | break; |
cjw851102 | 2:f427089e2bfa | 550 | } else if (lcd.getPixel(i,j)&&lcd.getPixel(i,j+1)) { |
cjw851102 | 2:f427089e2bfa | 551 | count++; |
cjw851102 | 2:f427089e2bfa | 552 | } |
cjw851102 | 2:f427089e2bfa | 553 | } |
cjw851102 | 2:f427089e2bfa | 554 | if(count==30) { // one line is filled |
cjw851102 | 2:f427089e2bfa | 555 | count=0; |
cjw851102 | 2:f427089e2bfa | 556 | lcd.drawRect(0,j,29,1,2); //clear the line |
cjw851102 | 2:f427089e2bfa | 557 | score+=10; // add the score |
cjw851102 | 2:f427089e2bfa | 558 | //print the score |
cjw851102 | 2:f427089e2bfa | 559 | char scoreBuffer[14]; |
cjw851102 | 2:f427089e2bfa | 560 | sprintf(scoreBuffer,"%d",score); |
cjw851102 | 2:f427089e2bfa | 561 | lcd.printString(scoreBuffer,42,3); |
cjw851102 | 2:f427089e2bfa | 562 | scan(); |
cjw851102 | 2:f427089e2bfa | 563 | // move the patterns upon the line down for 2 pixels' hight |
cjw851102 | 2:f427089e2bfa | 564 | for (int x=0; x<=29; x++) { |
cjw851102 | 2:f427089e2bfa | 565 | for (int y=j; y>=0; y--) { |
cjw851102 | 2:f427089e2bfa | 566 | if (buffer[x][y]) { |
cjw851102 | 2:f427089e2bfa | 567 | lcd.clearPixel(x,y); |
cjw851102 | 2:f427089e2bfa | 568 | lcd.setPixel(x,y+2); |
cjw851102 | 2:f427089e2bfa | 569 | } |
cjw851102 | 2:f427089e2bfa | 570 | } |
cjw851102 | 2:f427089e2bfa | 571 | } |
cjw851102 | 2:f427089e2bfa | 572 | } |
cjw851102 | 2:f427089e2bfa | 573 | } |
cjw851102 | 2:f427089e2bfa | 574 | } |
cjw851102 | 2:f427089e2bfa | 575 | |
cjw851102 | 2:f427089e2bfa | 576 | void finishAnimation() |
cjw851102 | 2:f427089e2bfa | 577 | { |
cjw851102 | 2:f427089e2bfa | 578 | for (int j=47; j>=0; j--) { |
cjw851102 | 2:f427089e2bfa | 579 | lcd.drawRect(0,j,29,1,1); |
cjw851102 | 2:f427089e2bfa | 580 | wait(0.05); |
cjw851102 | 2:f427089e2bfa | 581 | lcd.refresh(); |
cjw851102 | 2:f427089e2bfa | 582 | } |
cjw851102 | 2:f427089e2bfa | 583 | } |
cjw851102 | 2:f427089e2bfa | 584 | |
cjw851102 | 2:f427089e2bfa | 585 | |
cjw851102 | 2:f427089e2bfa | 586 |