an mbed tile music game using a capacitive touchpad and uLCD

Dependencies:   SDFileSystem mbed wave_player

Committer:
clu67
Date:
Mon Mar 14 00:26:24 2016 +0000
Revision:
0:a1c374b9a4fe
Initial Release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
clu67 0:a1c374b9a4fe 1 //
clu67 0:a1c374b9a4fe 2 // uLCD_4DGL is a class to drive 4D Systems TFT touch screens
clu67 0:a1c374b9a4fe 3 //
clu67 0:a1c374b9a4fe 4 // Copyright (C) <2010> Stephane ROCHON <stephane.rochon at free.fr>
clu67 0:a1c374b9a4fe 5 // Modifed for Goldelox processor <2013> Jim Hamblen
clu67 0:a1c374b9a4fe 6 //
clu67 0:a1c374b9a4fe 7 // uLCD_4DGL is free software: you can redistribute it and/or modify
clu67 0:a1c374b9a4fe 8 // it under the terms of the GNU General Public License as published by
clu67 0:a1c374b9a4fe 9 // the Free Software Foundation, either version 3 of the License, or
clu67 0:a1c374b9a4fe 10 // (at your option) any later version.
clu67 0:a1c374b9a4fe 11 //
clu67 0:a1c374b9a4fe 12 // uLCD_4DGL is distributed in the hope that it will be useful,
clu67 0:a1c374b9a4fe 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
clu67 0:a1c374b9a4fe 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
clu67 0:a1c374b9a4fe 15 // GNU General Public License for more details.
clu67 0:a1c374b9a4fe 16 //
clu67 0:a1c374b9a4fe 17 // You should have received a copy of the GNU General Public License
clu67 0:a1c374b9a4fe 18 // along with uLCD_4DGL. If not, see <http://www.gnu.org/licenses/>.
clu67 0:a1c374b9a4fe 19
clu67 0:a1c374b9a4fe 20 #include "mbed.h"
clu67 0:a1c374b9a4fe 21 #include "uLCD_4DGL.h"
clu67 0:a1c374b9a4fe 22
clu67 0:a1c374b9a4fe 23 //****************************************************************************************************
clu67 0:a1c374b9a4fe 24 void uLCD_4DGL :: set_font_size(char width, char height) // set font size
clu67 0:a1c374b9a4fe 25 {
clu67 0:a1c374b9a4fe 26 if (current_orientation == IS_PORTRAIT) {
clu67 0:a1c374b9a4fe 27 current_fx = width;
clu67 0:a1c374b9a4fe 28 current_fy = height;
clu67 0:a1c374b9a4fe 29 } else {
clu67 0:a1c374b9a4fe 30 current_fy = height;
clu67 0:a1c374b9a4fe 31 current_fx = width;
clu67 0:a1c374b9a4fe 32 }
clu67 0:a1c374b9a4fe 33 max_col = current_w / (current_fx*current_wf);
clu67 0:a1c374b9a4fe 34 max_row = current_h / (current_fy*current_hf);
clu67 0:a1c374b9a4fe 35 }
clu67 0:a1c374b9a4fe 36
clu67 0:a1c374b9a4fe 37 //****************************************************************************************************
clu67 0:a1c374b9a4fe 38 void uLCD_4DGL :: set_font(char mode) // set font - system or SD media
clu67 0:a1c374b9a4fe 39 {
clu67 0:a1c374b9a4fe 40 char command[3]= "";
clu67 0:a1c374b9a4fe 41
clu67 0:a1c374b9a4fe 42 command[0] = SETFONT;
clu67 0:a1c374b9a4fe 43 command[1] = 0;
clu67 0:a1c374b9a4fe 44 command[2] = mode;
clu67 0:a1c374b9a4fe 45
clu67 0:a1c374b9a4fe 46 current_font = mode;
clu67 0:a1c374b9a4fe 47
clu67 0:a1c374b9a4fe 48 if (current_orientation == IS_PORTRAIT) {
clu67 0:a1c374b9a4fe 49 current_w = SIZE_X;
clu67 0:a1c374b9a4fe 50 current_h = SIZE_Y;
clu67 0:a1c374b9a4fe 51 } else {
clu67 0:a1c374b9a4fe 52 current_w = SIZE_Y;
clu67 0:a1c374b9a4fe 53 current_h = SIZE_X;
clu67 0:a1c374b9a4fe 54 }
clu67 0:a1c374b9a4fe 55
clu67 0:a1c374b9a4fe 56 switch (mode) {
clu67 0:a1c374b9a4fe 57 case FONT_5X7 :
clu67 0:a1c374b9a4fe 58
clu67 0:a1c374b9a4fe 59 current_fx = 6;
clu67 0:a1c374b9a4fe 60 current_fy = 8;
clu67 0:a1c374b9a4fe 61 break;
clu67 0:a1c374b9a4fe 62 case FONT_7X8 :
clu67 0:a1c374b9a4fe 63 current_fx = 7;
clu67 0:a1c374b9a4fe 64 current_fy = 8;
clu67 0:a1c374b9a4fe 65 break;
clu67 0:a1c374b9a4fe 66 case FONT_8X8 :
clu67 0:a1c374b9a4fe 67 current_fx = 8;
clu67 0:a1c374b9a4fe 68 current_fy = 8;
clu67 0:a1c374b9a4fe 69 break;
clu67 0:a1c374b9a4fe 70 case FONT_8X12 :
clu67 0:a1c374b9a4fe 71 current_fx = 8;
clu67 0:a1c374b9a4fe 72 current_fy = 12;
clu67 0:a1c374b9a4fe 73 break;
clu67 0:a1c374b9a4fe 74 case FONT_12X16 :
clu67 0:a1c374b9a4fe 75 current_fx = 12;
clu67 0:a1c374b9a4fe 76 current_fy = 16;
clu67 0:a1c374b9a4fe 77 break;
clu67 0:a1c374b9a4fe 78 default:
clu67 0:a1c374b9a4fe 79 current_fx = 8;
clu67 0:a1c374b9a4fe 80 current_fy = 8;
clu67 0:a1c374b9a4fe 81 }
clu67 0:a1c374b9a4fe 82
clu67 0:a1c374b9a4fe 83 max_col = current_w / (current_fx*current_wf);
clu67 0:a1c374b9a4fe 84 max_row = current_h / (current_fy*current_hf);
clu67 0:a1c374b9a4fe 85
clu67 0:a1c374b9a4fe 86 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 87 }
clu67 0:a1c374b9a4fe 88
clu67 0:a1c374b9a4fe 89
clu67 0:a1c374b9a4fe 90
clu67 0:a1c374b9a4fe 91 //****************************************************************************************************
clu67 0:a1c374b9a4fe 92 void uLCD_4DGL :: text_mode(char mode) // set text mode
clu67 0:a1c374b9a4fe 93 {
clu67 0:a1c374b9a4fe 94 char command[3]= "";
clu67 0:a1c374b9a4fe 95
clu67 0:a1c374b9a4fe 96 command[0] = TEXTMODE;
clu67 0:a1c374b9a4fe 97 command[1] = 0;
clu67 0:a1c374b9a4fe 98 command[2] = mode;
clu67 0:a1c374b9a4fe 99
clu67 0:a1c374b9a4fe 100 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 101 }
clu67 0:a1c374b9a4fe 102
clu67 0:a1c374b9a4fe 103 //****************************************************************************************************
clu67 0:a1c374b9a4fe 104 void uLCD_4DGL :: text_bold(char mode) // set text mode
clu67 0:a1c374b9a4fe 105 {
clu67 0:a1c374b9a4fe 106 char command[3]= "";
clu67 0:a1c374b9a4fe 107
clu67 0:a1c374b9a4fe 108 command[0] = TEXTBOLD;
clu67 0:a1c374b9a4fe 109 command[1] = 0;
clu67 0:a1c374b9a4fe 110 command[2] = mode;
clu67 0:a1c374b9a4fe 111
clu67 0:a1c374b9a4fe 112 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 113 }
clu67 0:a1c374b9a4fe 114
clu67 0:a1c374b9a4fe 115 //****************************************************************************************************
clu67 0:a1c374b9a4fe 116 void uLCD_4DGL :: text_italic(char mode) // set text mode
clu67 0:a1c374b9a4fe 117 {
clu67 0:a1c374b9a4fe 118 char command[3]= "";
clu67 0:a1c374b9a4fe 119
clu67 0:a1c374b9a4fe 120 command[0] = TEXTITALIC;
clu67 0:a1c374b9a4fe 121 command[1] = 0;
clu67 0:a1c374b9a4fe 122 command[2] = mode;
clu67 0:a1c374b9a4fe 123
clu67 0:a1c374b9a4fe 124 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 125 }
clu67 0:a1c374b9a4fe 126
clu67 0:a1c374b9a4fe 127 //****************************************************************************************************
clu67 0:a1c374b9a4fe 128 void uLCD_4DGL :: text_inverse(char mode) // set text mode
clu67 0:a1c374b9a4fe 129 {
clu67 0:a1c374b9a4fe 130 char command[3]= "";
clu67 0:a1c374b9a4fe 131
clu67 0:a1c374b9a4fe 132 command[0] = TEXTINVERSE;
clu67 0:a1c374b9a4fe 133 command[1] = 0;
clu67 0:a1c374b9a4fe 134 command[2] = mode;
clu67 0:a1c374b9a4fe 135
clu67 0:a1c374b9a4fe 136 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 137 }
clu67 0:a1c374b9a4fe 138
clu67 0:a1c374b9a4fe 139 //****************************************************************************************************
clu67 0:a1c374b9a4fe 140 void uLCD_4DGL :: text_underline(char mode) // set text mode
clu67 0:a1c374b9a4fe 141 {
clu67 0:a1c374b9a4fe 142 char command[3]= "";
clu67 0:a1c374b9a4fe 143
clu67 0:a1c374b9a4fe 144 command[0] = TEXTUNDERLINE;
clu67 0:a1c374b9a4fe 145 command[1] = 0;
clu67 0:a1c374b9a4fe 146 command[2] = mode;
clu67 0:a1c374b9a4fe 147
clu67 0:a1c374b9a4fe 148 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 149 }
clu67 0:a1c374b9a4fe 150
clu67 0:a1c374b9a4fe 151 //****************************************************************************************************
clu67 0:a1c374b9a4fe 152 void uLCD_4DGL :: text_width(char width) // set text width
clu67 0:a1c374b9a4fe 153 {
clu67 0:a1c374b9a4fe 154 char command[3]= "";
clu67 0:a1c374b9a4fe 155
clu67 0:a1c374b9a4fe 156 command[0] = TEXTWIDTH;
clu67 0:a1c374b9a4fe 157 command[1] = 0;
clu67 0:a1c374b9a4fe 158 command[2] = width;
clu67 0:a1c374b9a4fe 159 current_wf = width;
clu67 0:a1c374b9a4fe 160 max_col = current_w / (current_fx*current_wf);
clu67 0:a1c374b9a4fe 161 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 162 }
clu67 0:a1c374b9a4fe 163
clu67 0:a1c374b9a4fe 164 //****************************************************************************************************
clu67 0:a1c374b9a4fe 165 void uLCD_4DGL :: text_height(char height) // set text height
clu67 0:a1c374b9a4fe 166 {
clu67 0:a1c374b9a4fe 167 char command[3]= "";
clu67 0:a1c374b9a4fe 168
clu67 0:a1c374b9a4fe 169 command[0] = TEXTHEIGHT;
clu67 0:a1c374b9a4fe 170 command[1] = 0;
clu67 0:a1c374b9a4fe 171 command[2] = height;
clu67 0:a1c374b9a4fe 172 current_hf = height;
clu67 0:a1c374b9a4fe 173 max_row = current_h / (current_fy*current_hf);
clu67 0:a1c374b9a4fe 174 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 175 }
clu67 0:a1c374b9a4fe 176
clu67 0:a1c374b9a4fe 177
clu67 0:a1c374b9a4fe 178 //****************************************************************************************************
clu67 0:a1c374b9a4fe 179 void uLCD_4DGL :: text_char(char c, char col, char row, int color) // draw a text char
clu67 0:a1c374b9a4fe 180 {
clu67 0:a1c374b9a4fe 181 char command[6]= "";
clu67 0:a1c374b9a4fe 182 command[0] = 0xE4; //move cursor
clu67 0:a1c374b9a4fe 183 command[1] = 0;
clu67 0:a1c374b9a4fe 184 command[2] = row;
clu67 0:a1c374b9a4fe 185 command[3] = 0;
clu67 0:a1c374b9a4fe 186 command[4] = col;
clu67 0:a1c374b9a4fe 187 writeCOMMAND(command, 5);
clu67 0:a1c374b9a4fe 188
clu67 0:a1c374b9a4fe 189 command[0] = 0x7F; //set color
clu67 0:a1c374b9a4fe 190
clu67 0:a1c374b9a4fe 191 int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
clu67 0:a1c374b9a4fe 192 int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
clu67 0:a1c374b9a4fe 193 int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
clu67 0:a1c374b9a4fe 194
clu67 0:a1c374b9a4fe 195 command[1] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
clu67 0:a1c374b9a4fe 196 command[2] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
clu67 0:a1c374b9a4fe 197 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 198
clu67 0:a1c374b9a4fe 199 command[0] = TEXTCHAR; //print char
clu67 0:a1c374b9a4fe 200 command[1] = 0;
clu67 0:a1c374b9a4fe 201 command[2] = c;
clu67 0:a1c374b9a4fe 202 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 203
clu67 0:a1c374b9a4fe 204 }
clu67 0:a1c374b9a4fe 205
clu67 0:a1c374b9a4fe 206
clu67 0:a1c374b9a4fe 207 //****************************************************************************************************
clu67 0:a1c374b9a4fe 208 void uLCD_4DGL :: text_string(char *s, char col, char row, char font, int color) // draw a text string
clu67 0:a1c374b9a4fe 209 {
clu67 0:a1c374b9a4fe 210
clu67 0:a1c374b9a4fe 211 char command[1000]= "";
clu67 0:a1c374b9a4fe 212 int size = strlen(s);
clu67 0:a1c374b9a4fe 213 int i = 0;
clu67 0:a1c374b9a4fe 214
clu67 0:a1c374b9a4fe 215 set_font(font);
clu67 0:a1c374b9a4fe 216
clu67 0:a1c374b9a4fe 217 command[0] = 0xE4; //move cursor
clu67 0:a1c374b9a4fe 218 command[1] = 0;
clu67 0:a1c374b9a4fe 219 command[2] = row;
clu67 0:a1c374b9a4fe 220 command[3] = 0;
clu67 0:a1c374b9a4fe 221 command[4] = col;
clu67 0:a1c374b9a4fe 222 writeCOMMAND(command, 5);
clu67 0:a1c374b9a4fe 223
clu67 0:a1c374b9a4fe 224 command[0] = 0x7F; //set color
clu67 0:a1c374b9a4fe 225 int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
clu67 0:a1c374b9a4fe 226 int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
clu67 0:a1c374b9a4fe 227 int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
clu67 0:a1c374b9a4fe 228
clu67 0:a1c374b9a4fe 229 command[1] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
clu67 0:a1c374b9a4fe 230 command[2] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
clu67 0:a1c374b9a4fe 231 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 232
clu67 0:a1c374b9a4fe 233 command[0] = TEXTSTRING;
clu67 0:a1c374b9a4fe 234 for (i=0; i<size; i++) command[1+i] = s[i];
clu67 0:a1c374b9a4fe 235 command[1+size] = 0;
clu67 0:a1c374b9a4fe 236 writeCOMMANDnull(command, 2 + size);
clu67 0:a1c374b9a4fe 237 }
clu67 0:a1c374b9a4fe 238
clu67 0:a1c374b9a4fe 239
clu67 0:a1c374b9a4fe 240
clu67 0:a1c374b9a4fe 241 //****************************************************************************************************
clu67 0:a1c374b9a4fe 242 void uLCD_4DGL :: locate(char col, char row) // place text curssor at col, row
clu67 0:a1c374b9a4fe 243 {
clu67 0:a1c374b9a4fe 244 char command[5] = "";
clu67 0:a1c374b9a4fe 245 current_col = col;
clu67 0:a1c374b9a4fe 246 current_row = row;
clu67 0:a1c374b9a4fe 247 command[0] = MOVECURSOR; //move cursor
clu67 0:a1c374b9a4fe 248 command[1] = 0;
clu67 0:a1c374b9a4fe 249 command[2] = current_row;
clu67 0:a1c374b9a4fe 250 command[3] = 0;
clu67 0:a1c374b9a4fe 251 command[4] = current_col;
clu67 0:a1c374b9a4fe 252 writeCOMMAND(command, 5);
clu67 0:a1c374b9a4fe 253 }
clu67 0:a1c374b9a4fe 254
clu67 0:a1c374b9a4fe 255 //****************************************************************************************************
clu67 0:a1c374b9a4fe 256 void uLCD_4DGL :: color(int color) // set text color
clu67 0:a1c374b9a4fe 257 {
clu67 0:a1c374b9a4fe 258 char command[5] = "";
clu67 0:a1c374b9a4fe 259 current_color = color;
clu67 0:a1c374b9a4fe 260 command[0] = 0x7F; //set color
clu67 0:a1c374b9a4fe 261
clu67 0:a1c374b9a4fe 262 int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
clu67 0:a1c374b9a4fe 263 int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
clu67 0:a1c374b9a4fe 264 int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
clu67 0:a1c374b9a4fe 265
clu67 0:a1c374b9a4fe 266 command[1] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
clu67 0:a1c374b9a4fe 267 command[2] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
clu67 0:a1c374b9a4fe 268 writeCOMMAND(command, 3);
clu67 0:a1c374b9a4fe 269 }
clu67 0:a1c374b9a4fe 270
clu67 0:a1c374b9a4fe 271 //****************************************************************************************************
clu67 0:a1c374b9a4fe 272 void uLCD_4DGL :: putc(char c) // place char at current cursor position
clu67 0:a1c374b9a4fe 273 //used by virtual printf function _putc
clu67 0:a1c374b9a4fe 274 {
clu67 0:a1c374b9a4fe 275 char command[6] ="";
clu67 0:a1c374b9a4fe 276 if(c<0x20) {
clu67 0:a1c374b9a4fe 277 if(c=='\n') {
clu67 0:a1c374b9a4fe 278 current_col = 0;
clu67 0:a1c374b9a4fe 279 current_row++;
clu67 0:a1c374b9a4fe 280 command[0] = MOVECURSOR; //move cursor to start of next line
clu67 0:a1c374b9a4fe 281 command[1] = 0;
clu67 0:a1c374b9a4fe 282 command[2] = current_row;
clu67 0:a1c374b9a4fe 283 command[3] = 0;
clu67 0:a1c374b9a4fe 284 command[4] = current_col;
clu67 0:a1c374b9a4fe 285 writeCOMMAND(command, 5);
clu67 0:a1c374b9a4fe 286 }
clu67 0:a1c374b9a4fe 287 if(c=='\r') {
clu67 0:a1c374b9a4fe 288 current_col = 0;
clu67 0:a1c374b9a4fe 289 command[0] = MOVECURSOR; //move cursor to start of line
clu67 0:a1c374b9a4fe 290 command[1] = 0;
clu67 0:a1c374b9a4fe 291 command[2] = current_row;
clu67 0:a1c374b9a4fe 292 command[3] = 0;
clu67 0:a1c374b9a4fe 293 command[4] = current_col;
clu67 0:a1c374b9a4fe 294 writeCOMMAND(command, 5);
clu67 0:a1c374b9a4fe 295 }
clu67 0:a1c374b9a4fe 296 if(c=='\f') {
clu67 0:a1c374b9a4fe 297 uLCD_4DGL::cls(); //clear screen on form feed
clu67 0:a1c374b9a4fe 298 }
clu67 0:a1c374b9a4fe 299 } else {
clu67 0:a1c374b9a4fe 300 command[0] = PUTCHAR;
clu67 0:a1c374b9a4fe 301 command[1] = 0x00;
clu67 0:a1c374b9a4fe 302 command[2] = c;
clu67 0:a1c374b9a4fe 303 writeCOMMAND(command,3);
clu67 0:a1c374b9a4fe 304 current_col++;
clu67 0:a1c374b9a4fe 305 }
clu67 0:a1c374b9a4fe 306 if (current_col == max_col) {
clu67 0:a1c374b9a4fe 307 current_col = 0;
clu67 0:a1c374b9a4fe 308 current_row++;
clu67 0:a1c374b9a4fe 309 command[0] = MOVECURSOR; //move cursor to next line
clu67 0:a1c374b9a4fe 310 command[1] = 0;
clu67 0:a1c374b9a4fe 311 command[2] = current_row;
clu67 0:a1c374b9a4fe 312 command[3] = 0;
clu67 0:a1c374b9a4fe 313 command[4] = current_col;
clu67 0:a1c374b9a4fe 314 writeCOMMAND(command, 5);
clu67 0:a1c374b9a4fe 315 }
clu67 0:a1c374b9a4fe 316 if (current_row == max_row) {
clu67 0:a1c374b9a4fe 317 current_row = 0;
clu67 0:a1c374b9a4fe 318 command[0] = MOVECURSOR; //move cursor back to start
clu67 0:a1c374b9a4fe 319 command[1] = 0;
clu67 0:a1c374b9a4fe 320 command[2] = current_row;
clu67 0:a1c374b9a4fe 321 command[3] = 0;
clu67 0:a1c374b9a4fe 322 command[4] = current_col;
clu67 0:a1c374b9a4fe 323 writeCOMMAND(command, 5);
clu67 0:a1c374b9a4fe 324 }
clu67 0:a1c374b9a4fe 325 }
clu67 0:a1c374b9a4fe 326
clu67 0:a1c374b9a4fe 327
clu67 0:a1c374b9a4fe 328 //****************************************************************************************************
clu67 0:a1c374b9a4fe 329 void uLCD_4DGL :: puts(char *s) // place string at current cursor position
clu67 0:a1c374b9a4fe 330 {
clu67 0:a1c374b9a4fe 331
clu67 0:a1c374b9a4fe 332 text_string(s, current_col, current_row, current_font, current_color);
clu67 0:a1c374b9a4fe 333
clu67 0:a1c374b9a4fe 334 current_col += strlen(s);
clu67 0:a1c374b9a4fe 335
clu67 0:a1c374b9a4fe 336 if (current_col >= max_col) {
clu67 0:a1c374b9a4fe 337 current_row += current_col / max_col;
clu67 0:a1c374b9a4fe 338 current_col %= max_col;
clu67 0:a1c374b9a4fe 339 }
clu67 0:a1c374b9a4fe 340 if (current_row >= max_row) {
clu67 0:a1c374b9a4fe 341 current_row %= max_row;
clu67 0:a1c374b9a4fe 342 }
clu67 0:a1c374b9a4fe 343 }
clu67 0:a1c374b9a4fe 344