MHVLib
20111011
An efficiency oriented runtime library for AVR microcontrollers
|
00001 /* Copyright (c) 2011, Make, Hack, Void Inc 00002 * All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are met: 00006 * * Redistributions of source code must retain the above copyright 00007 * notice, this list of conditions and the following disclaimer. 00008 * * Redistributions in binary form must reproduce the above copyright 00009 * notice, this list of conditions and the following disclaimer in the 00010 * documentation and/or other materials provided with the distribution. 00011 * * Neither the name of the Make, Hack, Void nor the 00012 * names of its contributors may be used to endorse or promote products 00013 * derived from this software without specific prior written permission. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00016 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00018 * DISCLAIMED. IN NO EVENT SHALL MAKE, HACK, VOID BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00020 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00021 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00022 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00024 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00025 */ 00026 00027 #include <MHV_Display_Character.h> 00028 00040 MHV_Display_Character::MHV_Display_Character(uint16_t colCount, uint16_t rowCount, 00041 MHV_RingBuffer *txBuffers) : 00042 MHV_Device_TX(txBuffers){ 00043 _colCount = colCount; 00044 _rowCount = rowCount; 00045 _wrap = true; 00046 _scroll = true; 00047 _currentRow = 0; 00048 _currentCol = 0; 00049 } 00050 00054 uint8_t MHV_Display_Character::getWidth() { 00055 return _colCount; 00056 } 00057 00061 uint8_t MHV_Display_Character::getHeight() { 00062 return _rowCount; 00063 } 00064 00072 bool MHV_Display_Character::writeString(int16_t *offsetX, uint16_t offsetY, const char *string) { 00073 const char *p = string; 00074 00075 while (*offsetX < 0) { 00076 (*offsetX)++; 00077 p++; 00078 if ('\0' == *p) { 00079 return false; 00080 } 00081 } 00082 00083 setCursor((uint16_t)*offsetX, offsetY); 00084 00085 bool ret = false; 00086 if (offsetY >= 0 && offsetY < _rowCount) { 00087 while (*p != '\0' && (*offsetX)++ < (int16_t)_colCount) { 00088 ret = true; 00089 writeChar(*p++); 00090 } 00091 } 00092 00093 return ret; 00094 } 00095 00104 bool MHV_Display_Character::writeBuffer(int16_t *offsetX, uint16_t offsetY, 00105 const char *buffer, uint16_t length) { 00106 bool ret = false; 00107 uint16_t i = 0; 00108 00109 if (*offsetX < 0) { 00110 i -= *offsetX; 00111 *offsetX = 0; 00112 } 00113 00114 setCursor((uint16_t)*offsetX, offsetY); 00115 00116 while (i < length && (*offsetX)++ < (int16_t)_colCount) { 00117 ret = true; 00118 writeChar(buffer[i++]); 00119 } 00120 00121 return ret; 00122 } 00123 00124 00132 bool MHV_Display_Character::writeString_P(int16_t *offsetX, uint16_t offsetY, PGM_P string) { 00133 const char *p = string; 00134 char c; 00135 00136 while (*offsetX < 0) { 00137 (*offsetX)++; 00138 p++; 00139 if ('\0' == pgm_read_byte(p)) { 00140 return false; 00141 } 00142 } 00143 setCursor((uint16_t)*offsetX, offsetY); 00144 00145 bool ret = false; 00146 if (offsetY >= 0 && offsetY < _rowCount) { 00147 while ('\0' != (c = pgm_read_byte(p++)) && (*offsetX)++ < (int16_t)_colCount) { 00148 ret = true; 00149 writeChar(c); 00150 } 00151 } 00152 00153 return ret; 00154 } 00155 00164 bool MHV_Display_Character::writeBuffer_P(int16_t *offsetX, uint16_t offsetY, 00165 PGM_P buffer, uint16_t length) { 00166 bool ret = false; 00167 uint16_t i = 0; 00168 00169 while (*offsetX < 0) { 00170 (*offsetX)++; 00171 i++; 00172 } 00173 setCursor((uint16_t)*offsetX, offsetY); 00174 00175 while (i < length && (*offsetX)++ < (int16_t)_colCount) { 00176 ret = true; 00177 writeChar(pgm_read_byte(buffer + i++)); 00178 } 00179 00180 return ret; 00181 } 00182 00186 void MHV_Display_Character::runTxBuffers() { 00187 _txOffset = _colCount - 1; 00188 moreTX(); 00189 } 00190 00196 bool MHV_Display_Character::txAnimation(uint16_t row) { 00197 if (!_tx) { 00198 return false; 00199 } 00200 00201 int16_t offsetX = _txOffset--; 00202 00203 setCursor(0, row); 00204 00205 bool ret; 00206 if (_currentTx.progmem) { 00207 if (_currentTx.isString) { 00208 ret = writeString_P(&offsetX, row, _tx); 00209 } else { 00210 ret = writeBuffer_P(&offsetX, row, _tx, _currentTx.length); 00211 } 00212 } else { 00213 if (_currentTx.isString) { 00214 ret = writeString(&offsetX, row, _tx); 00215 } else { 00216 ret = writeBuffer(&offsetX, row, _tx, _currentTx.length); 00217 } 00218 } 00219 00220 while (offsetX++ < (int16_t)_colCount) { 00221 writeChar(' '); 00222 } 00223 00224 if (!ret) { 00225 _txOffset = _colCount - 1; 00226 return moreTX(); 00227 } 00228 00229 return true; 00230 } 00231 00236 void MHV_Display_Character::setWrap(bool shouldWrap) { 00237 _wrap = shouldWrap; 00238 } 00239 00244 void MHV_Display_Character::setScroll(bool shouldScroll) { 00245 _scroll = shouldScroll; 00246 } 00247 00253 void MHV_Display_Character::setCursor(uint16_t col, uint16_t row) { 00254 _currentRow = row; 00255 _currentCol = col; 00256 _setCursor(col, row); 00257 } 00258 00268 void MHV_Display_Character::writeChar(char character) { 00269 switch (character) { 00270 case '\b': 00271 if (_wrap && 0 == _currentCol) { 00272 // Go to the previous line 00273 if (_currentRow + 1 < _rowCount) { 00274 _currentRow++; 00275 } 00276 setCursor(_colCount - 1, _currentRow); 00277 } else { 00278 setCursor(_currentCol - 1, _currentRow); 00279 } 00280 break; 00281 case '\t': 00282 _currentCol = (_currentCol + 4) & ~(4 - 1); 00283 if (_currentCol >= _colCount) { 00284 if (_wrap) { 00285 if (_currentRow > 0) { 00286 _currentRow--; 00287 } else if (_scroll) { 00288 scrollVertically(); 00289 break; 00290 } 00291 _currentCol = 0; 00292 } else { 00293 _currentCol = _colCount - 1; 00294 } 00295 } 00296 setCursor(_currentCol, _currentRow); 00297 break; 00298 case '\n': 00299 if (_currentRow > 0) { 00300 _currentRow--; 00301 } else if (_scroll) { 00302 scrollVertically(); 00303 } 00304 _currentCol = 0; 00305 setCursor(_currentCol, _currentRow); 00306 break; 00307 default: 00308 if (_currentCol++ >= _colCount - 1 && _wrap) { 00309 _currentCol = 0; 00310 if (_currentRow > 0) { 00311 _currentRow--; 00312 } else if (_scroll) { 00313 scrollVertically(); 00314 } else { 00315 setCursor(_currentCol, _currentRow); 00316 } 00317 } 00318 _writeChar(character); 00319 } 00320 } 00321 00325 void MHV_Display_Character::scrollVertically() { 00326 uint16_t x, y; 00327 char c; 00328 00329 for (y = _rowCount - 2; y > 0; y--) { 00330 // Copy each character in this row to the row above 00331 for (x = 0; x < _colCount; ++x) { 00332 _setCursor(x, y + 1); 00333 c = _readChar(); 00334 _setCursor(x, y); 00335 _writeChar(c); 00336 } 00337 } 00338 00339 // Blank the last row 00340 _setCursor(0, 0); 00341 for (x = 0; x < _colCount; ++x) { 00342 _writeChar(' '); 00343 } 00344 00345 // Set the cursor ready to write another line 00346 setCursor(0, 0); 00347 }