PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Committer:
spinal
Date:
Sun Nov 18 15:47:54 2018 +0000
Revision:
64:6e6c6c2b664e
Parent:
63:7d1c08cdde5c
added fix for directrectangle()

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pokitto 63:7d1c08cdde5c 1 /**************************************************************************/
Pokitto 63:7d1c08cdde5c 2 /*!
Pokitto 63:7d1c08cdde5c 3 @file PokittoDisplay.cpp
Pokitto 63:7d1c08cdde5c 4 @author Jonne Valola
Pokitto 63:7d1c08cdde5c 5
Pokitto 63:7d1c08cdde5c 6 @section LICENSE
Pokitto 63:7d1c08cdde5c 7
Pokitto 63:7d1c08cdde5c 8 Software License Agreement (BSD License)
Pokitto 63:7d1c08cdde5c 9
Pokitto 63:7d1c08cdde5c 10 Copyright (c) 2016, Jonne Valola
Pokitto 63:7d1c08cdde5c 11 All rights reserved.
Pokitto 63:7d1c08cdde5c 12
Pokitto 63:7d1c08cdde5c 13 Redistribution and use in source and binary forms, with or without
Pokitto 63:7d1c08cdde5c 14 modification, are permitted provided that the following conditions are met:
Pokitto 63:7d1c08cdde5c 15 1. Redistributions of source code must retain the above copyright
Pokitto 63:7d1c08cdde5c 16 notice, this list of conditions and the following disclaimer.
Pokitto 63:7d1c08cdde5c 17 2. Redistributions in binary form must reproduce the above copyright
Pokitto 63:7d1c08cdde5c 18 notice, this list of conditions and the following disclaimer in the
Pokitto 63:7d1c08cdde5c 19 documentation and/or other materials provided with the distribution.
Pokitto 63:7d1c08cdde5c 20 3. Neither the name of the copyright holders nor the
Pokitto 63:7d1c08cdde5c 21 names of its contributors may be used to endorse or promote products
Pokitto 63:7d1c08cdde5c 22 derived from this software without specific prior written permission.
Pokitto 63:7d1c08cdde5c 23
Pokitto 63:7d1c08cdde5c 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
Pokitto 63:7d1c08cdde5c 25 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Pokitto 63:7d1c08cdde5c 26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Pokitto 63:7d1c08cdde5c 27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
Pokitto 63:7d1c08cdde5c 28 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Pokitto 63:7d1c08cdde5c 29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Pokitto 63:7d1c08cdde5c 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
Pokitto 63:7d1c08cdde5c 31 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Pokitto 63:7d1c08cdde5c 32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Pokitto 63:7d1c08cdde5c 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Pokitto 63:7d1c08cdde5c 34 */
Pokitto 63:7d1c08cdde5c 35 /**************************************************************************/
Pokitto 63:7d1c08cdde5c 36
Pokitto 63:7d1c08cdde5c 37
Pokitto 63:7d1c08cdde5c 38 /* THE SEGMENT BELOW PERTAINS TO CIRCLE DRAWING FUNCTIONS ONLY
Pokitto 63:7d1c08cdde5c 39 *
Pokitto 63:7d1c08cdde5c 40 This is the core graphics library for all our displays, providing a common
Pokitto 63:7d1c08cdde5c 41 set of graphics primitives (points, lines, circles, etc.). It needs to be
Pokitto 63:7d1c08cdde5c 42 paired with a hardware-specific library for each display device we carry
Pokitto 63:7d1c08cdde5c 43 (to handle the lower-level functions).
Pokitto 63:7d1c08cdde5c 44 Adafruit invests time and resources providing this open source code, please
Pokitto 63:7d1c08cdde5c 45 support Adafruit & open-source hardware by purchasing products from Adafruit!
Pokitto 63:7d1c08cdde5c 46 Copyright (c) 2013 Adafruit Industries. All rights reserved.
Pokitto 63:7d1c08cdde5c 47 Redistribution and use in source and binary forms, with or without
Pokitto 63:7d1c08cdde5c 48 modification, are permitted provided that the following conditions are met:
Pokitto 63:7d1c08cdde5c 49 - Redistributions of source code must retain the above copyright notice,
Pokitto 63:7d1c08cdde5c 50 this list of conditions and the following disclaimer.
Pokitto 63:7d1c08cdde5c 51 - Redistributions in binary form must reproduce the above copyright notice,
Pokitto 63:7d1c08cdde5c 52 this list of conditions and the following disclaimer in the documentation
Pokitto 63:7d1c08cdde5c 53 and/or other materials provided with the distribution.
Pokitto 63:7d1c08cdde5c 54 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Pokitto 63:7d1c08cdde5c 55 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Pokitto 63:7d1c08cdde5c 56 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Pokitto 63:7d1c08cdde5c 57 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
Pokitto 63:7d1c08cdde5c 58 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Pokitto 63:7d1c08cdde5c 59 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Pokitto 63:7d1c08cdde5c 60 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Pokitto 63:7d1c08cdde5c 61 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Pokitto 63:7d1c08cdde5c 62 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Pokitto 63:7d1c08cdde5c 63 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Pokitto 63:7d1c08cdde5c 64 POSSIBILITY OF SUCH DAMAGE.
Pokitto 63:7d1c08cdde5c 65 */
Pokitto 63:7d1c08cdde5c 66
Pokitto 63:7d1c08cdde5c 67 #include "PokittoDisplay.h"
Pokitto 63:7d1c08cdde5c 68 #include "Pokitto_settings.h"
Pokitto 63:7d1c08cdde5c 69 #include "GBcompatibility.h"
Pokitto 63:7d1c08cdde5c 70 #include "PokittoCore.h"
Pokitto 63:7d1c08cdde5c 71 #include "PokittoSound.h"
Pokitto 63:7d1c08cdde5c 72 #include <stdio.h>
Pokitto 63:7d1c08cdde5c 73 #include <string.h>
Pokitto 63:7d1c08cdde5c 74 #ifdef DISABLEAVRMIN
Pokitto 63:7d1c08cdde5c 75 #include <algorithm>
Pokitto 63:7d1c08cdde5c 76 using std::min;
Pokitto 63:7d1c08cdde5c 77 using std::max;
Pokitto 63:7d1c08cdde5c 78 #endif // DISABLEAVRMIN
Pokitto 63:7d1c08cdde5c 79
Pokitto 63:7d1c08cdde5c 80 #ifndef POK_SIM
Pokitto 63:7d1c08cdde5c 81 #include "HWLCD.h"
Pokitto 63:7d1c08cdde5c 82 #else
Pokitto 63:7d1c08cdde5c 83 #include "SimLCD.h"
Pokitto 63:7d1c08cdde5c 84 #endif
Pokitto 63:7d1c08cdde5c 85
Pokitto 63:7d1c08cdde5c 86 extern "C" void CheckStack();
Pokitto 63:7d1c08cdde5c 87 extern char _ebss[]; // In map file
Pokitto 63:7d1c08cdde5c 88 extern char _vStackTop[]; // In map file
Pokitto 63:7d1c08cdde5c 89
Pokitto 63:7d1c08cdde5c 90 Pokitto::Core core;
Pokitto 63:7d1c08cdde5c 91 Pokitto::Sound _pdsound;
Pokitto 63:7d1c08cdde5c 92
Pokitto 63:7d1c08cdde5c 93 using namespace Pokitto;
Pokitto 63:7d1c08cdde5c 94
Pokitto 63:7d1c08cdde5c 95 uint8_t* Display::m_scrbuf;
Pokitto 63:7d1c08cdde5c 96 uint8_t* Display::m_tileset;
Pokitto 63:7d1c08cdde5c 97 uint8_t* Display::m_tilebuf;
Pokitto 63:7d1c08cdde5c 98 uint8_t* Display::m_tilecolorbuf;
Pokitto 63:7d1c08cdde5c 99 uint8_t Display::m_mode, Display::m_colordepth;
Pokitto 63:7d1c08cdde5c 100 uint8_t Display::palOffset;
Pokitto 63:7d1c08cdde5c 101 SpriteInfo Display::m_sprites[SPRITE_COUNT];
Pokitto 63:7d1c08cdde5c 102 uint8_t Display::fontSize=1;
Pokitto 63:7d1c08cdde5c 103 int16_t Display::cursorX,Display::cursorY;
Pokitto 63:7d1c08cdde5c 104 uint16_t Display::m_w,Display::m_h;
Pokitto 63:7d1c08cdde5c 105 uint8_t Display::fontWidth, Display::fontHeight;
Pokitto 63:7d1c08cdde5c 106 bool Display::textWrap=true;
Pokitto 63:7d1c08cdde5c 107
Pokitto 63:7d1c08cdde5c 108 uint8_t Display::persistence = 0;
Pokitto 63:7d1c08cdde5c 109 uint16_t Display::color = 1;
Pokitto 63:7d1c08cdde5c 110 uint16_t Display::bgcolor = 0;
Pokitto 63:7d1c08cdde5c 111 uint16_t Display::invisiblecolor = 17;
Pokitto 63:7d1c08cdde5c 112 uint16_t Display::directcolor=0xFFFF;
Pokitto 63:7d1c08cdde5c 113 uint16_t Display::directbgcolor=0x0;
Pokitto 63:7d1c08cdde5c 114 bool Display::directtextrotated=false;
Pokitto 63:7d1c08cdde5c 115 int16_t Display::clipX = 0;
Pokitto 63:7d1c08cdde5c 116 int16_t Display::clipY = 0;
Pokitto 63:7d1c08cdde5c 117 int16_t Display::clipW = LCDWIDTH;
Pokitto 63:7d1c08cdde5c 118 int16_t Display::clipH = LCDHEIGHT;
Pokitto 63:7d1c08cdde5c 119
Pokitto 63:7d1c08cdde5c 120 uint16_t* Display::paletteptr;
Pokitto 63:7d1c08cdde5c 121 uint16_t Display::palette[PALETTE_SIZE];
Pokitto 63:7d1c08cdde5c 122 const unsigned char* Display::font;
Pokitto 63:7d1c08cdde5c 123 int8_t Display::adjustCharStep = 1;
Pokitto 63:7d1c08cdde5c 124 int8_t Display::adjustLineStep = 1;
Pokitto 63:7d1c08cdde5c 125 bool Display::fixedWidthFont = false, Display::flipFontVertical = false;
Pokitto 63:7d1c08cdde5c 126
Pokitto 63:7d1c08cdde5c 127 /** drawing canvas **/
Pokitto 63:7d1c08cdde5c 128 //uint8_t* Display::canvas; // points to the active buffer. if null, draw direct to screen
Pokitto 63:7d1c08cdde5c 129
Pokitto 63:7d1c08cdde5c 130 /** screenbuffer **/
Pokitto 63:7d1c08cdde5c 131 uint8_t Display::bpp = POK_COLORDEPTH;
Pokitto 63:7d1c08cdde5c 132 #ifndef POK_TILEDMODE
Pokitto 63:7d1c08cdde5c 133 #if (POK_SCREENMODE == MODE_HI_MONOCHROME)
Pokitto 63:7d1c08cdde5c 134 uint8_t Display::width = POK_LCD_W;
Pokitto 63:7d1c08cdde5c 135 uint8_t Display::height = POK_LCD_H;
Pokitto 63:7d1c08cdde5c 136 uint8_t Display::screenbuffer[((POK_LCD_H+1)*POK_LCD_W)*POK_COLORDEPTH/8]; // maximum resolution
Pokitto 63:7d1c08cdde5c 137 #elif (POK_SCREENMODE == MODE_HI_4COLOR)
Pokitto 63:7d1c08cdde5c 138 uint8_t Display::width = POK_LCD_W;
Pokitto 63:7d1c08cdde5c 139 uint8_t Display::height = POK_LCD_H;
Pokitto 63:7d1c08cdde5c 140 uint8_t __attribute__((section (".bss"))) __attribute__ ((aligned)) Display::screenbuffer[((POK_LCD_H)*POK_LCD_W)/4]; // maximum resolution
Pokitto 63:7d1c08cdde5c 141 #elif (POK_SCREENMODE == MODE_FAST_16COLOR)
Pokitto 63:7d1c08cdde5c 142 uint8_t Display::width = POK_LCD_W/2;
Pokitto 63:7d1c08cdde5c 143 uint8_t Display::height = POK_LCD_H/2;
Pokitto 63:7d1c08cdde5c 144 uint8_t Display::screenbuffer[(((POK_LCD_H/2)+1)*POK_LCD_W/2)*POK_COLORDEPTH/8]; // half resolution
Pokitto 63:7d1c08cdde5c 145 #elif (POK_SCREENMODE == MODE_HI_16COLOR)
Pokitto 63:7d1c08cdde5c 146 uint8_t Display::width = POK_LCD_W;
Pokitto 63:7d1c08cdde5c 147 uint8_t Display::height = POK_LCD_H;
Pokitto 63:7d1c08cdde5c 148 uint8_t Display::screenbuffer[POK_LCD_H*POK_LCD_W/2]; // 4 bits per pixel
Pokitto 63:7d1c08cdde5c 149 #elif (POK_SCREENMODE == MODE_LAMENES)
Pokitto 63:7d1c08cdde5c 150 uint8_t Display::width = 128;
Pokitto 63:7d1c08cdde5c 151 uint8_t Display::height = 120;
Pokitto 63:7d1c08cdde5c 152 uint8_t Display::screenbuffer[((121)*128)*POK_COLORDEPTH/8]; // half resolution
Pokitto 63:7d1c08cdde5c 153 #elif (POK_SCREENMODE == MODE_GAMEBOY)
Pokitto 63:7d1c08cdde5c 154 uint8_t Display::width = 160;
Pokitto 63:7d1c08cdde5c 155 uint8_t Display::height = 144;
Pokitto 63:7d1c08cdde5c 156 uint8_t Display::screenbuffer[160*144/4];
Pokitto 63:7d1c08cdde5c 157 #elif (POK_SCREENMODE == MODE14)
Pokitto 63:7d1c08cdde5c 158 uint8_t Display::width = 220;
Pokitto 63:7d1c08cdde5c 159 uint8_t Display::height = 176;
Pokitto 63:7d1c08cdde5c 160 uint8_t Display::screenbuffer[14520];
Pokitto 63:7d1c08cdde5c 161 #elif (POK_SCREENMODE == MODE13)
Pokitto 63:7d1c08cdde5c 162 uint8_t Display::width = 110;
Pokitto 63:7d1c08cdde5c 163 uint8_t Display::height = 88;
Pokitto 63:7d1c08cdde5c 164 uint8_t Display::screenbuffer[110*88]; // 8bit 110x88
Pokitto 63:7d1c08cdde5c 165 #elif (POK_SCREENMODE == MIXMODE)
Pokitto 63:7d1c08cdde5c 166 uint8_t Display::width = 110;
Pokitto 63:7d1c08cdde5c 167 uint8_t Display::height = 88;
Pokitto 63:7d1c08cdde5c 168 uint8_t Display::screenbuffer[110*88]; // 8bit 110x88 or 4bit 110x176
Pokitto 63:7d1c08cdde5c 169 uint8_t Display::scanType[88]; // scanline bit depth indicator
Pokitto 63:7d1c08cdde5c 170 #elif (POK_SCREENMODE == MODE64)
Pokitto 63:7d1c08cdde5c 171 uint8_t Display::width = 110;
Pokitto 63:7d1c08cdde5c 172 uint8_t Display::height = 176;
Pokitto 63:7d1c08cdde5c 173 uint8_t __attribute__ ((aligned)) Display::screenbuffer[110*176]; // 8bit 110x176
Pokitto 63:7d1c08cdde5c 174 #elif (POK_SCREENMODE == MODE15)
Pokitto 63:7d1c08cdde5c 175 uint8_t Display::width = 220;
Pokitto 63:7d1c08cdde5c 176 uint8_t Display::height = 176;
Pokitto 63:7d1c08cdde5c 177 uint8_t __attribute__ ((aligned)) Display::screenbuffer[0x4BA0];
Pokitto 63:7d1c08cdde5c 178 #else
Pokitto 63:7d1c08cdde5c 179 uint8_t Display::width = 84;
Pokitto 63:7d1c08cdde5c 180 uint8_t Display::height = 48;
Pokitto 63:7d1c08cdde5c 181 uint8_t Display::screenbuffer[128*64]; // not needed because Gamebuino and Arduboy have their own buffer
Pokitto 63:7d1c08cdde5c 182 #endif
Pokitto 63:7d1c08cdde5c 183 #else //Tiledmode
Pokitto 63:7d1c08cdde5c 184 #if (POK_SCREENMODE == MODE_TILED_1BIT)
Pokitto 63:7d1c08cdde5c 185 uint8_t Display::width = POK_LCD_W;
Pokitto 63:7d1c08cdde5c 186 uint8_t Display::height = POK_LCD_H;
Pokitto 63:7d1c08cdde5c 187 uint8_t Display::screenbuffer[0];
Pokitto 63:7d1c08cdde5c 188 #else
Pokitto 63:7d1c08cdde5c 189 uint8_t Display::width = POK_LCD_W;
Pokitto 63:7d1c08cdde5c 190 uint8_t Display::height = POK_LCD_H;
Pokitto 63:7d1c08cdde5c 191 uint8_t Display::screenbuffer[0];
Pokitto 63:7d1c08cdde5c 192 #endif
Pokitto 63:7d1c08cdde5c 193 #endif //tiledmode
Pokitto 63:7d1c08cdde5c 194
Pokitto 63:7d1c08cdde5c 195 // RLE decoding
Pokitto 63:7d1c08cdde5c 196 #define RLE_ESC_EOL 0
Pokitto 63:7d1c08cdde5c 197 #define RLE_ESC_EOB 1
Pokitto 63:7d1c08cdde5c 198 #define RLE_ESC_OFFSET 2
Pokitto 63:7d1c08cdde5c 199
Pokitto 63:7d1c08cdde5c 200 Display::Display() {
Pokitto 63:7d1c08cdde5c 201 m_scrbuf = screenbuffer;
Pokitto 63:7d1c08cdde5c 202 setDefaultPalette();
Pokitto 63:7d1c08cdde5c 203 m_mode = 1; // direct printing on by default
Pokitto 63:7d1c08cdde5c 204 m_w = POK_LCD_W;
Pokitto 63:7d1c08cdde5c 205 m_h = POK_LCD_H;
Pokitto 63:7d1c08cdde5c 206 setFont(DEFAULT_FONT);
Pokitto 63:7d1c08cdde5c 207 invisiblecolor=17;
Pokitto 63:7d1c08cdde5c 208 bgcolor=0;
Pokitto 63:7d1c08cdde5c 209 if (POK_COLORDEPTH) m_colordepth = POK_COLORDEPTH;
Pokitto 63:7d1c08cdde5c 210 else m_colordepth = 4;
Pokitto 63:7d1c08cdde5c 211 #if POK_GAMEBUINO_SUPPORT
Pokitto 63:7d1c08cdde5c 212 setColorDepth(1);
Pokitto 63:7d1c08cdde5c 213 #endif // POK_GAMEBUINO_SUPPORT
Pokitto 63:7d1c08cdde5c 214
Pokitto 63:7d1c08cdde5c 215 // Reset sprites
Pokitto 63:7d1c08cdde5c 216 m_tilecolorbuf = NULL; //!!HV
Pokitto 63:7d1c08cdde5c 217 for (uint8_t s = 0; s < SPRITE_COUNT; s++) m_sprites[s].bitmapData = NULL;
Pokitto 63:7d1c08cdde5c 218 }
Pokitto 63:7d1c08cdde5c 219
Pokitto 63:7d1c08cdde5c 220 uint16_t Display::getWidth() {
Pokitto 63:7d1c08cdde5c 221 return width;
Pokitto 63:7d1c08cdde5c 222 }
Pokitto 63:7d1c08cdde5c 223
Pokitto 63:7d1c08cdde5c 224 uint8_t Display::getNumberOfColors() {
Pokitto 63:7d1c08cdde5c 225 return 1<<POK_COLORDEPTH;
Pokitto 63:7d1c08cdde5c 226 }
Pokitto 63:7d1c08cdde5c 227
Pokitto 63:7d1c08cdde5c 228 uint16_t Display::getHeight() {
Pokitto 63:7d1c08cdde5c 229 return height;
Pokitto 63:7d1c08cdde5c 230 }
Pokitto 63:7d1c08cdde5c 231
Pokitto 63:7d1c08cdde5c 232 uint8_t Display::getColorDepth() {
Pokitto 63:7d1c08cdde5c 233 return m_colordepth;
Pokitto 63:7d1c08cdde5c 234 }
Pokitto 63:7d1c08cdde5c 235
Pokitto 63:7d1c08cdde5c 236 void Display::setColorDepth(uint8_t v) {
Pokitto 63:7d1c08cdde5c 237 if (v > POK_COLORDEPTH) v=POK_COLORDEPTH;
Pokitto 63:7d1c08cdde5c 238 m_colordepth = v;
Pokitto 63:7d1c08cdde5c 239 }
Pokitto 63:7d1c08cdde5c 240
Pokitto 63:7d1c08cdde5c 241 void Display::clearLCD() {
Pokitto 63:7d1c08cdde5c 242 lcdFillSurface(0);
Pokitto 63:7d1c08cdde5c 243 setCursor(0,0); // old basic computer style
Pokitto 63:7d1c08cdde5c 244 }
Pokitto 63:7d1c08cdde5c 245
Pokitto 63:7d1c08cdde5c 246 void Display::fillLCD(uint16_t c) {
Pokitto 63:7d1c08cdde5c 247 lcdFillSurface(c);
Pokitto 63:7d1c08cdde5c 248 }
Pokitto 63:7d1c08cdde5c 249
Pokitto 63:7d1c08cdde5c 250 void Display::directPixel(int16_t x, int16_t y, uint16_t color) {
Pokitto 63:7d1c08cdde5c 251 if ((invisiblecolor < PALETTE_SIZE) && (invisiblecolor < 16) && (color == palette[invisiblecolor])) return;
Pokitto 63:7d1c08cdde5c 252 lcdPixel(x,y,color);
Pokitto 63:7d1c08cdde5c 253 }
Pokitto 63:7d1c08cdde5c 254
Pokitto 63:7d1c08cdde5c 255 void Display::directTile(int16_t x, int16_t y, int16_t x2, int16_t y2, uint16_t* gfx) {
Pokitto 63:7d1c08cdde5c 256 lcdTile(x,y,x2,y2,gfx);
Pokitto 63:7d1c08cdde5c 257 }
Pokitto 63:7d1c08cdde5c 258
Pokitto 63:7d1c08cdde5c 259 void Display::directRectangle(int16_t x, int16_t y,int16_t x2, int16_t y2, uint16_t color) {
Pokitto 63:7d1c08cdde5c 260 lcdRectangle(x,y,x2,y2,color);
Pokitto 63:7d1c08cdde5c 261 }
Pokitto 63:7d1c08cdde5c 262
Pokitto 63:7d1c08cdde5c 263 void Display::begin() {
Pokitto 63:7d1c08cdde5c 264 lcdInit();
Pokitto 63:7d1c08cdde5c 265 }
Pokitto 63:7d1c08cdde5c 266
Pokitto 63:7d1c08cdde5c 267 void Display::setCursor(int16_t x,int16_t y) {
Pokitto 63:7d1c08cdde5c 268 cursorX = x;
Pokitto 63:7d1c08cdde5c 269 cursorY = y;
Pokitto 63:7d1c08cdde5c 270 }
Pokitto 63:7d1c08cdde5c 271
Pokitto 63:7d1c08cdde5c 272 /**
Pokitto 63:7d1c08cdde5c 273 * Update the display.
Pokitto 63:7d1c08cdde5c 274 * The update rect is used for drawing only part of the screen buffer to LCD. Because of speed optimizations, the
Pokitto 63:7d1c08cdde5c 275 * x, y, and width of the update rect must be dividable by 4 pixels, and the height must be dividable by 8 pixels.
Pokitto 63:7d1c08cdde5c 276 * Note: The update rect is currently used for 220x176, 4 colors, screen mode only.
Pokitto 63:7d1c08cdde5c 277 * @param useDirectMode True, if only direct screen drawing is used. False, if the screen buffer is drawn. Note: If sprites are enabled, they are drawn in both modes.
Pokitto 63:7d1c08cdde5c 278 * @param updRectX The update rect.
Pokitto 63:7d1c08cdde5c 279 * @param updRectY The update rect.
Pokitto 63:7d1c08cdde5c 280 * @param updRectW The update rect.
Pokitto 63:7d1c08cdde5c 281 * @param updRectH The update rect.
Pokitto 63:7d1c08cdde5c 282 */
Pokitto 63:7d1c08cdde5c 283 void Display::update(bool useDirectDrawMode, uint8_t updRectX, uint8_t updRectY, uint8_t updRectW, uint8_t updRectH) {
Pokitto 63:7d1c08cdde5c 284
Pokitto 63:7d1c08cdde5c 285 #if POK_SCREENMODE == MODE_HI_4COLOR
Pokitto 63:7d1c08cdde5c 286 // If there is one or more sprites, use sprite enabled drawing.
Pokitto 63:7d1c08cdde5c 287 if (m_sprites[0].bitmapData != NULL)
Pokitto 63:7d1c08cdde5c 288 lcdRefreshMode1Spr(m_scrbuf, updRectX, updRectY, updRectW, updRectH, paletteptr, m_sprites, useDirectDrawMode);
Pokitto 63:7d1c08cdde5c 289 else if (!useDirectDrawMode)
Pokitto 63:7d1c08cdde5c 290 lcdRefreshMode1(m_scrbuf, updRectX, updRectY, updRectW, updRectH, paletteptr);
Pokitto 63:7d1c08cdde5c 291 #endif
Pokitto 63:7d1c08cdde5c 292
Pokitto 63:7d1c08cdde5c 293 // For the screen modes that do not support sprites, return if the direct draw mode is used.
Pokitto 63:7d1c08cdde5c 294 if (! useDirectDrawMode) {
Pokitto 63:7d1c08cdde5c 295 #if POK_SCREENMODE == MODE13
Pokitto 63:7d1c08cdde5c 296 lcdRefreshMode13(m_scrbuf, paletteptr, palOffset);
Pokitto 63:7d1c08cdde5c 297 #endif
Pokitto 63:7d1c08cdde5c 298
Pokitto 63:7d1c08cdde5c 299 #if POK_SCREENMODE == MIXMODE
Pokitto 63:7d1c08cdde5c 300 lcdRefreshMixMode(m_scrbuf, paletteptr, scanType);
Pokitto 63:7d1c08cdde5c 301 #endif
Pokitto 63:7d1c08cdde5c 302
Pokitto 63:7d1c08cdde5c 303 #if POK_SCREENMODE == MODE64
Pokitto 63:7d1c08cdde5c 304 lcdRefreshMode64(m_scrbuf, paletteptr);
Pokitto 63:7d1c08cdde5c 305 #endif
Pokitto 63:7d1c08cdde5c 306
Pokitto 63:7d1c08cdde5c 307 #if POK_SCREENMODE == MODE_GAMEBOY
Pokitto 63:7d1c08cdde5c 308 lcdRefreshModeGBC(m_scrbuf, paletteptr);
Pokitto 63:7d1c08cdde5c 309 #endif
Pokitto 63:7d1c08cdde5c 310
Pokitto 63:7d1c08cdde5c 311 #if POK_SCREENMODE == MODE_HI_16COLOR
Pokitto 63:7d1c08cdde5c 312 lcdRefreshMode3(m_scrbuf, paletteptr);
Pokitto 63:7d1c08cdde5c 313 #endif
Pokitto 63:7d1c08cdde5c 314
Pokitto 63:7d1c08cdde5c 315 #if POK_SCREENMODE == MODE_FAST_16COLOR
Pokitto 63:7d1c08cdde5c 316 lcdRefreshMode2(m_scrbuf, paletteptr);
Pokitto 63:7d1c08cdde5c 317 #endif
Pokitto 63:7d1c08cdde5c 318
Pokitto 63:7d1c08cdde5c 319 #if POK_SCREENMODE == MODE_GAMEBUINO_16COLOR
Pokitto 63:7d1c08cdde5c 320 lcdRefreshGB(m_scrbuf, paletteptr);
Pokitto 63:7d1c08cdde5c 321 #endif
Pokitto 63:7d1c08cdde5c 322
Pokitto 63:7d1c08cdde5c 323 #if POK_SCREENMODE == MODE_ARDUBOY_16COLOR
Pokitto 63:7d1c08cdde5c 324 lcdRefreshAB(m_scrbuf, paletteptr);
Pokitto 63:7d1c08cdde5c 325 #endif
Pokitto 63:7d1c08cdde5c 326
Pokitto 63:7d1c08cdde5c 327 #if POK_SCREENMODE == MODE14
Pokitto 63:7d1c08cdde5c 328 lcdRefreshMode14(m_scrbuf, paletteptr);
Pokitto 63:7d1c08cdde5c 329 #endif
Pokitto 63:7d1c08cdde5c 330
Pokitto 63:7d1c08cdde5c 331 #if POK_SCREENMODE == MODE15
Pokitto 63:7d1c08cdde5c 332 lcdRefreshMode15(paletteptr, m_scrbuf);
Pokitto 63:7d1c08cdde5c 333 #endif
Pokitto 63:7d1c08cdde5c 334
Pokitto 63:7d1c08cdde5c 335 #if POK_SCREENMODE == MODE_TILED_1BIT
Pokitto 63:7d1c08cdde5c 336 lcdRefreshT1(m_tilebuf, m_tilecolorbuf, m_tileset, paletteptr);
Pokitto 63:7d1c08cdde5c 337 #endif
Pokitto 63:7d1c08cdde5c 338 }
Pokitto 63:7d1c08cdde5c 339
Pokitto 63:7d1c08cdde5c 340 if (!persistence) clear();
Pokitto 63:7d1c08cdde5c 341
Pokitto 63:7d1c08cdde5c 342 /** draw volume bar if visible **/
Pokitto 63:7d1c08cdde5c 343 #if POK_SHOW_VOLUME > 0
Pokitto 63:7d1c08cdde5c 344 if (core.volbar_visible) {
Pokitto 63:7d1c08cdde5c 345 core.drawvolbar(4,20,_pdsound.getVolume(),true);
Pokitto 63:7d1c08cdde5c 346 core.volbar_visible--;
Pokitto 63:7d1c08cdde5c 347 }
Pokitto 63:7d1c08cdde5c 348 #endif // POK_SHOW_VOLUME
Pokitto 63:7d1c08cdde5c 349
Pokitto 63:7d1c08cdde5c 350 /** draw FPS if visible **/
Pokitto 63:7d1c08cdde5c 351 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 63:7d1c08cdde5c 352
Pokitto 63:7d1c08cdde5c 353 if(core.fps_counter_updated) {
Pokitto 63:7d1c08cdde5c 354
Pokitto 63:7d1c08cdde5c 355 // Store current state
Pokitto 63:7d1c08cdde5c 356 bool temp = isDirectPrintingEnabled();
Pokitto 63:7d1c08cdde5c 357 uint16_t oldcol = directcolor;
Pokitto 63:7d1c08cdde5c 358 uint16_t oldinvisiblecolor = invisiblecolor;
Pokitto 63:7d1c08cdde5c 359 uint16_t oldbgcol = directbgcolor;
Pokitto 63:7d1c08cdde5c 360 bool olddirecttextrotated = directtextrotated;
Pokitto 63:7d1c08cdde5c 361 int8_t oldadjustCharStep = adjustCharStep;
Pokitto 63:7d1c08cdde5c 362 const unsigned char * oldFont = font;
Pokitto 63:7d1c08cdde5c 363
Pokitto 63:7d1c08cdde5c 364 // Print FPS
Pokitto 63:7d1c08cdde5c 365 char str[16];
Pokitto 63:7d1c08cdde5c 366 sprintf(str,"FPS:%d ", (int)core.fps_counter);
Pokitto 63:7d1c08cdde5c 367 directcolor = COLOR_WHITE;
Pokitto 63:7d1c08cdde5c 368 invisiblecolor = COLOR_BLACK;
Pokitto 63:7d1c08cdde5c 369 directbgcolor = 0x0001; // Cannot be black as that is transparent color
Pokitto 63:7d1c08cdde5c 370 directtextrotated = false;
Pokitto 63:7d1c08cdde5c 371 adjustCharStep = 0;
Pokitto 63:7d1c08cdde5c 372 setFont(fontC64);
Pokitto 63:7d1c08cdde5c 373 enableDirectPrinting(true);
Pokitto 63:7d1c08cdde5c 374 print(0,0, str);
Pokitto 63:7d1c08cdde5c 375
Pokitto 63:7d1c08cdde5c 376 // Restore state
Pokitto 63:7d1c08cdde5c 377 enableDirectPrinting(temp);
Pokitto 63:7d1c08cdde5c 378 directcolor = oldcol;
Pokitto 63:7d1c08cdde5c 379 invisiblecolor = oldinvisiblecolor;
Pokitto 63:7d1c08cdde5c 380 directbgcolor = oldbgcol;
Pokitto 63:7d1c08cdde5c 381 directtextrotated = olddirecttextrotated;
Pokitto 63:7d1c08cdde5c 382 adjustCharStep = oldadjustCharStep;
Pokitto 63:7d1c08cdde5c 383 setFont(oldFont);
Pokitto 63:7d1c08cdde5c 384
Pokitto 63:7d1c08cdde5c 385 core.fps_counter_updated = false;
Pokitto 63:7d1c08cdde5c 386 }
Pokitto 63:7d1c08cdde5c 387 #endif
Pokitto 63:7d1c08cdde5c 388 }
Pokitto 63:7d1c08cdde5c 389
Pokitto 63:7d1c08cdde5c 390 void Display::directBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t depth, uint8_t scale) {
Pokitto 63:7d1c08cdde5c 391 uint8_t w = *bitmap;
Pokitto 63:7d1c08cdde5c 392 uint8_t h = *(bitmap + 1);
Pokitto 63:7d1c08cdde5c 393 bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
Pokitto 63:7d1c08cdde5c 394 int16_t i, j;
Pokitto 63:7d1c08cdde5c 395 int8_t byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 63:7d1c08cdde5c 396
Pokitto 63:7d1c08cdde5c 397 if (depth == 1) {
Pokitto 63:7d1c08cdde5c 398 for (i = 0; i < w; i++) {
Pokitto 63:7d1c08cdde5c 399 byteNum = i / 8;
Pokitto 63:7d1c08cdde5c 400 bitNum = i % 8;
Pokitto 63:7d1c08cdde5c 401 for (j = 0; j < h; j++) {
Pokitto 63:7d1c08cdde5c 402 if (*(bitmap + j * byteWidth + byteNum) & (0x80 >> bitNum)) { //0x80 = B10000000
Pokitto 63:7d1c08cdde5c 403 if (scale==1) directPixel(x + i, y + j,directcolor);
Pokitto 63:7d1c08cdde5c 404 else {
Pokitto 63:7d1c08cdde5c 405 directPixel(x + i + i, y + j + j,directcolor);
Pokitto 63:7d1c08cdde5c 406 directPixel(x + 1 + i + i, y + j + j,directcolor);
Pokitto 63:7d1c08cdde5c 407 directPixel(x + i + i, y + j + j + 1,directcolor);
Pokitto 63:7d1c08cdde5c 408 directPixel(x + i + i + 1 , y + j + j + 1,directcolor);
Pokitto 63:7d1c08cdde5c 409 }
Pokitto 63:7d1c08cdde5c 410 }
Pokitto 63:7d1c08cdde5c 411 }
Pokitto 63:7d1c08cdde5c 412 }
Pokitto 63:7d1c08cdde5c 413 } else if (depth == 4) {
Pokitto 63:7d1c08cdde5c 414 for (j = 0; j < h; j+=1) {
Pokitto 63:7d1c08cdde5c 415 for (i = 0; i < w; i+=2) {
Pokitto 63:7d1c08cdde5c 416 uint16_t col = paletteptr[*bitmap>>4]; //higher nibble
Pokitto 63:7d1c08cdde5c 417 if (scale==2) {
Pokitto 63:7d1c08cdde5c 418 directPixel(x + (i<<1), y + (j<<1),col);
Pokitto 63:7d1c08cdde5c 419 directPixel(x + (i<<1) + 1, y + (j<<1),col);
Pokitto 63:7d1c08cdde5c 420 directPixel(x + (i<<1) + 1, y + (j<<1) + 1,col);
Pokitto 63:7d1c08cdde5c 421 directPixel(x + (i<<1), y + (j<<1) + 1,col);
Pokitto 63:7d1c08cdde5c 422 } else directPixel(x + i, y + j,col);
Pokitto 63:7d1c08cdde5c 423 col = paletteptr[*bitmap&0xF]; // lower nibble
Pokitto 63:7d1c08cdde5c 424 if (scale==2) {
Pokitto 63:7d1c08cdde5c 425 directPixel(x + (i<<1) + 2, y + (j<<1),col);
Pokitto 63:7d1c08cdde5c 426 directPixel(x + (i<<1) + 1 + 2, y + (j<<1),col);
Pokitto 63:7d1c08cdde5c 427 directPixel(x + (i<<1) + 1 + 2, y + (j<<1) + 1,col);
Pokitto 63:7d1c08cdde5c 428 directPixel(x + (i<<1) + 2 , y + (j<<1) + 1,col);
Pokitto 63:7d1c08cdde5c 429 } else directPixel(x + i + 1, y + j,col);
Pokitto 63:7d1c08cdde5c 430 bitmap++;
Pokitto 63:7d1c08cdde5c 431 }
Pokitto 63:7d1c08cdde5c 432 }
Pokitto 63:7d1c08cdde5c 433 }
Pokitto 63:7d1c08cdde5c 434
Pokitto 63:7d1c08cdde5c 435 }
Pokitto 63:7d1c08cdde5c 436
Pokitto 63:7d1c08cdde5c 437 int Display::directChar(int16_t x, int16_t y, uint16_t index){
Pokitto 63:7d1c08cdde5c 438 const uint8_t* bitmap = font;
Pokitto 63:7d1c08cdde5c 439 uint8_t w = *bitmap;
Pokitto 63:7d1c08cdde5c 440 uint8_t h = *(bitmap + 1);
Pokitto 63:7d1c08cdde5c 441 uint8_t hbytes=0, xtra=1;
Pokitto 63:7d1c08cdde5c 442 if (h==8 || h==16) xtra=0; //don't add if exactly on byte limit
Pokitto 63:7d1c08cdde5c 443 hbytes=(h>>3)+xtra; //GLCD fonts are arranged w+1 times h/8 bytes
Pokitto 63:7d1c08cdde5c 444 //bitmap = bitmap + 3 + index * h * ((w>>3)+xtra); //add an offset to the pointer (fonts !)
Pokitto 63:7d1c08cdde5c 445 bitmap = bitmap + 4 + index * (w * hbytes + 1); //add an offset to the pointer (fonts !)
Pokitto 63:7d1c08cdde5c 446 //int8_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 63:7d1c08cdde5c 447 int8_t i, j, numBytes;
Pokitto 63:7d1c08cdde5c 448 numBytes = *bitmap++; //first byte of char is the width in bytes
Pokitto 63:7d1c08cdde5c 449 // GLCD fonts are arranged LSB = topmost pixel of char, so its easy to just shift through the column
Pokitto 63:7d1c08cdde5c 450 uint16_t bitcolumn; //16 bits for 2x8 bit high characters
Pokitto 63:7d1c08cdde5c 451
Pokitto 63:7d1c08cdde5c 452 for (i = 0; i < numBytes; i++) {
Pokitto 63:7d1c08cdde5c 453 bitcolumn = *bitmap++;
Pokitto 63:7d1c08cdde5c 454 if (hbytes == 2) bitcolumn |= (*bitmap++)<<8; // add second byte for 16 bit high fonts
Pokitto 63:7d1c08cdde5c 455 for (j = 0; j < h; j++) {
Pokitto 63:7d1c08cdde5c 456 if (bitcolumn&0x1) {
Pokitto 63:7d1c08cdde5c 457 if (fontSize==2) {
Pokitto 63:7d1c08cdde5c 458 directPixel(x + (i<<1) , y + (j<<1),directcolor);
Pokitto 63:7d1c08cdde5c 459 directPixel(x + (i<<1)+1, y + (j<<1),directcolor);
Pokitto 63:7d1c08cdde5c 460 directPixel(x + (i<<1) , y + (j<<1)+1,directcolor);
Pokitto 63:7d1c08cdde5c 461 directPixel(x + (i<<1)+1, y + (j<<1)+1,directcolor);
Pokitto 63:7d1c08cdde5c 462 } else {
Pokitto 63:7d1c08cdde5c 463 if(directtextrotated) directPixel(y + h - j - 1, x + i,directcolor);
Pokitto 63:7d1c08cdde5c 464 else directPixel(x + i, y + j,directcolor);
Pokitto 63:7d1c08cdde5c 465 }
Pokitto 63:7d1c08cdde5c 466
Pokitto 63:7d1c08cdde5c 467 } else if (directbgcolor != invisiblecolor) {
Pokitto 63:7d1c08cdde5c 468 if (fontSize==2) {
Pokitto 63:7d1c08cdde5c 469 directPixel(x + (i<<1) , y + (j<<1),directbgcolor);
Pokitto 63:7d1c08cdde5c 470 directPixel(x + (i<<1)+1, y + (j<<1),directbgcolor);
Pokitto 63:7d1c08cdde5c 471 directPixel(x + (i<<1) , y + (j<<1)+1,directbgcolor);
Pokitto 63:7d1c08cdde5c 472 directPixel(x + (i<<1)+1, y + (j<<1)+1,directbgcolor);
Pokitto 63:7d1c08cdde5c 473 } else {
Pokitto 63:7d1c08cdde5c 474 if(directtextrotated) directPixel(y + h - j - 1, x + i,directbgcolor);
Pokitto 63:7d1c08cdde5c 475 else directPixel(x + i, y + j,directbgcolor);
Pokitto 63:7d1c08cdde5c 476 }
Pokitto 63:7d1c08cdde5c 477 }
Pokitto 63:7d1c08cdde5c 478 bitcolumn>>=1;
Pokitto 63:7d1c08cdde5c 479 }
Pokitto 63:7d1c08cdde5c 480 }
Pokitto 63:7d1c08cdde5c 481 return (numBytes+adjustCharStep)*fontSize; // for character stepping
Pokitto 63:7d1c08cdde5c 482 }
Pokitto 63:7d1c08cdde5c 483
Pokitto 63:7d1c08cdde5c 484 int Display::bufferChar(int16_t x, int16_t y, uint16_t index){
Pokitto 63:7d1c08cdde5c 485 const uint8_t* bitmap = font;
Pokitto 63:7d1c08cdde5c 486 uint8_t w = *bitmap;
Pokitto 63:7d1c08cdde5c 487 uint8_t h = *(bitmap + 1);
Pokitto 63:7d1c08cdde5c 488 uint8_t hbytes=0, xtra=1;
Pokitto 63:7d1c08cdde5c 489 if (h==8 || h==16) xtra=0; //don't add if exactly on byte limit
Pokitto 63:7d1c08cdde5c 490 hbytes=(h>>3)+xtra; //GLCD fonts are arranged w+1 times h/8 bytes
Pokitto 63:7d1c08cdde5c 491 //bitmap = bitmap + 3 + index * h * ((w>>3)+xtra); //add an offset to the pointer (fonts !)
Pokitto 63:7d1c08cdde5c 492 bitmap = bitmap + 4 + index * (w * hbytes + 1); //add an offset to the pointer (fonts !)
Pokitto 63:7d1c08cdde5c 493 //int8_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 63:7d1c08cdde5c 494 int8_t i, j, numBytes;
Pokitto 63:7d1c08cdde5c 495 numBytes = *bitmap++; //first byte of char is the width in bytes
Pokitto 63:7d1c08cdde5c 496 // GLCD fonts are arranged LSB = topmost pixel of char, so its easy to just shift through the column
Pokitto 63:7d1c08cdde5c 497 uint16_t bitcolumn; //16 bits for 2x8 bit high characters
Pokitto 63:7d1c08cdde5c 498
Pokitto 63:7d1c08cdde5c 499 void (*drawPixelFG)(int16_t,int16_t, uint8_t) = &Display::drawPixelNOP;
Pokitto 63:7d1c08cdde5c 500 void (*drawPixelBG)(int16_t,int16_t, uint8_t) = &Display::drawPixelNOP;
Pokitto 63:7d1c08cdde5c 501 if( x>=0 && y >= 0 && x+w<width && y+h<height ){
Pokitto 63:7d1c08cdde5c 502 if( color != invisiblecolor )
Pokitto 63:7d1c08cdde5c 503 drawPixelFG = &Display::drawPixelRaw;
Pokitto 63:7d1c08cdde5c 504 if( bgcolor != invisiblecolor )
Pokitto 63:7d1c08cdde5c 505 drawPixelBG = &Display::drawPixelRaw;
Pokitto 63:7d1c08cdde5c 506 }else{
Pokitto 63:7d1c08cdde5c 507 if( color != invisiblecolor )
Pokitto 63:7d1c08cdde5c 508 drawPixelFG = &Display::drawPixel;
Pokitto 63:7d1c08cdde5c 509 if( bgcolor != invisiblecolor )
Pokitto 63:7d1c08cdde5c 510 drawPixelBG = &Display::drawPixel;
Pokitto 63:7d1c08cdde5c 511 }
Pokitto 63:7d1c08cdde5c 512
Pokitto 63:7d1c08cdde5c 513 void (*drawPixel[])(int16_t,int16_t, uint8_t) = {drawPixelBG, drawPixelFG};
Pokitto 63:7d1c08cdde5c 514 uint8_t colors[] = {bgcolor, color};
Pokitto 63:7d1c08cdde5c 515
Pokitto 63:7d1c08cdde5c 516 #if PROJ_ARDUBOY > 0
Pokitto 63:7d1c08cdde5c 517 #else
Pokitto 63:7d1c08cdde5c 518 if( fontSize != 2 ){
Pokitto 63:7d1c08cdde5c 519 #endif
Pokitto 63:7d1c08cdde5c 520
Pokitto 63:7d1c08cdde5c 521 for (i = 0; i < numBytes; i++) {
Pokitto 63:7d1c08cdde5c 522 bitcolumn = *bitmap++;
Pokitto 63:7d1c08cdde5c 523 if (hbytes == 2) bitcolumn |= (*bitmap++)<<8; // add second byte for 16 bit high fonts
Pokitto 63:7d1c08cdde5c 524 for (j = 0; j <= h; j++) { // was j<=h
Pokitto 63:7d1c08cdde5c 525 uint8_t c = colors[ bitcolumn & 1 ];
Pokitto 63:7d1c08cdde5c 526
Pokitto 63:7d1c08cdde5c 527 #if PROJ_ARDUBOY > 0
Pokitto 63:7d1c08cdde5c 528 drawPixel[ bitcolumn&1 ](x, y + 7 - j,c);
Pokitto 63:7d1c08cdde5c 529 #elif PROJ_SUPPORT_FONTROTATION > 0
Pokitto 63:7d1c08cdde5c 530 // if font flipping & rotation is allowed - do not slow down old programs!
Pokitto 63:7d1c08cdde5c 531 if (flipFontVertical) {
Pokitto 63:7d1c08cdde5c 532 drawPixel[ bitcolumn&1 ](x, y + h - j,c);
Pokitto 63:7d1c08cdde5c 533 } else {
Pokitto 63:7d1c08cdde5c 534 drawPixel[ bitcolumn&1 ](x, y + j,c);
Pokitto 63:7d1c08cdde5c 535 }
Pokitto 63:7d1c08cdde5c 536 #else
Pokitto 63:7d1c08cdde5c 537 // "Normal" case
Pokitto 63:7d1c08cdde5c 538 drawPixel[ bitcolumn&1 ](x, y + j,c);
Pokitto 63:7d1c08cdde5c 539 #endif // PROJ_ARDUBOY
Pokitto 63:7d1c08cdde5c 540 bitcolumn>>=1;
Pokitto 63:7d1c08cdde5c 541
Pokitto 63:7d1c08cdde5c 542 }
Pokitto 63:7d1c08cdde5c 543 #if PROJ_SUPPORT_FONTROTATION > 0
Pokitto 63:7d1c08cdde5c 544 if (flipFontVertical) x--;
Pokitto 63:7d1c08cdde5c 545 else x++;
Pokitto 63:7d1c08cdde5c 546 #else
Pokitto 63:7d1c08cdde5c 547 x++;
Pokitto 63:7d1c08cdde5c 548 #endif
Pokitto 63:7d1c08cdde5c 549 }
Pokitto 63:7d1c08cdde5c 550
Pokitto 63:7d1c08cdde5c 551 #if PROJ_SUPPORT_FONTROTATION > 0
Pokitto 63:7d1c08cdde5c 552 if (flipFontVertical) return -numBytes-adjustCharStep;
Pokitto 63:7d1c08cdde5c 553 else return numBytes+adjustCharStep; // for character stepping
Pokitto 63:7d1c08cdde5c 554 #else
Pokitto 63:7d1c08cdde5c 555 return numBytes+adjustCharStep;
Pokitto 63:7d1c08cdde5c 556 #endif
Pokitto 63:7d1c08cdde5c 557
Pokitto 63:7d1c08cdde5c 558
Pokitto 63:7d1c08cdde5c 559 #if PROJ_ARDUBOY > 0
Pokitto 63:7d1c08cdde5c 560 #else
Pokitto 63:7d1c08cdde5c 561 }else{
Pokitto 63:7d1c08cdde5c 562
Pokitto 63:7d1c08cdde5c 563 for (i = 0; i < numBytes; i++) {
Pokitto 63:7d1c08cdde5c 564 bitcolumn = *bitmap++;
Pokitto 63:7d1c08cdde5c 565 if (hbytes == 2) bitcolumn |= (*bitmap++)<<8; // add second byte for 16 bit high fonts
Pokitto 63:7d1c08cdde5c 566 for (j = 0; j <= h; j++) { // was j<=h
Pokitto 63:7d1c08cdde5c 567 uint8_t c = colors[ bitcolumn & 1 ];
Pokitto 63:7d1c08cdde5c 568
Pokitto 63:7d1c08cdde5c 569 drawPixel[ bitcolumn&1 ](x + (i<<1) , y + (j<<1), c);
Pokitto 63:7d1c08cdde5c 570 drawPixel[ bitcolumn&1 ](x + (i<<1)+1, y + (j<<1), c);
Pokitto 63:7d1c08cdde5c 571 drawPixel[ bitcolumn&1 ](x + (i<<1) , y + (j<<1)+1, c);
Pokitto 63:7d1c08cdde5c 572 drawPixel[ bitcolumn&1 ](x + (i<<1)+1, y + (j<<1)+1, c);
Pokitto 63:7d1c08cdde5c 573 bitcolumn>>=1;
Pokitto 63:7d1c08cdde5c 574
Pokitto 63:7d1c08cdde5c 575 }
Pokitto 63:7d1c08cdde5c 576 }
Pokitto 63:7d1c08cdde5c 577
Pokitto 63:7d1c08cdde5c 578 return (numBytes+adjustCharStep)<<1;
Pokitto 63:7d1c08cdde5c 579
Pokitto 63:7d1c08cdde5c 580 }
Pokitto 63:7d1c08cdde5c 581 #endif // PROJ_ARDUBOY
Pokitto 63:7d1c08cdde5c 582
Pokitto 63:7d1c08cdde5c 583 }
Pokitto 63:7d1c08cdde5c 584
Pokitto 63:7d1c08cdde5c 585 void Display::clear() {
Pokitto 63:7d1c08cdde5c 586
Pokitto 63:7d1c08cdde5c 587 uint8_t c=0;
Pokitto 63:7d1c08cdde5c 588 c = bgcolor & (PALETTE_SIZE-1) ; //don't let palette go out of bounds
Pokitto 63:7d1c08cdde5c 589 if (bpp==1 && bgcolor) c=0xFF; // bgcolor !=0, set all pixels
Pokitto 63:7d1c08cdde5c 590 else if (bpp==2) {
Pokitto 63:7d1c08cdde5c 591 c = bgcolor & 0x3;
Pokitto 63:7d1c08cdde5c 592 c = c | (c << 2);
Pokitto 63:7d1c08cdde5c 593 c = c | (c << 4);
Pokitto 63:7d1c08cdde5c 594 } else if (bpp==3){
Pokitto 63:7d1c08cdde5c 595 uint16_t j = POK_BITFRAME;
Pokitto 63:7d1c08cdde5c 596 if (bgcolor & 0x1) memset((void*)m_scrbuf,0xFF,j);// R
Pokitto 63:7d1c08cdde5c 597 else memset((void*)m_scrbuf,0x00,j);// R
Pokitto 63:7d1c08cdde5c 598 if ((bgcolor>>1) & 0x1) memset((void*)m_scrbuf+POK_BITFRAME,0xFF,j);// G
Pokitto 63:7d1c08cdde5c 599 else memset((void*)m_scrbuf+POK_BITFRAME,0x00,j);// G
Pokitto 63:7d1c08cdde5c 600 if ((bgcolor>>2) & 0x1) memset((void*)m_scrbuf+POK_BITFRAME*2,0xFF,j);// B
Pokitto 63:7d1c08cdde5c 601 else memset((void*)m_scrbuf+POK_BITFRAME*2,0x00,j);// B
Pokitto 63:7d1c08cdde5c 602 setCursor(0,0);
Pokitto 63:7d1c08cdde5c 603 return;
Pokitto 63:7d1c08cdde5c 604 } else if (bpp==4) {
Pokitto 63:7d1c08cdde5c 605 c = (c & 0x0F) | (c << 4);
Pokitto 63:7d1c08cdde5c 606 }
Pokitto 63:7d1c08cdde5c 607 uint16_t j = sizeof(screenbuffer);
Pokitto 63:7d1c08cdde5c 608 memset((void*)m_scrbuf,c,j);
Pokitto 63:7d1c08cdde5c 609
Pokitto 63:7d1c08cdde5c 610 setCursor(0,0);
Pokitto 63:7d1c08cdde5c 611
Pokitto 63:7d1c08cdde5c 612 }
Pokitto 63:7d1c08cdde5c 613
Pokitto 63:7d1c08cdde5c 614 void Display::scroll(int16_t pixelrows) {
Pokitto 63:7d1c08cdde5c 615 uint16_t index = 0, index2=0,oc;
Pokitto 63:7d1c08cdde5c 616 if (pixelrows==0) return;
Pokitto 63:7d1c08cdde5c 617 if (pixelrows >= height) pixelrows=height-1;
Pokitto 63:7d1c08cdde5c 618 if (bpp == 4) index2 = pixelrows*width/2;
Pokitto 63:7d1c08cdde5c 619 else if (bpp == 2) index2 = pixelrows*width/4;
Pokitto 63:7d1c08cdde5c 620 else return;
Pokitto 63:7d1c08cdde5c 621 oc = color;
Pokitto 63:7d1c08cdde5c 622 color = bgcolor;
Pokitto 63:7d1c08cdde5c 623 if (pixelrows>0) {
Pokitto 63:7d1c08cdde5c 624 for (uint16_t y=0;y<height-pixelrows;y++) {
Pokitto 63:7d1c08cdde5c 625 for (uint16_t x=0;x<(width/8)*bpp;x++) screenbuffer[index++]=screenbuffer[index2++];
Pokitto 63:7d1c08cdde5c 626 }
Pokitto 63:7d1c08cdde5c 627 fillRect(0,cursorY,width,height);
Pokitto 63:7d1c08cdde5c 628 } else {
Pokitto 63:7d1c08cdde5c 629 for (uint16_t y=pixelrows;y<height;y++) {
Pokitto 63:7d1c08cdde5c 630 for (uint16_t x=0;x<(width*bpp)/8;x++) screenbuffer[index2++]=screenbuffer[index++];
Pokitto 63:7d1c08cdde5c 631 }
Pokitto 63:7d1c08cdde5c 632 fillRect(0,0,width,pixelrows);
Pokitto 63:7d1c08cdde5c 633 }
Pokitto 63:7d1c08cdde5c 634 color=oc;
Pokitto 63:7d1c08cdde5c 635 }
Pokitto 63:7d1c08cdde5c 636
Pokitto 63:7d1c08cdde5c 637 void Display::fillScreen(uint16_t c) {
Pokitto 63:7d1c08cdde5c 638 c = c & (PALETTE_SIZE-1) ; //don't let palette go out of bounds
Pokitto 63:7d1c08cdde5c 639 if (bpp==1 && c) c=0xFF; // set all pixels
Pokitto 63:7d1c08cdde5c 640 else if (bpp==2) {
Pokitto 63:7d1c08cdde5c 641 c = c & 0x3;
Pokitto 63:7d1c08cdde5c 642 c = c | (c << 2);
Pokitto 63:7d1c08cdde5c 643 c = c | (c << 4);
Pokitto 63:7d1c08cdde5c 644 } else {
Pokitto 63:7d1c08cdde5c 645 c = (c & 0x0F) | (c << 4);
Pokitto 63:7d1c08cdde5c 646 }
Pokitto 63:7d1c08cdde5c 647 memset((void*)m_scrbuf,c,sizeof(screenbuffer));
Pokitto 63:7d1c08cdde5c 648 }
Pokitto 63:7d1c08cdde5c 649
Pokitto 63:7d1c08cdde5c 650 void Display::setDefaultPalette() {
Pokitto 63:7d1c08cdde5c 651 #if PICOPALETTE
Pokitto 63:7d1c08cdde5c 652 loadRGBPalette(palettePico);
Pokitto 63:7d1c08cdde5c 653 #else
Pokitto 63:7d1c08cdde5c 654 loadRGBPalette(POK_DEFAULT_PALETTE);
Pokitto 63:7d1c08cdde5c 655 #endif //PICOPALETTE
Pokitto 63:7d1c08cdde5c 656 }
Pokitto 63:7d1c08cdde5c 657
Pokitto 63:7d1c08cdde5c 658 void Display::setColor(uint8_t c) {
Pokitto 63:7d1c08cdde5c 659 color = c & ((1<<POK_COLORDEPTH)-1); // cut out colors that go above palette limit
Pokitto 63:7d1c08cdde5c 660 }
Pokitto 63:7d1c08cdde5c 661
Pokitto 63:7d1c08cdde5c 662 void Display::setColor(uint8_t c,uint8_t bgc){
Pokitto 63:7d1c08cdde5c 663 color = c & ((1<<POK_COLORDEPTH)-1); // cut out colors that go above palette limit
Pokitto 63:7d1c08cdde5c 664 bgcolor = bgc & ((1<<POK_COLORDEPTH)-1); // cut out colors that go above palette limit
Pokitto 63:7d1c08cdde5c 665 }
Pokitto 63:7d1c08cdde5c 666
Pokitto 63:7d1c08cdde5c 667 void Display::setInvisibleColor(uint16_t c){
Pokitto 63:7d1c08cdde5c 668 invisiblecolor = c; // invisible color can have values beyond 255 for identification purposes
Pokitto 63:7d1c08cdde5c 669 }
Pokitto 63:7d1c08cdde5c 670
Pokitto 63:7d1c08cdde5c 671 uint8_t Display::getColor() {
Pokitto 63:7d1c08cdde5c 672 return color;
Pokitto 63:7d1c08cdde5c 673 }
Pokitto 63:7d1c08cdde5c 674
Pokitto 63:7d1c08cdde5c 675 uint8_t Display::getBgColor() {
Pokitto 63:7d1c08cdde5c 676 return bgcolor;
Pokitto 63:7d1c08cdde5c 677 }
Pokitto 63:7d1c08cdde5c 678
Pokitto 63:7d1c08cdde5c 679 uint16_t Display::getInvisibleColor() {
Pokitto 63:7d1c08cdde5c 680 return invisiblecolor;
Pokitto 63:7d1c08cdde5c 681 }
Pokitto 63:7d1c08cdde5c 682
Pokitto 63:7d1c08cdde5c 683 void Display::setClipRect(int16_t x, int16_t y, int16_t w, int16_t h) {
Pokitto 63:7d1c08cdde5c 684 clipX = x; clipY = y; clipW = w; clipH = h;
Pokitto 63:7d1c08cdde5c 685 }
Pokitto 63:7d1c08cdde5c 686
Pokitto 63:7d1c08cdde5c 687 void Display::drawPixelNOP(int16_t x,int16_t y, uint8_t col) {
Pokitto 63:7d1c08cdde5c 688 }
Pokitto 63:7d1c08cdde5c 689
Pokitto 63:7d1c08cdde5c 690 void Display::drawPixelRaw(int16_t x,int16_t y, uint8_t col) {
Pokitto 63:7d1c08cdde5c 691 #if POK_COLORDEPTH == 8
Pokitto 63:7d1c08cdde5c 692 m_scrbuf[x+width*y] = col;
Pokitto 63:7d1c08cdde5c 693 #endif
Pokitto 63:7d1c08cdde5c 694
Pokitto 63:7d1c08cdde5c 695 #if POK_GAMEBUINO_SUPPORT >0
Pokitto 63:7d1c08cdde5c 696
Pokitto 63:7d1c08cdde5c 697 uint8_t c = col;
Pokitto 63:7d1c08cdde5c 698 uint8_t ct = col;
Pokitto 63:7d1c08cdde5c 699
Pokitto 63:7d1c08cdde5c 700 uint16_t bitptr=0;
Pokitto 63:7d1c08cdde5c 701 for (uint8_t cbit=0;cbit<POK_COLORDEPTH;cbit++) {
Pokitto 63:7d1c08cdde5c 702 c = ct & 1; // take the lowest bit of the color index number
Pokitto 63:7d1c08cdde5c 703 if(c == 0){ //white - or actually "Clear bit"
Pokitto 63:7d1c08cdde5c 704 m_scrbuf[x + (y / 8) * LCDWIDTH + bitptr] &= ~_BV(y % 8);
Pokitto 63:7d1c08cdde5c 705 } else { //black - or actually "Set bit"
Pokitto 63:7d1c08cdde5c 706 m_scrbuf[x + (y / 8) * LCDWIDTH + bitptr] |= _BV(y % 8);
Pokitto 63:7d1c08cdde5c 707 }
Pokitto 63:7d1c08cdde5c 708 ct >>=1; // shift to get next bit
Pokitto 63:7d1c08cdde5c 709 bitptr += POK_BITFRAME; // move one screen worth of buffer forward to get to the next color bit
Pokitto 63:7d1c08cdde5c 710 } // POK_COLOURDEPTH
Pokitto 63:7d1c08cdde5c 711
Pokitto 63:7d1c08cdde5c 712 #else
Pokitto 63:7d1c08cdde5c 713 #if POK_COLORDEPTH == 1
Pokitto 63:7d1c08cdde5c 714 if (col) {m_scrbuf[(y >> 3) * width + x] |= (0x80 >> (y & 7)); return;}
Pokitto 63:7d1c08cdde5c 715 m_scrbuf[(y >> 3) * width + x] &= ~(0x80 >> (y & 7));
Pokitto 63:7d1c08cdde5c 716 #elif POK_COLORDEPTH == 2
Pokitto 63:7d1c08cdde5c 717 if (col) {
Pokitto 63:7d1c08cdde5c 718 col &= 3;
Pokitto 63:7d1c08cdde5c 719 }
Pokitto 63:7d1c08cdde5c 720 uint16_t i = y*(width>>2) + (x>>2);
Pokitto 63:7d1c08cdde5c 721 uint8_t pixel = m_scrbuf[i];
Pokitto 63:7d1c08cdde5c 722 uint8_t column = x&0x03;
Pokitto 63:7d1c08cdde5c 723 if (column==3) pixel = (pixel&0xFC)|(col); // bits 0-1
Pokitto 63:7d1c08cdde5c 724 else if (column==2) pixel = (pixel&0xF3)|(col<<2); // bits 2-3
Pokitto 63:7d1c08cdde5c 725 else if (column==1) pixel = (pixel&0xCF)|(col<<4); // bits 4-5
Pokitto 63:7d1c08cdde5c 726 else pixel = (pixel&0x3F)|(col<<6); // bits 6-7
Pokitto 63:7d1c08cdde5c 727 m_scrbuf[i] = pixel;
Pokitto 63:7d1c08cdde5c 728 #elif POK_COLORDEPTH == 3
Pokitto 63:7d1c08cdde5c 729 uint8_t c = col;
Pokitto 63:7d1c08cdde5c 730 uint8_t ct = col;
Pokitto 63:7d1c08cdde5c 731
Pokitto 63:7d1c08cdde5c 732 uint16_t bitptr=0;
Pokitto 63:7d1c08cdde5c 733 for (uint8_t cbit=0;cbit<POK_COLORDEPTH;cbit++) {
Pokitto 63:7d1c08cdde5c 734 c = ct & 1; // take the lowest bit of the color index number
Pokitto 63:7d1c08cdde5c 735 if(c == 0){ //white - or actually "Clear bit"
Pokitto 63:7d1c08cdde5c 736 m_scrbuf[x + (y / 8) * LCDWIDTH + bitptr] &= ~_BV(y % 8);
Pokitto 63:7d1c08cdde5c 737 } else { //black - or actually "Set bit"
Pokitto 63:7d1c08cdde5c 738 m_scrbuf[x + (y / 8) * LCDWIDTH + bitptr] |= _BV(y % 8);
Pokitto 63:7d1c08cdde5c 739 }
Pokitto 63:7d1c08cdde5c 740 ct >>=1; // shift to get next bit
Pokitto 63:7d1c08cdde5c 741 bitptr += POK_BITFRAME; // move one screen worth of buffer forward to get to the next color bit
Pokitto 63:7d1c08cdde5c 742 } // POK_COLOURDEPTH
Pokitto 63:7d1c08cdde5c 743 #elif POK_COLORDEPTH == 4
Pokitto 63:7d1c08cdde5c 744 uint16_t i = y*(width>>1) + (x>>1);
Pokitto 63:7d1c08cdde5c 745 uint8_t pixel = m_scrbuf[i];
Pokitto 63:7d1c08cdde5c 746 if (x&1) pixel = (pixel&0xF0)|(col);
Pokitto 63:7d1c08cdde5c 747 else pixel = (pixel&0x0F) | (col<<4);
Pokitto 63:7d1c08cdde5c 748 m_scrbuf[i] = pixel;
Pokitto 63:7d1c08cdde5c 749 #endif // POK_COLORDEPTH
Pokitto 63:7d1c08cdde5c 750 #endif // POK_GAMEBUINO_SUPPORT
Pokitto 63:7d1c08cdde5c 751 }
Pokitto 63:7d1c08cdde5c 752
Pokitto 63:7d1c08cdde5c 753 void Display::drawPixel(int16_t x,int16_t y, uint8_t col) {
Pokitto 63:7d1c08cdde5c 754 if (col==invisiblecolor) return; // do not draw transparent pixels
Pokitto 63:7d1c08cdde5c 755 if ((uint16_t)x >= width || (uint16_t)y >= height) return;
Pokitto 63:7d1c08cdde5c 756 col &= (PALETTE_SIZE-1);
Pokitto 63:7d1c08cdde5c 757 drawPixelRaw( x, y, col );
Pokitto 63:7d1c08cdde5c 758 }
Pokitto 63:7d1c08cdde5c 759
Pokitto 63:7d1c08cdde5c 760 void Display::drawPixel(int16_t x,int16_t y) {
Pokitto 63:7d1c08cdde5c 761 if ((uint16_t)x >= width || (uint16_t)y >= height) return;
Pokitto 63:7d1c08cdde5c 762 drawPixelRaw( x, y, color );
Pokitto 63:7d1c08cdde5c 763 }
Pokitto 63:7d1c08cdde5c 764
Pokitto 63:7d1c08cdde5c 765 uint8_t Display::getPixel(int16_t x,int16_t y) {
Pokitto 63:7d1c08cdde5c 766 if ((uint16_t)x >= width || (uint16_t)y >= height) return 0;
Pokitto 63:7d1c08cdde5c 767 #if POK_COLORDEPTH == 8
Pokitto 63:7d1c08cdde5c 768 uint16_t i = y*width+x;
Pokitto 63:7d1c08cdde5c 769 return m_scrbuf[i];
Pokitto 63:7d1c08cdde5c 770 #endif // POK_COLORDEPTH
Pokitto 63:7d1c08cdde5c 771
Pokitto 63:7d1c08cdde5c 772 #if POK_GAMEBUINO_SUPPORT
Pokitto 63:7d1c08cdde5c 773 uint8_t color=0; //jonne
Pokitto 63:7d1c08cdde5c 774 for (uint8_t cbit=0; cbit<POK_COLORDEPTH;cbit++) {
Pokitto 63:7d1c08cdde5c 775 color |= (m_scrbuf[x + (y / 8) * LCDWIDTH+POK_BITFRAME*cbit] >> (y % 8)) & 0x1 ; //jonne - added +504*cbit
Pokitto 63:7d1c08cdde5c 776 }
Pokitto 63:7d1c08cdde5c 777 return color;
Pokitto 63:7d1c08cdde5c 778 #else
Pokitto 63:7d1c08cdde5c 779 /** not gamebuino */
Pokitto 63:7d1c08cdde5c 780 #if POK_COLORDEPTH == 1
Pokitto 63:7d1c08cdde5c 781 return (m_scrbuf[(y >> 3) * width + x] & (0x80 >> (y & 7))) ? 1:0;
Pokitto 63:7d1c08cdde5c 782 #elif POK_COLORDEPTH == 2
Pokitto 63:7d1c08cdde5c 783 uint16_t i = y*(width>>2) + (x>>2);
Pokitto 63:7d1c08cdde5c 784 uint8_t pixel = m_scrbuf[i];
Pokitto 63:7d1c08cdde5c 785 uint8_t column = x&0x03;
Pokitto 63:7d1c08cdde5c 786 if (column==0) return pixel & 0x03; // bits 0-1
Pokitto 63:7d1c08cdde5c 787 else if (column==1) return (pixel & 0x0C)>>2; // bits 2-3
Pokitto 63:7d1c08cdde5c 788 else if (column==2) return (pixel & 0x30)>>4; // bits 4-5
Pokitto 63:7d1c08cdde5c 789 else return pixel>>6;; // bits 6-7
Pokitto 63:7d1c08cdde5c 790 #elif POK_COLORDEPTH == 3
Pokitto 63:7d1c08cdde5c 791 #elif POK_COLORDEPTH == 4
Pokitto 63:7d1c08cdde5c 792 uint16_t i = y*(width>>1) + (x>>1);
Pokitto 63:7d1c08cdde5c 793 uint8_t pixel = m_scrbuf[i];
Pokitto 63:7d1c08cdde5c 794 if (x&1) return pixel & 0x0F;
Pokitto 63:7d1c08cdde5c 795 else return pixel>>4;
Pokitto 63:7d1c08cdde5c 796 #endif // POK_COLORDEPTH
Pokitto 63:7d1c08cdde5c 797 #endif // POK_GAMEBUINO_SUPPORT
Pokitto 63:7d1c08cdde5c 798 }
Pokitto 63:7d1c08cdde5c 799
Pokitto 63:7d1c08cdde5c 800 void Display::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
Pokitto 63:7d1c08cdde5c 801 if ((uint16_t)x0 >= width || (uint16_t)y0 >= height || (uint16_t)x1 >= width || (uint16_t)y1 >= height ) {
Pokitto 63:7d1c08cdde5c 802 if (clipLine (&x0,&y0,&x1,&y1)==0) return; // line out of bounds
Pokitto 63:7d1c08cdde5c 803 }
Pokitto 63:7d1c08cdde5c 804 if (x0 == x1)
Pokitto 63:7d1c08cdde5c 805 drawColumn(x0,y0,y1);
Pokitto 63:7d1c08cdde5c 806 else if (y0 == y1)
Pokitto 63:7d1c08cdde5c 807 drawRow(x0,x1,y0);
Pokitto 63:7d1c08cdde5c 808 else {
Pokitto 63:7d1c08cdde5c 809 int e;
Pokitto 63:7d1c08cdde5c 810 signed int dx,dy,j, temp;
Pokitto 63:7d1c08cdde5c 811 signed char s1,s2, xchange;
Pokitto 63:7d1c08cdde5c 812 signed int x,y;
Pokitto 63:7d1c08cdde5c 813
Pokitto 63:7d1c08cdde5c 814 x = x0;
Pokitto 63:7d1c08cdde5c 815 y = y0;
Pokitto 63:7d1c08cdde5c 816
Pokitto 63:7d1c08cdde5c 817 //take absolute value
Pokitto 63:7d1c08cdde5c 818 if (x1 < x0) {
Pokitto 63:7d1c08cdde5c 819 dx = x0 - x1;
Pokitto 63:7d1c08cdde5c 820 s1 = -1;
Pokitto 63:7d1c08cdde5c 821 }
Pokitto 63:7d1c08cdde5c 822 else if (x1 == x0) {
Pokitto 63:7d1c08cdde5c 823 dx = 0;
Pokitto 63:7d1c08cdde5c 824 s1 = 0;
Pokitto 63:7d1c08cdde5c 825 }
Pokitto 63:7d1c08cdde5c 826 else {
Pokitto 63:7d1c08cdde5c 827 dx = x1 - x0;
Pokitto 63:7d1c08cdde5c 828 s1 = 1;
Pokitto 63:7d1c08cdde5c 829 }
Pokitto 63:7d1c08cdde5c 830
Pokitto 63:7d1c08cdde5c 831 if (y1 < y0) {
Pokitto 63:7d1c08cdde5c 832 dy = y0 - y1;
Pokitto 63:7d1c08cdde5c 833 s2 = -1;
Pokitto 63:7d1c08cdde5c 834 }
Pokitto 63:7d1c08cdde5c 835 else if (y1 == y0) {
Pokitto 63:7d1c08cdde5c 836 dy = 0;
Pokitto 63:7d1c08cdde5c 837 s2 = 0;
Pokitto 63:7d1c08cdde5c 838 }
Pokitto 63:7d1c08cdde5c 839 else {
Pokitto 63:7d1c08cdde5c 840 dy = y1 - y0;
Pokitto 63:7d1c08cdde5c 841 s2 = 1;
Pokitto 63:7d1c08cdde5c 842 }
Pokitto 63:7d1c08cdde5c 843
Pokitto 63:7d1c08cdde5c 844 xchange = 0;
Pokitto 63:7d1c08cdde5c 845
Pokitto 63:7d1c08cdde5c 846 if (dy>dx) {
Pokitto 63:7d1c08cdde5c 847 temp = dx;
Pokitto 63:7d1c08cdde5c 848 dx = dy;
Pokitto 63:7d1c08cdde5c 849 dy = temp;
Pokitto 63:7d1c08cdde5c 850 xchange = 1;
Pokitto 63:7d1c08cdde5c 851 }
Pokitto 63:7d1c08cdde5c 852
Pokitto 63:7d1c08cdde5c 853 e = ((int)dy<<1) - dx;
Pokitto 63:7d1c08cdde5c 854
Pokitto 63:7d1c08cdde5c 855 for (j=0; j<=dx; j++) {
Pokitto 63:7d1c08cdde5c 856 drawPixel(x,y);
Pokitto 63:7d1c08cdde5c 857
Pokitto 63:7d1c08cdde5c 858 if (e>=0) {
Pokitto 63:7d1c08cdde5c 859 if (xchange==1) x = x + s1;
Pokitto 63:7d1c08cdde5c 860 else y = y + s2;
Pokitto 63:7d1c08cdde5c 861 e = e - ((int)dx<<1);
Pokitto 63:7d1c08cdde5c 862 }
Pokitto 63:7d1c08cdde5c 863 if (xchange==1)
Pokitto 63:7d1c08cdde5c 864 y = y + s2;
Pokitto 63:7d1c08cdde5c 865 else
Pokitto 63:7d1c08cdde5c 866 x = x + s1;
Pokitto 63:7d1c08cdde5c 867 e = e + ((int)dy<<1);
Pokitto 63:7d1c08cdde5c 868 }
Pokitto 63:7d1c08cdde5c 869 }
Pokitto 63:7d1c08cdde5c 870 }
Pokitto 63:7d1c08cdde5c 871
Pokitto 63:7d1c08cdde5c 872 uint8_t Display::clipLine(int16_t *x0, int16_t *y0, int16_t *x1, int16_t *y1){
Pokitto 63:7d1c08cdde5c 873 // Check X bounds
Pokitto 63:7d1c08cdde5c 874 if (*x1 < *x0) {
Pokitto 63:7d1c08cdde5c 875 //std::swap (*x1,*x0); // swap so that we dont have to check x1 also
Pokitto 63:7d1c08cdde5c 876 swapWT(int16_t*, x1, x0);
Pokitto 63:7d1c08cdde5c 877 //std::swap (*y1,*y0); // y needs to be swaaped also
Pokitto 63:7d1c08cdde5c 878 swapWT(int16_t*, y1, y0);
Pokitto 63:7d1c08cdde5c 879 }
Pokitto 63:7d1c08cdde5c 880
Pokitto 63:7d1c08cdde5c 881 if (*x0 >= width) return 0; // whole line is out of bounds
Pokitto 63:7d1c08cdde5c 882
Pokitto 63:7d1c08cdde5c 883 // Clip against X0 = 0
Pokitto 63:7d1c08cdde5c 884 if (*x0 < 0) {
Pokitto 63:7d1c08cdde5c 885 if (*x1 < 0) return 0; // nothing visible
Pokitto 63:7d1c08cdde5c 886 int32_t dx = (*x1 - *x0);
Pokitto 63:7d1c08cdde5c 887 int32_t dy = ((*y1 - *y0) << 16); // 16.16 fixed point calculation trick
Pokitto 63:7d1c08cdde5c 888 int32_t m = dy/dx;
Pokitto 63:7d1c08cdde5c 889 *y0 = *y0 + ((m*-*x0) >> 16); // get y0 at boundary
Pokitto 63:7d1c08cdde5c 890 *x0 = 0;
Pokitto 63:7d1c08cdde5c 891 }
Pokitto 63:7d1c08cdde5c 892
Pokitto 63:7d1c08cdde5c 893 // Clip against x1 >= width
Pokitto 63:7d1c08cdde5c 894 if (*x1 >= width) {
Pokitto 63:7d1c08cdde5c 895 int32_t dx = (*x1 - *x0);
Pokitto 63:7d1c08cdde5c 896 int32_t dy = ((*y1 - *y0) << 16); // 16.16 fixed point calculation trick
Pokitto 63:7d1c08cdde5c 897 int32_t m = dy / dx;
Pokitto 63:7d1c08cdde5c 898 *y1 = *y1 + ((m * ((width - 1) - *x1)) >> 16); // get y0 at boundary
Pokitto 63:7d1c08cdde5c 899 *x1 = width-1;
Pokitto 63:7d1c08cdde5c 900 }
Pokitto 63:7d1c08cdde5c 901
Pokitto 63:7d1c08cdde5c 902 // Check Y bounds
Pokitto 63:7d1c08cdde5c 903 if (*y1 < *y0) {
Pokitto 63:7d1c08cdde5c 904 //std::swap (*x1,*x0); // swap so that we dont have to check x1 also
Pokitto 63:7d1c08cdde5c 905 swapWT(int16_t*, x1, x0);
Pokitto 63:7d1c08cdde5c 906 //std::swap (*y1,*y0); // y needs to be swaaped also
Pokitto 63:7d1c08cdde5c 907 swapWT(int16_t*, y1, y0);
Pokitto 63:7d1c08cdde5c 908 }
Pokitto 63:7d1c08cdde5c 909
Pokitto 63:7d1c08cdde5c 910 if (*y0 >= height) return 0; // whole line is out of bounds
Pokitto 63:7d1c08cdde5c 911
Pokitto 63:7d1c08cdde5c 912 if (*y0 < 0) {
Pokitto 63:7d1c08cdde5c 913 if (*y1 < 0) return 0; // nothing visible
Pokitto 63:7d1c08cdde5c 914 int32_t dx = (*x1 - *x0) << 16;
Pokitto 63:7d1c08cdde5c 915 int32_t dy = (*y1 - *y0); // 16.16 fixed point calculation trick
Pokitto 63:7d1c08cdde5c 916 int32_t m = dx / dy;
Pokitto 63:7d1c08cdde5c 917 *x0 = *x0 + ((m * -(*y0)) >> 16); // get x0 at boundary
Pokitto 63:7d1c08cdde5c 918 *y0 = 0;
Pokitto 63:7d1c08cdde5c 919 }
Pokitto 63:7d1c08cdde5c 920
Pokitto 63:7d1c08cdde5c 921 // Clip against y1 >= height
Pokitto 63:7d1c08cdde5c 922 if (*y1 >= height) {
Pokitto 63:7d1c08cdde5c 923 int32_t dx = (*x1 - *x0) << 16;
Pokitto 63:7d1c08cdde5c 924 int32_t dy = (*y1 - *y0); // 16.16 fixed point calculation trick
Pokitto 63:7d1c08cdde5c 925 int32_t m = dx / dy;
Pokitto 63:7d1c08cdde5c 926 *x1 = *x1 + ((m * ((height - 1) - *y1)) >> 16); // get y0 at boundary
Pokitto 63:7d1c08cdde5c 927 *y1 = height-1;
Pokitto 63:7d1c08cdde5c 928 }
Pokitto 63:7d1c08cdde5c 929 return 1; // clipped succesfully
Pokitto 63:7d1c08cdde5c 930 }
Pokitto 63:7d1c08cdde5c 931
Pokitto 63:7d1c08cdde5c 932 void Display::map1BitColumn(int16_t x, int16_t sy, int16_t ey, const uint8_t* bitmap, uint16_t column){
Pokitto 63:7d1c08cdde5c 933 if ((uint16_t)sy>=height && (uint16_t)ey>=height) return; //completely out of bounds
Pokitto 63:7d1c08cdde5c 934 if ((uint16_t)x>=width) return; //completely out of bounds
Pokitto 63:7d1c08cdde5c 935 if (sy>ey) {
Pokitto 63:7d1c08cdde5c 936 int y=sy;
Pokitto 63:7d1c08cdde5c 937 sy=ey;
Pokitto 63:7d1c08cdde5c 938 ey=y; // swap around so that x0 is less than x1
Pokitto 63:7d1c08cdde5c 939 }
Pokitto 63:7d1c08cdde5c 940 uint16_t bmw,bmh;
Pokitto 63:7d1c08cdde5c 941 float texelstep, texelindex;
Pokitto 63:7d1c08cdde5c 942 bmw = *(bitmap);
Pokitto 63:7d1c08cdde5c 943 bmh = *(bitmap+1);
Pokitto 63:7d1c08cdde5c 944 if (column>bmw-1) column=bmw-1;
Pokitto 63:7d1c08cdde5c 945 bitmap += 2;
Pokitto 63:7d1c08cdde5c 946 bitmap += column;
Pokitto 63:7d1c08cdde5c 947 texelstep = (float)bmh/((float)ey-(float)sy);
Pokitto 63:7d1c08cdde5c 948 texelindex = 0;
Pokitto 63:7d1c08cdde5c 949 for (int y=sy; y <= ey; y++, texelindex += texelstep) {
Pokitto 63:7d1c08cdde5c 950 uint8_t texel;
Pokitto 63:7d1c08cdde5c 951 uint8_t currbyte, bit;
Pokitto 63:7d1c08cdde5c 952 currbyte = texelindex / 8;
Pokitto 63:7d1c08cdde5c 953 bit = 7-((uint16_t) texelindex & 0x7);
Pokitto 63:7d1c08cdde5c 954 texel=*(bitmap+currbyte*bmw);
Pokitto 63:7d1c08cdde5c 955 if (texel & (1<<bit)) drawPixel(x,y);
Pokitto 63:7d1c08cdde5c 956 else if (bgcolor != invisiblecolor) drawPixel(x,y,bgcolor);
Pokitto 63:7d1c08cdde5c 957 }
Pokitto 63:7d1c08cdde5c 958 };
Pokitto 63:7d1c08cdde5c 959
Pokitto 63:7d1c08cdde5c 960 void Display::drawColumn(int16_t x, int16_t sy, int16_t ey){
Pokitto 63:7d1c08cdde5c 961 if ((uint16_t)sy>=height && (uint16_t)ey>=height) return; //completely out of bounds
Pokitto 63:7d1c08cdde5c 962 if ((uint16_t)x>=width) return; //completely out of bounds
Pokitto 63:7d1c08cdde5c 963 if (sy>ey) {
Pokitto 63:7d1c08cdde5c 964 int y=sy;
Pokitto 63:7d1c08cdde5c 965 sy=ey;
Pokitto 63:7d1c08cdde5c 966 ey=y; // swap around so that x0 is less than x1
Pokitto 63:7d1c08cdde5c 967 }
Pokitto 63:7d1c08cdde5c 968 for (int y=sy; y <= ey; y++) {
Pokitto 63:7d1c08cdde5c 969 drawPixel(x,y);
Pokitto 63:7d1c08cdde5c 970 }
Pokitto 63:7d1c08cdde5c 971 }
Pokitto 63:7d1c08cdde5c 972
Pokitto 63:7d1c08cdde5c 973 void Display::drawRow(int16_t x0, int16_t x1, int16_t y){
Pokitto 63:7d1c08cdde5c 974 if ((uint16_t)x0>=width && (uint16_t)x1>=width) return; //completely out of bounds
Pokitto 63:7d1c08cdde5c 975 if ((uint16_t)y>=height) return; //completely out of bounds
Pokitto 63:7d1c08cdde5c 976
Pokitto 63:7d1c08cdde5c 977 if (x0>x1) {
Pokitto 63:7d1c08cdde5c 978 int x=x0;
Pokitto 63:7d1c08cdde5c 979 x0=x1;
Pokitto 63:7d1c08cdde5c 980 x1=x; // swap around so that x0 is less than x1
Pokitto 63:7d1c08cdde5c 981 }
Pokitto 63:7d1c08cdde5c 982 for (int x=x0; x <= x1; x++) {
Pokitto 63:7d1c08cdde5c 983 drawPixel(x,y);
Pokitto 63:7d1c08cdde5c 984 }
Pokitto 63:7d1c08cdde5c 985 }
Pokitto 63:7d1c08cdde5c 986
Pokitto 63:7d1c08cdde5c 987 void Display::drawFastVLine(int16_t x, int16_t y, int16_t h){
Pokitto 63:7d1c08cdde5c 988 if (h<0) {y += h; h = -h;}
Pokitto 63:7d1c08cdde5c 989 drawColumn(x,y,y+h);
Pokitto 63:7d1c08cdde5c 990 }
Pokitto 63:7d1c08cdde5c 991
Pokitto 63:7d1c08cdde5c 992 void Display::drawFastHLine(int16_t x, int16_t y, int16_t w){
Pokitto 63:7d1c08cdde5c 993 if (w<0) {x += w; w = -w;}
Pokitto 63:7d1c08cdde5c 994 drawRow(x,x+w-1,y);
Pokitto 63:7d1c08cdde5c 995 }
Pokitto 63:7d1c08cdde5c 996
Pokitto 63:7d1c08cdde5c 997 void Display::drawRectangle(int16_t x0, int16_t y0, int16_t w, int16_t h) {
Pokitto 63:7d1c08cdde5c 998 drawColumn(x0,y0,y0+h);
Pokitto 63:7d1c08cdde5c 999 drawColumn(x0+w,y0,y0+h);
Pokitto 63:7d1c08cdde5c 1000 drawRow(x0,x0+w,y0);
Pokitto 63:7d1c08cdde5c 1001 drawRow(x0,x0+w,y0+h);
Pokitto 63:7d1c08cdde5c 1002 }
Pokitto 63:7d1c08cdde5c 1003
Pokitto 63:7d1c08cdde5c 1004 void Display::fillRectangle(int16_t x0,int16_t y0, int16_t w, int16_t h){
Pokitto 63:7d1c08cdde5c 1005 int16_t x,y,x1,y1;
Pokitto 63:7d1c08cdde5c 1006 x1=x0+w;y1=y0+h;
Pokitto 63:7d1c08cdde5c 1007 if ((x0<0 && x1<0) || (x0>=width && x1 >=width)) return; //completely out of bounds
Pokitto 63:7d1c08cdde5c 1008 if ((y0<0 && y1<0) || (y0>=height && y1 >=height)) return; //completely out of bounds
Pokitto 63:7d1c08cdde5c 1009 if (x0>x1) {x=x1;x1=x0;}
Pokitto 63:7d1c08cdde5c 1010 else x=x0;
Pokitto 63:7d1c08cdde5c 1011 if (y0>y1) {y=y1;y1=y0;}
Pokitto 63:7d1c08cdde5c 1012 else y=y0;
Pokitto 63:7d1c08cdde5c 1013 if (x<0) x=0;
Pokitto 63:7d1c08cdde5c 1014 if (y<0) y=0;
Pokitto 63:7d1c08cdde5c 1015 for (;x<x1;x++) drawColumn(x,y,y1);
Pokitto 63:7d1c08cdde5c 1016 }
Pokitto 63:7d1c08cdde5c 1017
Pokitto 63:7d1c08cdde5c 1018 void Display::fillRect(int16_t x, int16_t y, int16_t w, int16_t h) {
Pokitto 63:7d1c08cdde5c 1019 fillRectangle(x,y,w,h);
Pokitto 63:7d1c08cdde5c 1020 }
Pokitto 63:7d1c08cdde5c 1021
Pokitto 63:7d1c08cdde5c 1022 void Display::drawRect(int16_t x, int16_t y, int16_t w, int16_t h) {
Pokitto 63:7d1c08cdde5c 1023 drawRectangle(x,y,w,h);
Pokitto 63:7d1c08cdde5c 1024 }
Pokitto 63:7d1c08cdde5c 1025
Pokitto 63:7d1c08cdde5c 1026 void Display::drawCircle(int16_t x0, int16_t y0, int16_t r) {
Pokitto 63:7d1c08cdde5c 1027 int16_t f = 1 - r;
Pokitto 63:7d1c08cdde5c 1028 int16_t ddF_x = 1;
Pokitto 63:7d1c08cdde5c 1029 int16_t ddF_y = -2 * r;
Pokitto 63:7d1c08cdde5c 1030 int16_t x = 0;
Pokitto 63:7d1c08cdde5c 1031 int16_t y = r;
Pokitto 63:7d1c08cdde5c 1032
Pokitto 63:7d1c08cdde5c 1033 drawPixel(x0, y0 + r);
Pokitto 63:7d1c08cdde5c 1034 drawPixel(x0, y0 - r);
Pokitto 63:7d1c08cdde5c 1035 drawPixel(x0 + r, y0);
Pokitto 63:7d1c08cdde5c 1036 drawPixel(x0 - r, y0);
Pokitto 63:7d1c08cdde5c 1037
Pokitto 63:7d1c08cdde5c 1038 while (x < y) {
Pokitto 63:7d1c08cdde5c 1039 if (f >= 0) {
Pokitto 63:7d1c08cdde5c 1040
Pokitto 63:7d1c08cdde5c 1041 y--;
Pokitto 63:7d1c08cdde5c 1042 ddF_y += 2;
Pokitto 63:7d1c08cdde5c 1043 f += ddF_y;
Pokitto 63:7d1c08cdde5c 1044 }
Pokitto 63:7d1c08cdde5c 1045 x++;
Pokitto 63:7d1c08cdde5c 1046 ddF_x += 2;
Pokitto 63:7d1c08cdde5c 1047 f += ddF_x;
Pokitto 63:7d1c08cdde5c 1048
Pokitto 63:7d1c08cdde5c 1049 drawPixel(x0 + x, y0 + y);
Pokitto 63:7d1c08cdde5c 1050 drawPixel(x0 - x, y0 + y);
Pokitto 63:7d1c08cdde5c 1051 drawPixel(x0 + x, y0 - y);
Pokitto 63:7d1c08cdde5c 1052 drawPixel(x0 - x, y0 - y);
Pokitto 63:7d1c08cdde5c 1053 drawPixel(x0 + y, y0 + x);
Pokitto 63:7d1c08cdde5c 1054 drawPixel(x0 - y, y0 + x);
Pokitto 63:7d1c08cdde5c 1055 drawPixel(x0 + y, y0 - x);
Pokitto 63:7d1c08cdde5c 1056 drawPixel(x0 - y, y0 - x);
Pokitto 63:7d1c08cdde5c 1057
Pokitto 63:7d1c08cdde5c 1058 }
Pokitto 63:7d1c08cdde5c 1059 }
Pokitto 63:7d1c08cdde5c 1060
Pokitto 63:7d1c08cdde5c 1061 void Display::drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint16_t cornername) {
Pokitto 63:7d1c08cdde5c 1062 int16_t f = 1 - r;
Pokitto 63:7d1c08cdde5c 1063 int16_t ddF_x = 1;
Pokitto 63:7d1c08cdde5c 1064 int16_t ddF_y = -2 * r;
Pokitto 63:7d1c08cdde5c 1065 int16_t x = 0;
Pokitto 63:7d1c08cdde5c 1066 int16_t y = r;
Pokitto 63:7d1c08cdde5c 1067
Pokitto 63:7d1c08cdde5c 1068 while (x < y) {
Pokitto 63:7d1c08cdde5c 1069 if (f >= 0) {
Pokitto 63:7d1c08cdde5c 1070 y--;
Pokitto 63:7d1c08cdde5c 1071 ddF_y += 2;
Pokitto 63:7d1c08cdde5c 1072 f += ddF_y;
Pokitto 63:7d1c08cdde5c 1073 }
Pokitto 63:7d1c08cdde5c 1074 x++;
Pokitto 63:7d1c08cdde5c 1075 ddF_x += 2;
Pokitto 63:7d1c08cdde5c 1076 f += ddF_x;
Pokitto 63:7d1c08cdde5c 1077 if (cornername & 0x4) {
Pokitto 63:7d1c08cdde5c 1078 drawPixel(x0 + x, y0 + y);
Pokitto 63:7d1c08cdde5c 1079 drawPixel(x0 + y, y0 + x);
Pokitto 63:7d1c08cdde5c 1080 }
Pokitto 63:7d1c08cdde5c 1081 if (cornername & 0x2) {
Pokitto 63:7d1c08cdde5c 1082 drawPixel(x0 + x, y0 - y);
Pokitto 63:7d1c08cdde5c 1083 drawPixel(x0 + y, y0 - x);
Pokitto 63:7d1c08cdde5c 1084 }
Pokitto 63:7d1c08cdde5c 1085 if (cornername & 0x8) {
Pokitto 63:7d1c08cdde5c 1086 drawPixel(x0 - y, y0 + x);
Pokitto 63:7d1c08cdde5c 1087 drawPixel(x0 - x, y0 + y);
Pokitto 63:7d1c08cdde5c 1088 }
Pokitto 63:7d1c08cdde5c 1089 if (cornername & 0x1) {
Pokitto 63:7d1c08cdde5c 1090
Pokitto 63:7d1c08cdde5c 1091 drawPixel(x0 - y, y0 - x);
Pokitto 63:7d1c08cdde5c 1092 drawPixel(x0 - x, y0 - y);
Pokitto 63:7d1c08cdde5c 1093 }
Pokitto 63:7d1c08cdde5c 1094 }
Pokitto 63:7d1c08cdde5c 1095 }
Pokitto 63:7d1c08cdde5c 1096
Pokitto 63:7d1c08cdde5c 1097 void Display::fillCircle(int16_t x0, int16_t y0, int16_t r) {
Pokitto 63:7d1c08cdde5c 1098 drawFastVLine(x0, y0 - r, 2 * r );
Pokitto 63:7d1c08cdde5c 1099 fillCircleHelper(x0, y0, r, 3, 0);
Pokitto 63:7d1c08cdde5c 1100 }
Pokitto 63:7d1c08cdde5c 1101
Pokitto 63:7d1c08cdde5c 1102 void Display::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint16_t cornername, int16_t delta) {
Pokitto 63:7d1c08cdde5c 1103 int16_t f = 1 - r;
Pokitto 63:7d1c08cdde5c 1104 int16_t ddF_x = 1;
Pokitto 63:7d1c08cdde5c 1105 int16_t ddF_y = -2 * r;
Pokitto 63:7d1c08cdde5c 1106 int16_t x = 0;
Pokitto 63:7d1c08cdde5c 1107 int16_t y = r;
Pokitto 63:7d1c08cdde5c 1108
Pokitto 63:7d1c08cdde5c 1109 while (x < y) {
Pokitto 63:7d1c08cdde5c 1110 if (f >= 0) {
Pokitto 63:7d1c08cdde5c 1111 y--;
Pokitto 63:7d1c08cdde5c 1112 ddF_y += 2;
Pokitto 63:7d1c08cdde5c 1113 f += ddF_y;
Pokitto 63:7d1c08cdde5c 1114 }
Pokitto 63:7d1c08cdde5c 1115 x++;
Pokitto 63:7d1c08cdde5c 1116 ddF_x += 2;
Pokitto 63:7d1c08cdde5c 1117 f += ddF_x;
Pokitto 63:7d1c08cdde5c 1118
Pokitto 63:7d1c08cdde5c 1119 if (cornername & 0x1) {
Pokitto 63:7d1c08cdde5c 1120 drawFastVLine(x0 + x, y0 - y, 2 * y + 1 + delta-1); //added -1 here, jonne
Pokitto 63:7d1c08cdde5c 1121 drawFastVLine(x0 + y, y0 - x, 2 * x + 1 + delta-1); //added -1 here, jonne
Pokitto 63:7d1c08cdde5c 1122 }
Pokitto 63:7d1c08cdde5c 1123 if (cornername & 0x2) {
Pokitto 63:7d1c08cdde5c 1124
Pokitto 63:7d1c08cdde5c 1125 drawFastVLine(x0 - x, y0 - y, 2 * y + 1 + delta-1); //added -1 here, jonne
Pokitto 63:7d1c08cdde5c 1126 drawFastVLine(x0 - y, y0 - x, 2 * x + 1 + delta-1); //added -1 here, jonne
Pokitto 63:7d1c08cdde5c 1127 }
Pokitto 63:7d1c08cdde5c 1128 }
Pokitto 63:7d1c08cdde5c 1129 }
Pokitto 63:7d1c08cdde5c 1130
Pokitto 63:7d1c08cdde5c 1131 void Display::drawRoundRect(int16_t x, int16_t y, int16_t w,int16_t h, int16_t r) {
Pokitto 63:7d1c08cdde5c 1132 if (r<2) {drawRectangle(x,y,w,h);return;}
Pokitto 63:7d1c08cdde5c 1133 // smarter version
Pokitto 63:7d1c08cdde5c 1134 drawFastHLine(x + r, y, w - 2 * r); // Top
Pokitto 63:7d1c08cdde5c 1135 drawFastHLine(x + r, y + h - 1, w - 2 * r); // Bottom
Pokitto 63:7d1c08cdde5c 1136 drawFastVLine(x, y + r, h - 2 * r); // Left
Pokitto 63:7d1c08cdde5c 1137 drawFastVLine(x + w - 1, y + r, h - 2 * r); // Right
Pokitto 63:7d1c08cdde5c 1138 // draw four corners
Pokitto 63:7d1c08cdde5c 1139 drawCircleHelper(x + r, y + r, r, 1);
Pokitto 63:7d1c08cdde5c 1140 drawCircleHelper(x + w - r - 1, y + r, r, 2);
Pokitto 63:7d1c08cdde5c 1141 drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4);
Pokitto 63:7d1c08cdde5c 1142 drawCircleHelper(x + r, y + h - r - 1, r, 8);
Pokitto 63:7d1c08cdde5c 1143 }
Pokitto 63:7d1c08cdde5c 1144
Pokitto 63:7d1c08cdde5c 1145 void Display::fillRoundRect(int16_t x, int16_t y, int16_t w,int16_t h, int16_t r) {
Pokitto 63:7d1c08cdde5c 1146 if (r<2) {fillRectangle(x,y,w,h);return;}
Pokitto 63:7d1c08cdde5c 1147 fillRectangle(x + r, y, w - 2 * r, h-1);
Pokitto 63:7d1c08cdde5c 1148 // draw four corners
Pokitto 63:7d1c08cdde5c 1149 fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1);
Pokitto 63:7d1c08cdde5c 1150 fillCircleHelper(x + r, y + r, r, 2, h - 2 * r - 1);
Pokitto 63:7d1c08cdde5c 1151 }
Pokitto 63:7d1c08cdde5c 1152
Pokitto 63:7d1c08cdde5c 1153 void Display::drawTriangle(int16_t x0, int16_t y0,
Pokitto 63:7d1c08cdde5c 1154 int16_t x1, int16_t y1,
Pokitto 63:7d1c08cdde5c 1155 int16_t x2, int16_t y2) {
Pokitto 63:7d1c08cdde5c 1156 drawLine(x0, y0, x1, y1);
Pokitto 63:7d1c08cdde5c 1157 drawLine(x1, y1, x2, y2);
Pokitto 63:7d1c08cdde5c 1158 drawLine(x2, y2, x0, y0);
Pokitto 63:7d1c08cdde5c 1159 }
Pokitto 63:7d1c08cdde5c 1160
Pokitto 63:7d1c08cdde5c 1161 void Display::fillTriangle(int16_t x0, int16_t y0,
Pokitto 63:7d1c08cdde5c 1162 int16_t x1, int16_t y1,
Pokitto 63:7d1c08cdde5c 1163 int16_t x2, int16_t y2) {
Pokitto 63:7d1c08cdde5c 1164 int16_t a, b, y, last;
Pokitto 63:7d1c08cdde5c 1165
Pokitto 63:7d1c08cdde5c 1166 // Sort coordinates by Y order (y2 >= y1 >= y0)
Pokitto 63:7d1c08cdde5c 1167 if (y0 > y1) {
Pokitto 63:7d1c08cdde5c 1168 swapWT(int16_t,y0, y1);
Pokitto 63:7d1c08cdde5c 1169 swapWT(int16_t,x0, x1);
Pokitto 63:7d1c08cdde5c 1170 }
Pokitto 63:7d1c08cdde5c 1171 if (y1 > y2) {
Pokitto 63:7d1c08cdde5c 1172 swapWT(int16_t,y2, y1);
Pokitto 63:7d1c08cdde5c 1173 swapWT(int16_t,x2, x1);
Pokitto 63:7d1c08cdde5c 1174 }
Pokitto 63:7d1c08cdde5c 1175 if (y0 > y1) {
Pokitto 63:7d1c08cdde5c 1176 swapWT(int16_t,y0, y1);
Pokitto 63:7d1c08cdde5c 1177 swapWT(int16_t,x0, x1);
Pokitto 63:7d1c08cdde5c 1178 }
Pokitto 63:7d1c08cdde5c 1179
Pokitto 63:7d1c08cdde5c 1180 if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing
Pokitto 63:7d1c08cdde5c 1181 a = b = x0;
Pokitto 63:7d1c08cdde5c 1182 if (x1 < a) a = x1;
Pokitto 63:7d1c08cdde5c 1183 else if (x1 > b) b = x1;
Pokitto 63:7d1c08cdde5c 1184 if (x2 < a) a = x2;
Pokitto 63:7d1c08cdde5c 1185 else if (x2 > b) b = x2;
Pokitto 63:7d1c08cdde5c 1186 drawFastHLine(a, y0, b - a + 1);
Pokitto 63:7d1c08cdde5c 1187 return;
Pokitto 63:7d1c08cdde5c 1188 }
Pokitto 63:7d1c08cdde5c 1189
Pokitto 63:7d1c08cdde5c 1190 int16_t
Pokitto 63:7d1c08cdde5c 1191 dx01 = x1 - x0,
Pokitto 63:7d1c08cdde5c 1192 dy01 = y1 - y0,
Pokitto 63:7d1c08cdde5c 1193 dx02 = x2 - x0,
Pokitto 63:7d1c08cdde5c 1194 dy02 = y2 - y0,
Pokitto 63:7d1c08cdde5c 1195 dx12 = x2 - x1,
Pokitto 63:7d1c08cdde5c 1196 dy12 = y2 - y1,
Pokitto 63:7d1c08cdde5c 1197 sa = 0,
Pokitto 63:7d1c08cdde5c 1198 sb = 0;
Pokitto 63:7d1c08cdde5c 1199
Pokitto 63:7d1c08cdde5c 1200 // For upper part of triangle, find scanline crossings for segments
Pokitto 63:7d1c08cdde5c 1201 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
Pokitto 63:7d1c08cdde5c 1202 // is included here (and second loop will be skipped, avoiding a /0
Pokitto 63:7d1c08cdde5c 1203 // error there), otherwise scanline y1 is skipped here and handled
Pokitto 63:7d1c08cdde5c 1204 // in the second loop...which also avoids a /0 error here if y0=y1
Pokitto 63:7d1c08cdde5c 1205 // (flat-topped triangle).
Pokitto 63:7d1c08cdde5c 1206 if (y1 == y2) last = y1; // Include y1 scanline
Pokitto 63:7d1c08cdde5c 1207 else last = y1 - 1; // Skip it
Pokitto 63:7d1c08cdde5c 1208
Pokitto 63:7d1c08cdde5c 1209 for (y = y0; y <= last; y++) {
Pokitto 63:7d1c08cdde5c 1210 a = x0 + sa / dy01;
Pokitto 63:7d1c08cdde5c 1211 b = x0 + sb / dy02;
Pokitto 63:7d1c08cdde5c 1212 sa += dx01;
Pokitto 63:7d1c08cdde5c 1213 sb += dx02;
Pokitto 63:7d1c08cdde5c 1214 /* longhand:
Pokitto 63:7d1c08cdde5c 1215 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
Pokitto 63:7d1c08cdde5c 1216 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
Pokitto 63:7d1c08cdde5c 1217 */
Pokitto 63:7d1c08cdde5c 1218 if (a > b) swapWT(int16_t,a, b);
Pokitto 63:7d1c08cdde5c 1219 drawFastHLine(a, y, b - a + 1);
Pokitto 63:7d1c08cdde5c 1220 }
Pokitto 63:7d1c08cdde5c 1221
Pokitto 63:7d1c08cdde5c 1222 // For lower part of triangle, find scanline crossings for segments
Pokitto 63:7d1c08cdde5c 1223 // 0-2 and 1-2. This loop is skipped if y1=y2.
Pokitto 63:7d1c08cdde5c 1224 sa = dx12 * (y - y1);
Pokitto 63:7d1c08cdde5c 1225 sb = dx02 * (y - y0);
Pokitto 63:7d1c08cdde5c 1226 for (; y <= y2; y++) {
Pokitto 63:7d1c08cdde5c 1227 a = x1 + sa / dy12;
Pokitto 63:7d1c08cdde5c 1228 b = x0 + sb / dy02;
Pokitto 63:7d1c08cdde5c 1229 sa += dx12;
Pokitto 63:7d1c08cdde5c 1230 sb += dx02;
Pokitto 63:7d1c08cdde5c 1231
Pokitto 63:7d1c08cdde5c 1232 if (a > b) swapWT(int16_t,a, b);
Pokitto 63:7d1c08cdde5c 1233 drawFastHLine(a, y, b - a + 1);
Pokitto 63:7d1c08cdde5c 1234 }
Pokitto 63:7d1c08cdde5c 1235 }
Pokitto 63:7d1c08cdde5c 1236
Pokitto 63:7d1c08cdde5c 1237 void Display::setFont(const unsigned char * f) {
Pokitto 63:7d1c08cdde5c 1238 font = f;
Pokitto 63:7d1c08cdde5c 1239 fontWidth = *(font)+1;
Pokitto 63:7d1c08cdde5c 1240 fontHeight = *(font + 1)+1;
Pokitto 63:7d1c08cdde5c 1241 }
Pokitto 63:7d1c08cdde5c 1242
Pokitto 63:7d1c08cdde5c 1243 void Display::drawMonoBitmap(int16_t x, int16_t y, const uint8_t* bitmap, uint8_t index) {
Pokitto 63:7d1c08cdde5c 1244 uint8_t w = *bitmap;
Pokitto 63:7d1c08cdde5c 1245 uint8_t h = *(bitmap + 1);
Pokitto 63:7d1c08cdde5c 1246 uint8_t xtra=0;
Pokitto 63:7d1c08cdde5c 1247 if (w&0x7) xtra=1;
Pokitto 63:7d1c08cdde5c 1248 bitmap = bitmap + 3 + index * h * ((w>>3)+xtra); //add an offset to the pointer (fonts !)
Pokitto 63:7d1c08cdde5c 1249 #if POK_GAMEBUINO_SUPPORT > 0
Pokitto 63:7d1c08cdde5c 1250 int8_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 63:7d1c08cdde5c 1251 for (i = 0; i < w; i++) {
Pokitto 63:7d1c08cdde5c 1252 byteNum = i / 8;
Pokitto 63:7d1c08cdde5c 1253 bitNum = i % 8;
Pokitto 63:7d1c08cdde5c 1254 for (j = 0; j < h; j++) {
Pokitto 63:7d1c08cdde5c 1255 uint8_t source = *(bitmap + j * byteWidth + byteNum);
Pokitto 63:7d1c08cdde5c 1256 if (source & (0x80 >> bitNum)) {
Pokitto 63:7d1c08cdde5c 1257 drawPixel(x + i, y + j);
Pokitto 63:7d1c08cdde5c 1258 }
Pokitto 63:7d1c08cdde5c 1259 }
Pokitto 63:7d1c08cdde5c 1260 }
Pokitto 63:7d1c08cdde5c 1261 #else
Pokitto 63:7d1c08cdde5c 1262 /** not gamebuino */
Pokitto 63:7d1c08cdde5c 1263 int8_t scrx,scry;
Pokitto 63:7d1c08cdde5c 1264 uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
Pokitto 63:7d1c08cdde5c 1265 int8_t bitptr;
Pokitto 63:7d1c08cdde5c 1266 for (scry = y; scry < y+h; scry+=1) {
Pokitto 63:7d1c08cdde5c 1267 if ((x&1)==0) { /** EVEN pixel starting line**/
Pokitto 63:7d1c08cdde5c 1268 for (scrx = x, bitptr=7; scrx < w+x; scrx+=2) {
Pokitto 63:7d1c08cdde5c 1269 uint8_t targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1270 if (*bitmap & (1<<bitptr)) targetpixel = (targetpixel & 0xF) | color<<4; // upper nibble
Pokitto 63:7d1c08cdde5c 1271 else if (bgcolor != invisiblecolor) targetpixel = (targetpixel & 0xF) | bgcolor<<4; // upper nibble
Pokitto 63:7d1c08cdde5c 1272 bitptr--;
Pokitto 63:7d1c08cdde5c 1273 if (*bitmap & (1<<bitptr)) targetpixel = (targetpixel & 0xF0) | color; // lower nibble
Pokitto 63:7d1c08cdde5c 1274 else if (bgcolor != invisiblecolor) targetpixel = (targetpixel & 0xF0) | bgcolor; // lower nibble
Pokitto 63:7d1c08cdde5c 1275 bitptr--;
Pokitto 63:7d1c08cdde5c 1276 if (bitptr<0) { bitptr = 7; bitmap++; }
Pokitto 63:7d1c08cdde5c 1277 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1278 scrptr++;
Pokitto 63:7d1c08cdde5c 1279 }
Pokitto 63:7d1c08cdde5c 1280 } else { /** ODD pixel starting line **/
Pokitto 63:7d1c08cdde5c 1281 for (scrx = x, bitptr=7; scrx < w+x; scrx+=2) {
Pokitto 63:7d1c08cdde5c 1282 uint8_t targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1283 // store higher nibble of source pixel in lower nibble of target
Pokitto 63:7d1c08cdde5c 1284 if (*bitmap & (1<<bitptr)) targetpixel = (targetpixel & 0xF0) | color; // lower nibble
Pokitto 63:7d1c08cdde5c 1285 else if (bgcolor != invisiblecolor) targetpixel = (targetpixel & 0xF0) | bgcolor; // lower nibble
Pokitto 63:7d1c08cdde5c 1286 *scrptr = targetpixel; // store
Pokitto 63:7d1c08cdde5c 1287 bitptr--;scrptr++;targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1288 // store lower nibble of source pixel in higher nibble of target
Pokitto 63:7d1c08cdde5c 1289 if (*bitmap & (1<<bitptr)) targetpixel = (targetpixel & 0xF) | color<<4; // higher nibble
Pokitto 63:7d1c08cdde5c 1290 else if (bgcolor != invisiblecolor) targetpixel = (targetpixel & 0xF) | bgcolor<<4; // higher nibble
Pokitto 63:7d1c08cdde5c 1291 *scrptr = targetpixel; // store
Pokitto 63:7d1c08cdde5c 1292 bitptr--; // do not increment scrptr here !
Pokitto 63:7d1c08cdde5c 1293 }
Pokitto 63:7d1c08cdde5c 1294 }
Pokitto 63:7d1c08cdde5c 1295 if (bitptr!=7) bitmap++; // force skip to next line
Pokitto 63:7d1c08cdde5c 1296 // increment the y jump in the scrptr
Pokitto 63:7d1c08cdde5c 1297 scrptr = scrptr + ((width - w)>>1);
Pokitto 63:7d1c08cdde5c 1298 }
Pokitto 63:7d1c08cdde5c 1299 #endif // POK_GAMEBUINO_SUPPORT
Pokitto 63:7d1c08cdde5c 1300 }
Pokitto 63:7d1c08cdde5c 1301
Pokitto 63:7d1c08cdde5c 1302
Pokitto 63:7d1c08cdde5c 1303 void Display::drawBitmap(int16_t x, int16_t y, const uint8_t* bitmap, uint8_t frame)
Pokitto 63:7d1c08cdde5c 1304 {
Pokitto 63:7d1c08cdde5c 1305 int16_t w = *bitmap;
Pokitto 63:7d1c08cdde5c 1306 int16_t h = *(bitmap + 1);
Pokitto 63:7d1c08cdde5c 1307 uint8_t framew = *(bitmap+2);
Pokitto 63:7d1c08cdde5c 1308 bitmap = bitmap + 3; //add an offset to the pointer to start after the width and height
Pokitto 63:7d1c08cdde5c 1309 /** visibility check */
Pokitto 63:7d1c08cdde5c 1310 if (y<-h || y>height) return; //invisible
Pokitto 63:7d1c08cdde5c 1311 if (x<-framew || x>width) return; //invisible
Pokitto 63:7d1c08cdde5c 1312 /** 1 bpp mode */
Pokitto 63:7d1c08cdde5c 1313 if (m_colordepth<2) {
Pokitto 63:7d1c08cdde5c 1314 int16_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 63:7d1c08cdde5c 1315 for (i = 0; i < w; i++) {
Pokitto 63:7d1c08cdde5c 1316 byteNum = i / 8;
Pokitto 63:7d1c08cdde5c 1317 bitNum = i % 8;
Pokitto 63:7d1c08cdde5c 1318 for (j = 0; j < h; j++) {
Pokitto 63:7d1c08cdde5c 1319 uint8_t source = *(bitmap + j * byteWidth + byteNum);
Pokitto 63:7d1c08cdde5c 1320 if (source & (0x80 >> bitNum)) {
Pokitto 63:7d1c08cdde5c 1321 drawPixel(x + i, y + j);
Pokitto 63:7d1c08cdde5c 1322 }
Pokitto 63:7d1c08cdde5c 1323 }
Pokitto 63:7d1c08cdde5c 1324 }
Pokitto 63:7d1c08cdde5c 1325
Pokitto 63:7d1c08cdde5c 1326 return;
Pokitto 63:7d1c08cdde5c 1327 }
Pokitto 63:7d1c08cdde5c 1328 /** 2 bpp mode */
Pokitto 63:7d1c08cdde5c 1329 if (m_colordepth<4) {
Pokitto 63:7d1c08cdde5c 1330 int16_t i, j, byteNum, bitNum, byteWidth = w >> 2;
Pokitto 63:7d1c08cdde5c 1331 for (i = 0; i < w; i++) {
Pokitto 63:7d1c08cdde5c 1332 byteNum = i / 4;
Pokitto 63:7d1c08cdde5c 1333 bitNum = (i % 4)<<1;
Pokitto 63:7d1c08cdde5c 1334 for (j = 0; j < h; j++) {
Pokitto 63:7d1c08cdde5c 1335 uint8_t source = *(bitmap + j * byteWidth + byteNum);
Pokitto 63:7d1c08cdde5c 1336 uint8_t output = (source & (0xC0 >> bitNum));
Pokitto 63:7d1c08cdde5c 1337 output >>= (6-bitNum);
Pokitto 63:7d1c08cdde5c 1338 if (output != invisiblecolor) {
Pokitto 63:7d1c08cdde5c 1339 setColor(output);
Pokitto 63:7d1c08cdde5c 1340 drawPixel(x + i, y + j);
Pokitto 63:7d1c08cdde5c 1341 }
Pokitto 63:7d1c08cdde5c 1342 }
Pokitto 63:7d1c08cdde5c 1343 }
Pokitto 63:7d1c08cdde5c 1344
Pokitto 63:7d1c08cdde5c 1345 return;
Pokitto 63:7d1c08cdde5c 1346 }
Pokitto 63:7d1c08cdde5c 1347 /** 4bpp fast version */
Pokitto 63:7d1c08cdde5c 1348 int16_t scrx,scry,xclip,xjump,scrxjump;
Pokitto 63:7d1c08cdde5c 1349 xclip=xjump=scrxjump=0;
Pokitto 63:7d1c08cdde5c 1350 bitmap += (framew*frame)>>1;
Pokitto 63:7d1c08cdde5c 1351 /** y clipping */
Pokitto 63:7d1c08cdde5c 1352 if (y<0) { h+=y; bitmap -= y*(w>>1); y=0;}
Pokitto 63:7d1c08cdde5c 1353 else if (y+h>height) { h -=(y-height);}
Pokitto 63:7d1c08cdde5c 1354 /** x clipping */
Pokitto 63:7d1c08cdde5c 1355 xjump = (w-framew)>>1;
Pokitto 63:7d1c08cdde5c 1356 if (x<0) { xclip=(x&1)<<1; framew+=x; xjump = ((-x)>>1); bitmap += xjump; x=0;}
Pokitto 63:7d1c08cdde5c 1357 else if (x+framew>width) {
Pokitto 63:7d1c08cdde5c 1358 xclip = (x&1)<<1;
Pokitto 63:7d1c08cdde5c 1359 scrxjump = x&1;
Pokitto 63:7d1c08cdde5c 1360 xjump=((x+framew-width)>>1)+scrxjump;
Pokitto 63:7d1c08cdde5c 1361 framew = width-x;}
Pokitto 63:7d1c08cdde5c 1362
Pokitto 63:7d1c08cdde5c 1363 uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
Pokitto 63:7d1c08cdde5c 1364 /** ONLY 4-bit mode for time being **/
Pokitto 63:7d1c08cdde5c 1365 for (scry = y; scry < y+h; scry+=1) {
Pokitto 63:7d1c08cdde5c 1366 if (scry>=height) return;
Pokitto 63:7d1c08cdde5c 1367 if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
Pokitto 63:7d1c08cdde5c 1368 for (scrx = x; scrx < framew+x-xclip; scrx+=2) {
Pokitto 63:7d1c08cdde5c 1369 uint8_t sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 1370 if (xclip) {
Pokitto 63:7d1c08cdde5c 1371 sourcepixel <<=4;
Pokitto 63:7d1c08cdde5c 1372 sourcepixel |= ((*(bitmap+1))>>4);
Pokitto 63:7d1c08cdde5c 1373 }
Pokitto 63:7d1c08cdde5c 1374 uint8_t targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1375 if ((sourcepixel>>4) != invisiblecolor ) targetpixel = (targetpixel&0x0F) | (sourcepixel & 0xF0);
Pokitto 63:7d1c08cdde5c 1376 if ((sourcepixel&0x0F) != invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel & 0x0F);
Pokitto 63:7d1c08cdde5c 1377 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1378 bitmap++;
Pokitto 63:7d1c08cdde5c 1379 scrptr++;
Pokitto 63:7d1c08cdde5c 1380 }
Pokitto 63:7d1c08cdde5c 1381 if (xclip){
Pokitto 63:7d1c08cdde5c 1382 if (framew&1) {
Pokitto 63:7d1c08cdde5c 1383 /**last pixel is odd pixel due to clipping & odd width*/
Pokitto 63:7d1c08cdde5c 1384 uint8_t sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 1385 if ((sourcepixel&0x0F) != invisiblecolor) {
Pokitto 63:7d1c08cdde5c 1386 sourcepixel <<=4;
Pokitto 63:7d1c08cdde5c 1387 uint8_t targetpixel = *scrptr;// & 0x0F;
Pokitto 63:7d1c08cdde5c 1388 targetpixel |= sourcepixel;
Pokitto 63:7d1c08cdde5c 1389 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1390 }
Pokitto 63:7d1c08cdde5c 1391 //scrptr++;
Pokitto 63:7d1c08cdde5c 1392 }
Pokitto 63:7d1c08cdde5c 1393 bitmap++;
Pokitto 63:7d1c08cdde5c 1394 scrptr++;
Pokitto 63:7d1c08cdde5c 1395 }
Pokitto 63:7d1c08cdde5c 1396 bitmap += xjump; // needed if x<0 clipping occurs
Pokitto 63:7d1c08cdde5c 1397 } else { /** ODD pixel starting line **/
Pokitto 63:7d1c08cdde5c 1398 for (scrx = x; scrx < framew+x-xclip; scrx+=2) {
Pokitto 63:7d1c08cdde5c 1399 uint8_t sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 1400 uint8_t targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1401 // store higher nibble of source pixel in lower nibble of target
Pokitto 63:7d1c08cdde5c 1402 if((sourcepixel>>4)!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel >> 4 );
Pokitto 63:7d1c08cdde5c 1403 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1404 scrptr++;
Pokitto 63:7d1c08cdde5c 1405 targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1406 // store lower nibble of source pixel in higher nibble of target
Pokitto 63:7d1c08cdde5c 1407 if((sourcepixel&0x0F)!=invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel << 4);
Pokitto 63:7d1c08cdde5c 1408 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1409 bitmap++;
Pokitto 63:7d1c08cdde5c 1410 }
Pokitto 63:7d1c08cdde5c 1411 bitmap+=xjump;
Pokitto 63:7d1c08cdde5c 1412 }
Pokitto 63:7d1c08cdde5c 1413 // increment the y jump in the scrptr
Pokitto 63:7d1c08cdde5c 1414 scrptr = scrptr + ((width - framew)>>1)+scrxjump;
Pokitto 63:7d1c08cdde5c 1415 }
Pokitto 63:7d1c08cdde5c 1416 }
Pokitto 63:7d1c08cdde5c 1417
Pokitto 63:7d1c08cdde5c 1418
Pokitto 63:7d1c08cdde5c 1419 void Display::drawBitmap(int16_t x, int16_t y, const uint8_t* bitmap)
Pokitto 63:7d1c08cdde5c 1420 {
Pokitto 63:7d1c08cdde5c 1421 int16_t w = *bitmap;
Pokitto 63:7d1c08cdde5c 1422 int16_t h = *(bitmap + 1);
Pokitto 63:7d1c08cdde5c 1423 bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
Pokitto 63:7d1c08cdde5c 1424 drawBitmapData(x, y, w, h, bitmap);
Pokitto 63:7d1c08cdde5c 1425 }
Pokitto 63:7d1c08cdde5c 1426
Pokitto 63:7d1c08cdde5c 1427 void Display::drawBitmapData(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t* bitmap) {
Pokitto 63:7d1c08cdde5c 1428 /** visibility check */
Pokitto 63:7d1c08cdde5c 1429 if (y<-h || y>height) return; //invisible
Pokitto 63:7d1c08cdde5c 1430 if (x<-w || x>width) return; //invisible
Pokitto 63:7d1c08cdde5c 1431 /** 1 bpp mode */
Pokitto 63:7d1c08cdde5c 1432 if (m_colordepth<2) {
Pokitto 63:7d1c08cdde5c 1433 int16_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 63:7d1c08cdde5c 1434 for (i = 0; i < w; i++) {
Pokitto 63:7d1c08cdde5c 1435 byteNum = i / 8;
Pokitto 63:7d1c08cdde5c 1436 bitNum = i % 8;
Pokitto 63:7d1c08cdde5c 1437 for (j = 0; j < h; j++) {
Pokitto 63:7d1c08cdde5c 1438 uint8_t source = *(bitmap + j * byteWidth + byteNum);
Pokitto 63:7d1c08cdde5c 1439 if (source & (0x80 >> bitNum)) {
Pokitto 63:7d1c08cdde5c 1440 drawPixel(x + i, y + j);
Pokitto 63:7d1c08cdde5c 1441 }
Pokitto 63:7d1c08cdde5c 1442 }
Pokitto 63:7d1c08cdde5c 1443 }
Pokitto 63:7d1c08cdde5c 1444
Pokitto 63:7d1c08cdde5c 1445 return;
Pokitto 63:7d1c08cdde5c 1446 }
Pokitto 63:7d1c08cdde5c 1447 /** 2 bpp mode */
Pokitto 63:7d1c08cdde5c 1448 else if (m_colordepth==2) {
Pokitto 63:7d1c08cdde5c 1449 if(clipH > 0) {
Pokitto 63:7d1c08cdde5c 1450
Pokitto 63:7d1c08cdde5c 1451 // Clip
Pokitto 63:7d1c08cdde5c 1452 int16_t x1 = max(x, clipX);
Pokitto 63:7d1c08cdde5c 1453 int16_t x2 = min(x + w, clipX + clipW);
Pokitto 63:7d1c08cdde5c 1454 int16_t bmupdateX = x1 - x;
Pokitto 63:7d1c08cdde5c 1455 int16_t bmupdateX2 = x2 - x;
Pokitto 63:7d1c08cdde5c 1456 int16_t y1 = max(y, clipY);
Pokitto 63:7d1c08cdde5c 1457 int16_t y2 = min(y + h, clipY + clipH);
Pokitto 63:7d1c08cdde5c 1458 int16_t bmupdateY = y1 - y;
Pokitto 63:7d1c08cdde5c 1459 int16_t bmupdateY2 = y2 - y;
Pokitto 63:7d1c08cdde5c 1460
Pokitto 63:7d1c08cdde5c 1461 int16_t i, j, byteNum, bitNum, byteWidth = w >> 2;
Pokitto 63:7d1c08cdde5c 1462 for (i = bmupdateX; i < bmupdateX2; i++) {
Pokitto 63:7d1c08cdde5c 1463 byteNum = i / 4;
Pokitto 63:7d1c08cdde5c 1464 bitNum = (i % 4)<<1;
Pokitto 63:7d1c08cdde5c 1465 for (j = bmupdateY; j < bmupdateY2; j++) {
Pokitto 63:7d1c08cdde5c 1466 uint8_t source = *(bitmap + (j * byteWidth) + byteNum);
Pokitto 63:7d1c08cdde5c 1467 uint8_t output = (source & (0xC0 >> bitNum));
Pokitto 63:7d1c08cdde5c 1468 output >>= (6-bitNum);
Pokitto 63:7d1c08cdde5c 1469 if (output != invisiblecolor) {
Pokitto 63:7d1c08cdde5c 1470 setColor(output);
Pokitto 63:7d1c08cdde5c 1471 drawPixel(x + i, y + j);
Pokitto 63:7d1c08cdde5c 1472 }
Pokitto 63:7d1c08cdde5c 1473 }
Pokitto 63:7d1c08cdde5c 1474 }
Pokitto 63:7d1c08cdde5c 1475 }
Pokitto 63:7d1c08cdde5c 1476 else {
Pokitto 63:7d1c08cdde5c 1477 int16_t i, j, byteNum, bitNum, byteWidth = w >> 2;
Pokitto 63:7d1c08cdde5c 1478 for (i = 0; i < w; i++) {
Pokitto 63:7d1c08cdde5c 1479 byteNum = i / 4;
Pokitto 63:7d1c08cdde5c 1480 bitNum = (i % 4)<<1;
Pokitto 63:7d1c08cdde5c 1481 for (j = 0; j < h; j++) {
Pokitto 63:7d1c08cdde5c 1482 uint8_t source = *(bitmap + (j * byteWidth) + byteNum);
Pokitto 63:7d1c08cdde5c 1483 uint8_t output = (source & (0xC0 >> bitNum));
Pokitto 63:7d1c08cdde5c 1484 output >>= (6-bitNum);
Pokitto 63:7d1c08cdde5c 1485 if (output != invisiblecolor) {
Pokitto 63:7d1c08cdde5c 1486 setColor(output);
Pokitto 63:7d1c08cdde5c 1487 drawPixel(x + i, y + j);
Pokitto 63:7d1c08cdde5c 1488 }
Pokitto 63:7d1c08cdde5c 1489 }
Pokitto 63:7d1c08cdde5c 1490 }
Pokitto 63:7d1c08cdde5c 1491 }
Pokitto 63:7d1c08cdde5c 1492 return;
Pokitto 63:7d1c08cdde5c 1493 }
Pokitto 63:7d1c08cdde5c 1494
Pokitto 63:7d1c08cdde5c 1495 /** 3 bpp mode */
Pokitto 63:7d1c08cdde5c 1496 else if (m_colordepth==3) {
Pokitto 63:7d1c08cdde5c 1497 int16_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 63:7d1c08cdde5c 1498 int16_t bitFrame = w * h / 8;
Pokitto 63:7d1c08cdde5c 1499 for (i = 0; i < w; i++) {
Pokitto 63:7d1c08cdde5c 1500 byteNum = i / 8;
Pokitto 63:7d1c08cdde5c 1501 bitNum = i % 8;
Pokitto 63:7d1c08cdde5c 1502
Pokitto 63:7d1c08cdde5c 1503 uint8_t bitcount=0;
Pokitto 63:7d1c08cdde5c 1504 for (j = 0; j <= h/8; j++) {
Pokitto 63:7d1c08cdde5c 1505 uint8_t r_val = *(bitmap + j * byteWidth + byteNum);
Pokitto 63:7d1c08cdde5c 1506 uint8_t g_val = *(bitmap + bitFrame + j * byteWidth + byteNum);
Pokitto 63:7d1c08cdde5c 1507 uint8_t b_val = *(bitmap + (bitFrame<<1) + j * byteWidth + byteNum);
Pokitto 63:7d1c08cdde5c 1508 for (bitcount=0; bitcount<8; bitcount++) {
Pokitto 63:7d1c08cdde5c 1509 uint8_t col = (r_val&0x1) | ((g_val&0x1)<<1) | ((b_val&0x1)<<2);
Pokitto 63:7d1c08cdde5c 1510 r_val >>= 1; g_val >>= 1; b_val >>= 1;
Pokitto 63:7d1c08cdde5c 1511 drawPixel(x + i, y + j+bitcount,col);
Pokitto 63:7d1c08cdde5c 1512 }
Pokitto 63:7d1c08cdde5c 1513 }
Pokitto 63:7d1c08cdde5c 1514 }
Pokitto 63:7d1c08cdde5c 1515
Pokitto 63:7d1c08cdde5c 1516 return;
Pokitto 63:7d1c08cdde5c 1517 }
Pokitto 63:7d1c08cdde5c 1518
Pokitto 63:7d1c08cdde5c 1519
Pokitto 63:7d1c08cdde5c 1520 /** 4bpp fast version */
Pokitto 63:7d1c08cdde5c 1521 else if (m_colordepth==4) {
Pokitto 63:7d1c08cdde5c 1522
Pokitto 63:7d1c08cdde5c 1523 /** 4bpp fast version */
Pokitto 63:7d1c08cdde5c 1524 int16_t scrx,scry,xjump,scrxjump;
Pokitto 63:7d1c08cdde5c 1525 int16_t xclip;
Pokitto 63:7d1c08cdde5c 1526 xclip=xjump=scrxjump=0;
Pokitto 63:7d1c08cdde5c 1527 /** y clipping */
Pokitto 63:7d1c08cdde5c 1528 if (y<0) { h+=y; bitmap -= y*(w>>1); y=0;}
Pokitto 63:7d1c08cdde5c 1529 else if (y+h>height) { h -=(y-height);}
Pokitto 63:7d1c08cdde5c 1530 /** x clipping */
Pokitto 63:7d1c08cdde5c 1531 if (x<0) { xclip=(x&1)<<1; w+=x; xjump = ((-x)>>1); bitmap += xjump; x=0;}
Pokitto 63:7d1c08cdde5c 1532 else if (x+w>width) {
Pokitto 63:7d1c08cdde5c 1533 xclip = (x&1)<<1;
Pokitto 63:7d1c08cdde5c 1534 scrxjump = x&1;
Pokitto 63:7d1c08cdde5c 1535 xjump=((x+w-width)>>1)+scrxjump;
Pokitto 63:7d1c08cdde5c 1536 w = width-x;}
Pokitto 63:7d1c08cdde5c 1537
Pokitto 63:7d1c08cdde5c 1538 uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
Pokitto 63:7d1c08cdde5c 1539 /** ONLY 4-bit mode for time being **/
Pokitto 63:7d1c08cdde5c 1540 for (scry = y; scry < y+h; scry+=1) {
Pokitto 63:7d1c08cdde5c 1541 if (scry>=height) return;
Pokitto 63:7d1c08cdde5c 1542 if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
Pokitto 63:7d1c08cdde5c 1543 for (scrx = x; scrx < w+x-xclip; scrx+=2) {
Pokitto 63:7d1c08cdde5c 1544 uint8_t sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 1545 if (xclip) {
Pokitto 63:7d1c08cdde5c 1546 sourcepixel <<=4;
Pokitto 63:7d1c08cdde5c 1547 sourcepixel |= ((*(bitmap+1))>>4);
Pokitto 63:7d1c08cdde5c 1548 }
Pokitto 63:7d1c08cdde5c 1549 uint8_t targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1550 if ((sourcepixel>>4) != invisiblecolor ) targetpixel = (targetpixel&0x0F) | (sourcepixel & 0xF0);
Pokitto 63:7d1c08cdde5c 1551 if ((sourcepixel&0x0F) != invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel & 0x0F);
Pokitto 63:7d1c08cdde5c 1552 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1553 bitmap++;
Pokitto 63:7d1c08cdde5c 1554 scrptr++;
Pokitto 63:7d1c08cdde5c 1555 }
Pokitto 63:7d1c08cdde5c 1556 if (xclip){
Pokitto 63:7d1c08cdde5c 1557 if (w&1) {
Pokitto 63:7d1c08cdde5c 1558 /**last pixel is odd pixel due to clipping & odd width*/
Pokitto 63:7d1c08cdde5c 1559 uint8_t sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 1560 if ((sourcepixel&0x0F) != invisiblecolor) {
Pokitto 63:7d1c08cdde5c 1561 sourcepixel <<=4;
Pokitto 63:7d1c08cdde5c 1562 volatile uint8_t targetpixel = *scrptr;// & 0x0F;
Pokitto 63:7d1c08cdde5c 1563 targetpixel &= 0xF; //clear upper nibble
Pokitto 63:7d1c08cdde5c 1564 targetpixel |= sourcepixel; //now OR it
Pokitto 63:7d1c08cdde5c 1565 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1566 }
Pokitto 63:7d1c08cdde5c 1567 //scrptr++;
Pokitto 63:7d1c08cdde5c 1568 }
Pokitto 63:7d1c08cdde5c 1569 bitmap++;
Pokitto 63:7d1c08cdde5c 1570 scrptr++;
Pokitto 63:7d1c08cdde5c 1571 }
Pokitto 63:7d1c08cdde5c 1572 bitmap += xjump; // needed if x<0 clipping occurs
Pokitto 63:7d1c08cdde5c 1573 } else { /** ODD pixel starting line **/
Pokitto 63:7d1c08cdde5c 1574 uint8_t sourcepixel;
Pokitto 63:7d1c08cdde5c 1575 uint8_t targetpixel;
Pokitto 63:7d1c08cdde5c 1576 for (scrx = x; scrx < w+x-xclip; scrx+=2) {
Pokitto 63:7d1c08cdde5c 1577 sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 1578 targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1579 // store higher nibble of source pixel in lower nibble of target
Pokitto 63:7d1c08cdde5c 1580 if((sourcepixel>>4)!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel >> 4 );
Pokitto 63:7d1c08cdde5c 1581 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1582 scrptr++;
Pokitto 63:7d1c08cdde5c 1583 targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1584 // store lower nibble of source pixel in higher nibble of target
Pokitto 63:7d1c08cdde5c 1585 if((sourcepixel&0x0F)!=invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel << 4);
Pokitto 63:7d1c08cdde5c 1586 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1587 bitmap++;
Pokitto 63:7d1c08cdde5c 1588 }
Pokitto 63:7d1c08cdde5c 1589 if (xclip) {
Pokitto 63:7d1c08cdde5c 1590 // last line, store higher nibble of last source pixel in lower nibble of last address
Pokitto 63:7d1c08cdde5c 1591 sourcepixel = *bitmap >> 4;
Pokitto 63:7d1c08cdde5c 1592 if(sourcepixel!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | sourcepixel;
Pokitto 63:7d1c08cdde5c 1593 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1594 }
Pokitto 63:7d1c08cdde5c 1595 bitmap+=xjump;
Pokitto 63:7d1c08cdde5c 1596 }
Pokitto 63:7d1c08cdde5c 1597 // increment the y jump in the scrptr
Pokitto 63:7d1c08cdde5c 1598 scrptr = scrptr + ((width - w)>>1)+scrxjump;
Pokitto 63:7d1c08cdde5c 1599 }
Pokitto 63:7d1c08cdde5c 1600
Pokitto 63:7d1c08cdde5c 1601 return;
Pokitto 63:7d1c08cdde5c 1602 }
Pokitto 63:7d1c08cdde5c 1603
Pokitto 63:7d1c08cdde5c 1604 /** 4bpp fast version */
Pokitto 63:7d1c08cdde5c 1605
Pokitto 63:7d1c08cdde5c 1606 if (m_colordepth==8) {
Pokitto 63:7d1c08cdde5c 1607 int16_t scrx,scry,xclip,xjump,scrxjump;
Pokitto 63:7d1c08cdde5c 1608 xclip=xjump=scrxjump=0;
Pokitto 63:7d1c08cdde5c 1609 /** y clipping */
Pokitto 63:7d1c08cdde5c 1610 if (y<0) { h+=y; bitmap -= y*w; y=0;}
Pokitto 63:7d1c08cdde5c 1611 else if (y+h>height) { h -=(y-height);}
Pokitto 63:7d1c08cdde5c 1612 /** x clipping */
Pokitto 63:7d1c08cdde5c 1613 if (x<0) { xclip=x; w+=x; xjump = (-x); bitmap += xjump; x=0;}
Pokitto 63:7d1c08cdde5c 1614 else if (x+w>width) {
Pokitto 63:7d1c08cdde5c 1615 xclip = x;
Pokitto 63:7d1c08cdde5c 1616 scrxjump = x;
Pokitto 63:7d1c08cdde5c 1617 xjump=(x+w-width)+scrxjump;
Pokitto 63:7d1c08cdde5c 1618 w = width-x;}
Pokitto 63:7d1c08cdde5c 1619
Pokitto 63:7d1c08cdde5c 1620 uint8_t* scrptr = m_scrbuf + (y*width + x);
Pokitto 63:7d1c08cdde5c 1621 for (scry = y; scry < y+h; scry+=1) {
Pokitto 63:7d1c08cdde5c 1622 if (scry>=height) return;
Pokitto 63:7d1c08cdde5c 1623 for (scrx = x; scrx < w+x; scrx++) {
Pokitto 63:7d1c08cdde5c 1624 uint8_t sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 1625 uint8_t targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1626 if (sourcepixel != invisiblecolor ) targetpixel = sourcepixel;
Pokitto 63:7d1c08cdde5c 1627 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1628 bitmap++;
Pokitto 63:7d1c08cdde5c 1629 scrptr++;
Pokitto 63:7d1c08cdde5c 1630 }
Pokitto 63:7d1c08cdde5c 1631 bitmap += xjump; // needed if x<0 clipping occurs
Pokitto 63:7d1c08cdde5c 1632 scrptr = scrptr + (width - w)+scrxjump;
Pokitto 63:7d1c08cdde5c 1633 }
Pokitto 63:7d1c08cdde5c 1634 return;
Pokitto 63:7d1c08cdde5c 1635 }
Pokitto 63:7d1c08cdde5c 1636
Pokitto 63:7d1c08cdde5c 1637
Pokitto 63:7d1c08cdde5c 1638 }
Pokitto 63:7d1c08cdde5c 1639
Pokitto 63:7d1c08cdde5c 1640 void Display::drawRleBitmap(int16_t x, int16_t y, const uint8_t* rlebitmap)
Pokitto 63:7d1c08cdde5c 1641 {
Pokitto 63:7d1c08cdde5c 1642 // ONLY can copy 4-bit bitmap to 4-bit screen mode for time being
Pokitto 63:7d1c08cdde5c 1643 #if (POK_SCREENMODE != MODE_FAST_16COLOR)
Pokitto 63:7d1c08cdde5c 1644 return;
Pokitto 63:7d1c08cdde5c 1645 #endif
Pokitto 63:7d1c08cdde5c 1646
Pokitto 63:7d1c08cdde5c 1647 int16_t w = *rlebitmap;
Pokitto 63:7d1c08cdde5c 1648 int16_t h = *(rlebitmap + 1);
Pokitto 63:7d1c08cdde5c 1649 rlebitmap = rlebitmap + 2; //add an offset to the pointer to start after the width and height
Pokitto 63:7d1c08cdde5c 1650
Pokitto 63:7d1c08cdde5c 1651 // visibility check
Pokitto 63:7d1c08cdde5c 1652 if (y<-h || y>height) return; //invisible
Pokitto 63:7d1c08cdde5c 1653 if (x<-w || x>width) return; //invisible
Pokitto 63:7d1c08cdde5c 1654
Pokitto 63:7d1c08cdde5c 1655 // Clipping is not supported
Pokitto 63:7d1c08cdde5c 1656 if ((x < 0) || (x+w > width) || (y < 0) || (y+h > height)) return;
Pokitto 63:7d1c08cdde5c 1657
Pokitto 63:7d1c08cdde5c 1658 // Currently only support RLE bitmaps in 16 color mode.
Pokitto 63:7d1c08cdde5c 1659 if (m_colordepth != 4) //
Pokitto 63:7d1c08cdde5c 1660 return;
Pokitto 63:7d1c08cdde5c 1661
Pokitto 63:7d1c08cdde5c 1662 // Go through each line.
Pokitto 63:7d1c08cdde5c 1663 uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
Pokitto 63:7d1c08cdde5c 1664 bool is_endofbitmap = false;
Pokitto 63:7d1c08cdde5c 1665 for (int16_t scry = y; scry < y+h && !is_endofbitmap;) {
Pokitto 63:7d1c08cdde5c 1666
Pokitto 63:7d1c08cdde5c 1667 // Process one line. Go through each pixel run and escape command in RLE data.
Pokitto 63:7d1c08cdde5c 1668 for (int16_t scrx = x;;) {
Pokitto 63:7d1c08cdde5c 1669 uint8_t rle_count = *rlebitmap++;
Pokitto 63:7d1c08cdde5c 1670
Pokitto 63:7d1c08cdde5c 1671 if (rle_count == 0) {
Pokitto 63:7d1c08cdde5c 1672
Pokitto 63:7d1c08cdde5c 1673 /* Escape or absolute mode */
Pokitto 63:7d1c08cdde5c 1674
Pokitto 63:7d1c08cdde5c 1675 uint8_t rle_escape_or_runsize = *rlebitmap++;
Pokitto 63:7d1c08cdde5c 1676 if ( rle_escape_or_runsize == RLE_ESC_EOL) {
Pokitto 63:7d1c08cdde5c 1677 // End of line.
Pokitto 63:7d1c08cdde5c 1678 break;
Pokitto 63:7d1c08cdde5c 1679 }
Pokitto 63:7d1c08cdde5c 1680 else if ( rle_escape_or_runsize == RLE_ESC_EOB) {
Pokitto 63:7d1c08cdde5c 1681 // End of bitmap.
Pokitto 63:7d1c08cdde5c 1682 is_endofbitmap = true;
Pokitto 63:7d1c08cdde5c 1683 break;
Pokitto 63:7d1c08cdde5c 1684 }
Pokitto 63:7d1c08cdde5c 1685 else if ( rle_escape_or_runsize == RLE_ESC_OFFSET) {
Pokitto 63:7d1c08cdde5c 1686 // Move position in target.
Pokitto 63:7d1c08cdde5c 1687 // TODO: not tested yet.
Pokitto 63:7d1c08cdde5c 1688 uint8_t xoffset = *rlebitmap++;
Pokitto 63:7d1c08cdde5c 1689 uint8_t yoffset = *rlebitmap++;
Pokitto 63:7d1c08cdde5c 1690 scrptr += (xoffset>1);
Pokitto 63:7d1c08cdde5c 1691 scrx += xoffset;
Pokitto 63:7d1c08cdde5c 1692 scrptr += yoffset*width;
Pokitto 63:7d1c08cdde5c 1693 scry += yoffset;
Pokitto 63:7d1c08cdde5c 1694 }
Pokitto 63:7d1c08cdde5c 1695 else {
Pokitto 63:7d1c08cdde5c 1696
Pokitto 63:7d1c08cdde5c 1697 /* Absolute mode. Copy pixels from the source bitmap to the target screen. */
Pokitto 63:7d1c08cdde5c 1698
Pokitto 63:7d1c08cdde5c 1699 int16_t runsize = rle_escape_or_runsize;
Pokitto 63:7d1c08cdde5c 1700 uint8_t targetpixel = *scrptr; // initial value
Pokitto 63:7d1c08cdde5c 1701 uint8_t sourcepixel = *rlebitmap; // initial value
Pokitto 63:7d1c08cdde5c 1702 for( int16_t runx = 0; runx < runsize; ) {
Pokitto 63:7d1c08cdde5c 1703 if (scrx&0x1) { // screen pixel is in the low nibble
Pokitto 63:7d1c08cdde5c 1704 if (runx&0x1) { // bitmap pixel is in the low nibble
Pokitto 63:7d1c08cdde5c 1705 if ((sourcepixel&0x0F) != invisiblecolor)
Pokitto 63:7d1c08cdde5c 1706 targetpixel = (targetpixel&0xF0) | (sourcepixel&0x0F); // Copy low to low nibble.
Pokitto 63:7d1c08cdde5c 1707 rlebitmap++;
Pokitto 63:7d1c08cdde5c 1708 }
Pokitto 63:7d1c08cdde5c 1709 else // bitmap pixel is in the high nibble
Pokitto 63:7d1c08cdde5c 1710 if ((sourcepixel>>4) != invisiblecolor)
Pokitto 63:7d1c08cdde5c 1711 targetpixel = (targetpixel&0xF0) | (sourcepixel>>4); // Copy high to low nibble.
Pokitto 63:7d1c08cdde5c 1712
Pokitto 63:7d1c08cdde5c 1713 // Copy the byte to the target.
Pokitto 63:7d1c08cdde5c 1714 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1715 scrptr++;
Pokitto 63:7d1c08cdde5c 1716 }
Pokitto 63:7d1c08cdde5c 1717 else { // screen pixel is in the high nibble
Pokitto 63:7d1c08cdde5c 1718 targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1719 sourcepixel = *rlebitmap;
Pokitto 63:7d1c08cdde5c 1720 if (runx&0x1) { // bitmap pixel is sourcepixel = *rlebitmapin the low nibble
Pokitto 63:7d1c08cdde5c 1721 if ((sourcepixel&0x0F) != invisiblecolor )
Pokitto 63:7d1c08cdde5c 1722 targetpixel = (targetpixel&0x0F) | ((sourcepixel<<4)&0xF0); // Copy low to high nibble.
Pokitto 63:7d1c08cdde5c 1723 rlebitmap++; // read the new source byte
Pokitto 63:7d1c08cdde5c 1724 }
Pokitto 63:7d1c08cdde5c 1725 else // bitmap pixel is in the high nibble
Pokitto 63:7d1c08cdde5c 1726 if ((sourcepixel>>4) != invisiblecolor )
Pokitto 63:7d1c08cdde5c 1727 targetpixel = (targetpixel&0x0F) | (sourcepixel&0xF0); // Copy high to high nibble.
Pokitto 63:7d1c08cdde5c 1728 }
Pokitto 63:7d1c08cdde5c 1729 runx++;
Pokitto 63:7d1c08cdde5c 1730 scrx++;
Pokitto 63:7d1c08cdde5c 1731 } // end for
Pokitto 63:7d1c08cdde5c 1732
Pokitto 63:7d1c08cdde5c 1733 // If this is odd target index, copy the byte to the target.
Pokitto 63:7d1c08cdde5c 1734 if (scrx&0x1) {
Pokitto 63:7d1c08cdde5c 1735 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1736 scrptr++;
Pokitto 63:7d1c08cdde5c 1737 }
Pokitto 63:7d1c08cdde5c 1738
Pokitto 63:7d1c08cdde5c 1739 // In absolute mode the source size is always padded to the word boundary.
Pokitto 63:7d1c08cdde5c 1740 if (runsize%4) {
Pokitto 63:7d1c08cdde5c 1741 int16_t padpixcount = 4 - (runsize%4);
Pokitto 63:7d1c08cdde5c 1742 rlebitmap += padpixcount>>1; // skip n padding bytes
Pokitto 63:7d1c08cdde5c 1743 }
Pokitto 63:7d1c08cdde5c 1744 }
Pokitto 63:7d1c08cdde5c 1745 }
Pokitto 63:7d1c08cdde5c 1746 else {
Pokitto 63:7d1c08cdde5c 1747
Pokitto 63:7d1c08cdde5c 1748 /* Encoded mode. Duplicate one pixel pair to the all required pixels on the target screen */
Pokitto 63:7d1c08cdde5c 1749
Pokitto 63:7d1c08cdde5c 1750 int16_t runsize = rle_count;
Pokitto 63:7d1c08cdde5c 1751 uint8_t clonepixelpair = *rlebitmap++;
Pokitto 63:7d1c08cdde5c 1752 uint8_t targetpixel = *scrptr; // initial value
Pokitto 63:7d1c08cdde5c 1753 for( int16_t runx = 0; runx < runsize; ) {
Pokitto 63:7d1c08cdde5c 1754 if (scrx&0x1) { // screen pixel is in the low nibble
Pokitto 63:7d1c08cdde5c 1755 if (runx&0x1) { // bitmap pixel is in the low nibble
Pokitto 63:7d1c08cdde5c 1756 if ((clonepixelpair&0x0F) != invisiblecolor)
Pokitto 63:7d1c08cdde5c 1757 targetpixel = (targetpixel&0xF0) | (clonepixelpair&0x0F); // Copy low to low nibble.
Pokitto 63:7d1c08cdde5c 1758 }
Pokitto 63:7d1c08cdde5c 1759 else // bitmap pixel is in the high nibble
Pokitto 63:7d1c08cdde5c 1760 if ((clonepixelpair>>4) != invisiblecolor)
Pokitto 63:7d1c08cdde5c 1761 targetpixel = (targetpixel&0xF0) | (clonepixelpair>>4); // Copy high to low nibble.
Pokitto 63:7d1c08cdde5c 1762
Pokitto 63:7d1c08cdde5c 1763 // Copy the byte to the target.
Pokitto 63:7d1c08cdde5c 1764 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1765 scrptr++;
Pokitto 63:7d1c08cdde5c 1766 }
Pokitto 63:7d1c08cdde5c 1767 else { // screen pixel is in the high nibble
Pokitto 63:7d1c08cdde5c 1768 targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1769 if (runx&0x1) {// bitmap pixel is in the low nibble
Pokitto 63:7d1c08cdde5c 1770 if ((clonepixelpair&0x0F) != invisiblecolor )
Pokitto 63:7d1c08cdde5c 1771 targetpixel = (targetpixel&0x0F) | ((clonepixelpair<<4)&0xF0); // Copy low to high nibble.
Pokitto 63:7d1c08cdde5c 1772 }
Pokitto 63:7d1c08cdde5c 1773 else // bitmap pixel is in the high nibble
Pokitto 63:7d1c08cdde5c 1774 if ((clonepixelpair>>4) != invisiblecolor )
Pokitto 63:7d1c08cdde5c 1775 targetpixel = (targetpixel&0x0F) | (clonepixelpair&0xF0); // Copy high to high nibble.
Pokitto 63:7d1c08cdde5c 1776 }
Pokitto 63:7d1c08cdde5c 1777 runx++;
Pokitto 63:7d1c08cdde5c 1778 scrx++;
Pokitto 63:7d1c08cdde5c 1779
Pokitto 63:7d1c08cdde5c 1780 } // end for
Pokitto 63:7d1c08cdde5c 1781
Pokitto 63:7d1c08cdde5c 1782 // If this is odd target index, copy the byte to the target.
Pokitto 63:7d1c08cdde5c 1783 if (scrx&0x1) {
Pokitto 63:7d1c08cdde5c 1784 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1785 scrptr++;
Pokitto 63:7d1c08cdde5c 1786 }
Pokitto 63:7d1c08cdde5c 1787 } // end if
Pokitto 63:7d1c08cdde5c 1788 } // end while
Pokitto 63:7d1c08cdde5c 1789
Pokitto 63:7d1c08cdde5c 1790 // Increment the target screen pointer and index.
Pokitto 63:7d1c08cdde5c 1791 scrptr = scrptr + ((width - w)>>1);
Pokitto 63:7d1c08cdde5c 1792 scry++;
Pokitto 63:7d1c08cdde5c 1793 } // end for scry
Pokitto 63:7d1c08cdde5c 1794 }
Pokitto 63:7d1c08cdde5c 1795
Pokitto 63:7d1c08cdde5c 1796 void Display::drawBitmapXFlipped(int16_t x, int16_t y, const uint8_t* bitmap)
Pokitto 63:7d1c08cdde5c 1797 {
Pokitto 63:7d1c08cdde5c 1798 int16_t w = *bitmap;
Pokitto 63:7d1c08cdde5c 1799 int16_t h = *(bitmap + 1);
Pokitto 63:7d1c08cdde5c 1800 bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
Pokitto 63:7d1c08cdde5c 1801 /** visibility check */
Pokitto 63:7d1c08cdde5c 1802 if (y<-h || y>height) return; //invisible
Pokitto 63:7d1c08cdde5c 1803 if (x<-w || x>width) return; //invisible
Pokitto 63:7d1c08cdde5c 1804 /** 1 bpp mode */
Pokitto 63:7d1c08cdde5c 1805 if (m_colordepth<2) {
Pokitto 63:7d1c08cdde5c 1806 int16_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 63:7d1c08cdde5c 1807 for (i = 0; i < w; i++) {
Pokitto 63:7d1c08cdde5c 1808 byteNum = i / 8;
Pokitto 63:7d1c08cdde5c 1809 bitNum = i % 8;
Pokitto 63:7d1c08cdde5c 1810 for (j = 0; j < h; j++) {
Pokitto 63:7d1c08cdde5c 1811 uint8_t source = *(bitmap + j * byteWidth + byteNum);
Pokitto 63:7d1c08cdde5c 1812 if (source & (0x80 >> bitNum)) {
Pokitto 63:7d1c08cdde5c 1813 drawPixel(x + w - i, y + j);
Pokitto 63:7d1c08cdde5c 1814 }
Pokitto 63:7d1c08cdde5c 1815 }
Pokitto 63:7d1c08cdde5c 1816 }
Pokitto 63:7d1c08cdde5c 1817
Pokitto 63:7d1c08cdde5c 1818 return;
Pokitto 63:7d1c08cdde5c 1819 }
Pokitto 63:7d1c08cdde5c 1820 /** 2 bpp mode */
Pokitto 63:7d1c08cdde5c 1821 if (m_colordepth<4) {
Pokitto 63:7d1c08cdde5c 1822 int16_t i, j, byteNum, bitNum, byteWidth = w >> 2;
Pokitto 63:7d1c08cdde5c 1823 for (i = 0; i < w; i++) {
Pokitto 63:7d1c08cdde5c 1824 byteNum = i / 4;
Pokitto 63:7d1c08cdde5c 1825 bitNum = (i % 4)<<1;
Pokitto 63:7d1c08cdde5c 1826 for (j = 0; j < h; j++) {
Pokitto 63:7d1c08cdde5c 1827 uint8_t source = *(bitmap + j * byteWidth + byteNum);
Pokitto 63:7d1c08cdde5c 1828 uint8_t output = (source & (0xC0 >> bitNum));
Pokitto 63:7d1c08cdde5c 1829 output >>= (6-bitNum);
Pokitto 63:7d1c08cdde5c 1830 if (output != invisiblecolor) {
Pokitto 63:7d1c08cdde5c 1831 setColor(output);
Pokitto 63:7d1c08cdde5c 1832 drawPixel(x + i, y + j);
Pokitto 63:7d1c08cdde5c 1833 }
Pokitto 63:7d1c08cdde5c 1834 }
Pokitto 63:7d1c08cdde5c 1835 }
Pokitto 63:7d1c08cdde5c 1836
Pokitto 63:7d1c08cdde5c 1837 return;
Pokitto 63:7d1c08cdde5c 1838 }
Pokitto 63:7d1c08cdde5c 1839 /** 4bpp fast version */
Pokitto 63:7d1c08cdde5c 1840 int16_t scrx,scry,xclip,xjump,scrxjump;
Pokitto 63:7d1c08cdde5c 1841 xclip=xjump=scrxjump=0;
Pokitto 63:7d1c08cdde5c 1842 /** y clipping */
Pokitto 63:7d1c08cdde5c 1843 if (y<0) { h+=y; bitmap -= y*(w>>1); y=0;}
Pokitto 63:7d1c08cdde5c 1844 else if (y+h>height) { h -=(y-height);}
Pokitto 63:7d1c08cdde5c 1845 /** x clipping */
Pokitto 63:7d1c08cdde5c 1846 bitmap += ((w>>1)-1); //inverted!
Pokitto 63:7d1c08cdde5c 1847 if (x<0) {
Pokitto 63:7d1c08cdde5c 1848 xclip=(x&1)<<1;
Pokitto 63:7d1c08cdde5c 1849 w+=x;
Pokitto 63:7d1c08cdde5c 1850 xjump = ((-x)>>1);
Pokitto 63:7d1c08cdde5c 1851 //bitmap += xjump; // do not clip left edge of source, as bitmap is inverted !
Pokitto 63:7d1c08cdde5c 1852 x=0;
Pokitto 63:7d1c08cdde5c 1853 }
Pokitto 63:7d1c08cdde5c 1854 else if (x+w>width) {
Pokitto 63:7d1c08cdde5c 1855 xclip = (x&1)<<1;
Pokitto 63:7d1c08cdde5c 1856 scrxjump = x&1;
Pokitto 63:7d1c08cdde5c 1857 xjump=((x+w-width)>>1)+scrxjump;
Pokitto 63:7d1c08cdde5c 1858 w = width-x;}
Pokitto 63:7d1c08cdde5c 1859
Pokitto 63:7d1c08cdde5c 1860 //uint8_t* scrptr = m_scrbuf + (y*(width>>1) + ((x+width)>>1));
Pokitto 63:7d1c08cdde5c 1861 uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
Pokitto 63:7d1c08cdde5c 1862 /** ONLY 4-bit mode for time being **/
Pokitto 63:7d1c08cdde5c 1863 for (scry = y; scry < y+h; scry+=1) {
Pokitto 63:7d1c08cdde5c 1864 // for (scry = y; scry < y+2; scry+=1) {
Pokitto 63:7d1c08cdde5c 1865 if (scry>=height) return;
Pokitto 63:7d1c08cdde5c 1866 if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
Pokitto 63:7d1c08cdde5c 1867 //for (scrx = w+x-xclip-1; scrx >= x; scrx-=2) {
Pokitto 63:7d1c08cdde5c 1868 for (scrx = x; scrx < w+x-xclip; scrx+=2) {
Pokitto 63:7d1c08cdde5c 1869 uint8_t sourcepixel = *(bitmap);
Pokitto 63:7d1c08cdde5c 1870 if (xclip) {
Pokitto 63:7d1c08cdde5c 1871 sourcepixel <<=4;
Pokitto 63:7d1c08cdde5c 1872 sourcepixel |= ((*(bitmap-1))>>4);//inverted!
Pokitto 63:7d1c08cdde5c 1873 }
Pokitto 63:7d1c08cdde5c 1874 uint8_t targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1875 // NIBBLES ARE INVERTED BECAUSE PICTURE IS FLIPPED !!!
Pokitto 63:7d1c08cdde5c 1876 if ((sourcepixel>>4) != invisiblecolor ) targetpixel = (targetpixel&0xF0) | (sourcepixel>>4);
Pokitto 63:7d1c08cdde5c 1877 if ((sourcepixel&0x0F) != invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel<<4);
Pokitto 63:7d1c08cdde5c 1878 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1879 bitmap--;
Pokitto 63:7d1c08cdde5c 1880 scrptr++;
Pokitto 63:7d1c08cdde5c 1881 }
Pokitto 63:7d1c08cdde5c 1882 bitmap += w; // w*2 >> 1 because inverted and because 2 pixels per byte!!
Pokitto 63:7d1c08cdde5c 1883 if (xclip){
Pokitto 63:7d1c08cdde5c 1884 if (w&1) {
Pokitto 63:7d1c08cdde5c 1885 /**last pixel is odd pixel due to clipping & odd width*/
Pokitto 63:7d1c08cdde5c 1886 uint8_t sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 1887 if ((sourcepixel&0x0F) != invisiblecolor) {
Pokitto 63:7d1c08cdde5c 1888 sourcepixel <<=4;
Pokitto 63:7d1c08cdde5c 1889 uint8_t targetpixel = *scrptr;// & 0x0F;
Pokitto 63:7d1c08cdde5c 1890 targetpixel |= sourcepixel;
Pokitto 63:7d1c08cdde5c 1891 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1892 }
Pokitto 63:7d1c08cdde5c 1893 //scrptr++;
Pokitto 63:7d1c08cdde5c 1894 }
Pokitto 63:7d1c08cdde5c 1895 bitmap++;
Pokitto 63:7d1c08cdde5c 1896 scrptr++;
Pokitto 63:7d1c08cdde5c 1897 }
Pokitto 63:7d1c08cdde5c 1898 bitmap += xjump; // needed if x<0 clipping occurs
Pokitto 63:7d1c08cdde5c 1899 } else { /** ODD pixel starting line **/
Pokitto 63:7d1c08cdde5c 1900 for (scrx = x; scrx < w+x-xclip; scrx+=2 ) {
Pokitto 63:7d1c08cdde5c 1901 uint8_t sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 1902 uint8_t targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1903 // inverted !!! store lower nibble of source pixel in lower nibble of target
Pokitto 63:7d1c08cdde5c 1904 if((sourcepixel&0x0F)!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel & 0x0F );
Pokitto 63:7d1c08cdde5c 1905 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1906 scrptr++;
Pokitto 63:7d1c08cdde5c 1907 targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 1908 // inverted ! store higher nibble of source pixel in higher nibble of target
Pokitto 63:7d1c08cdde5c 1909 if((sourcepixel>>4)!=invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel & 0xF0);
Pokitto 63:7d1c08cdde5c 1910 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 1911 bitmap--;
Pokitto 63:7d1c08cdde5c 1912 }
Pokitto 63:7d1c08cdde5c 1913 bitmap += w; // w*2 >> 1 because inverted and because 2 pixels per byte!!
Pokitto 63:7d1c08cdde5c 1914 bitmap+=xjump;
Pokitto 63:7d1c08cdde5c 1915 }
Pokitto 63:7d1c08cdde5c 1916 // increment the y jump in the scrptr
Pokitto 63:7d1c08cdde5c 1917 scrptr = scrptr + ((width - w)>>1)+scrxjump;
Pokitto 63:7d1c08cdde5c 1918 }
Pokitto 63:7d1c08cdde5c 1919 }
Pokitto 63:7d1c08cdde5c 1920
Pokitto 63:7d1c08cdde5c 1921 void Display::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t rotation, uint8_t flip) {
Pokitto 63:7d1c08cdde5c 1922 #if PROJ_GAMEBUINO == 0
Pokitto 63:7d1c08cdde5c 1923 if (!flip) drawBitmap(x,y,bitmap);
Pokitto 63:7d1c08cdde5c 1924 else drawBitmapXFlipped(x,y,bitmap);
Pokitto 63:7d1c08cdde5c 1925 #else
Pokitto 63:7d1c08cdde5c 1926 if((rotation == NOROT) && (flip == NOFLIP)){
Pokitto 63:7d1c08cdde5c 1927 drawBitmap(x,y,bitmap); //use the faster algorithm
Pokitto 63:7d1c08cdde5c 1928 return;
Pokitto 63:7d1c08cdde5c 1929 }
Pokitto 63:7d1c08cdde5c 1930 uint8_t w = bitmap[0];
Pokitto 63:7d1c08cdde5c 1931 uint8_t h = bitmap[1];
Pokitto 63:7d1c08cdde5c 1932 bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
Pokitto 63:7d1c08cdde5c 1933 int8_t i, j, //coordinates in the raw bitmap
Pokitto 63:7d1c08cdde5c 1934 k, l, //coordinates in the rotated/flipped bitmap
Pokitto 63:7d1c08cdde5c 1935 byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 63:7d1c08cdde5c 1936
Pokitto 63:7d1c08cdde5c 1937 rotation %= 4;
Pokitto 63:7d1c08cdde5c 1938
Pokitto 63:7d1c08cdde5c 1939 for (i = 0; i < w; i++) {
Pokitto 63:7d1c08cdde5c 1940 byteNum = i / 8;
Pokitto 63:7d1c08cdde5c 1941 bitNum = i % 8;
Pokitto 63:7d1c08cdde5c 1942 for (j = 0; j < h; j++) {
Pokitto 63:7d1c08cdde5c 1943 if (bitmap[j * byteWidth + byteNum] & (B10000000 >> bitNum)) {
Pokitto 63:7d1c08cdde5c 1944 switch (rotation) {
Pokitto 63:7d1c08cdde5c 1945 case NOROT: //no rotation
Pokitto 63:7d1c08cdde5c 1946 k = i;
Pokitto 63:7d1c08cdde5c 1947 l = j;
Pokitto 63:7d1c08cdde5c 1948 break;
Pokitto 63:7d1c08cdde5c 1949 case ROTCCW: //90° counter-clockwise
Pokitto 63:7d1c08cdde5c 1950 k = j;
Pokitto 63:7d1c08cdde5c 1951 l = w - i - 1;
Pokitto 63:7d1c08cdde5c 1952 break;
Pokitto 63:7d1c08cdde5c 1953 case ROT180: //180°
Pokitto 63:7d1c08cdde5c 1954 k = w - i - 1;
Pokitto 63:7d1c08cdde5c 1955 l = h - j - 1;
Pokitto 63:7d1c08cdde5c 1956 break;
Pokitto 63:7d1c08cdde5c 1957 case ROTCW: //90° clockwise
Pokitto 63:7d1c08cdde5c 1958 k = h - j - 1;
Pokitto 63:7d1c08cdde5c 1959 l = i;
Pokitto 63:7d1c08cdde5c 1960 break;
Pokitto 63:7d1c08cdde5c 1961 }
Pokitto 63:7d1c08cdde5c 1962 if (flip) {
Pokitto 63:7d1c08cdde5c 1963 flip %= 4;
Pokitto 63:7d1c08cdde5c 1964 if (flip & B00000001) { //horizontal flip
Pokitto 63:7d1c08cdde5c 1965 k = w - k;
Pokitto 63:7d1c08cdde5c 1966 }
Pokitto 63:7d1c08cdde5c 1967 if (flip & B00000010) { //vertical flip
Pokitto 63:7d1c08cdde5c 1968 l = h - l;
Pokitto 63:7d1c08cdde5c 1969 }
Pokitto 63:7d1c08cdde5c 1970 }
Pokitto 63:7d1c08cdde5c 1971 k += x; //place the bitmap on the screen
Pokitto 63:7d1c08cdde5c 1972 l += y;
Pokitto 63:7d1c08cdde5c 1973 drawPixel(k, l);
Pokitto 63:7d1c08cdde5c 1974 }
Pokitto 63:7d1c08cdde5c 1975 }
Pokitto 63:7d1c08cdde5c 1976 }
Pokitto 63:7d1c08cdde5c 1977 #endif //PROJ_GAMEBUINO
Pokitto 63:7d1c08cdde5c 1978
Pokitto 63:7d1c08cdde5c 1979 }
Pokitto 63:7d1c08cdde5c 1980
Pokitto 63:7d1c08cdde5c 1981 uint8_t* Display::getBuffer() {
Pokitto 63:7d1c08cdde5c 1982 return m_scrbuf;
Pokitto 63:7d1c08cdde5c 1983 }
Pokitto 63:7d1c08cdde5c 1984
Pokitto 63:7d1c08cdde5c 1985 uint8_t Display::getBitmapPixel(const uint8_t* bitmap, uint16_t x, uint16_t y) {
Pokitto 63:7d1c08cdde5c 1986 uint16_t w = *bitmap;
Pokitto 63:7d1c08cdde5c 1987 uint8_t sourcebyte = bitmap[2+(y * ((w+7)>>3))+ (x>>3)];
Pokitto 63:7d1c08cdde5c 1988 return sourcebyte & (0x80>>(x&7));
Pokitto 63:7d1c08cdde5c 1989 }
Pokitto 63:7d1c08cdde5c 1990
Pokitto 63:7d1c08cdde5c 1991 int Display::print_char(uint8_t x, uint8_t y, unsigned char c) {
Pokitto 63:7d1c08cdde5c 1992 c -= font[2];
Pokitto 63:7d1c08cdde5c 1993 if (m_mode) return directChar(x,y,c);
Pokitto 63:7d1c08cdde5c 1994 return bufferChar(x,y,c);
Pokitto 63:7d1c08cdde5c 1995 }
Pokitto 63:7d1c08cdde5c 1996
Pokitto 63:7d1c08cdde5c 1997 void Display::drawChar(int8_t x, int8_t y, unsigned char c, uint8_t size) {
Pokitto 63:7d1c08cdde5c 1998 print_char(x,y,c);
Pokitto 63:7d1c08cdde5c 1999 return;
Pokitto 63:7d1c08cdde5c 2000 }
Pokitto 63:7d1c08cdde5c 2001
Pokitto 63:7d1c08cdde5c 2002
Pokitto 63:7d1c08cdde5c 2003 bool Display::isDirectPrintingEnabled() {
Pokitto 63:7d1c08cdde5c 2004 return m_mode;
Pokitto 63:7d1c08cdde5c 2005 }
Pokitto 63:7d1c08cdde5c 2006
Pokitto 63:7d1c08cdde5c 2007 void Display::enableDirectPrinting(uint8_t m) {
Pokitto 63:7d1c08cdde5c 2008 if (m) {
Pokitto 63:7d1c08cdde5c 2009 m_mode=true;
Pokitto 63:7d1c08cdde5c 2010 m_w = POK_LCD_W;
Pokitto 63:7d1c08cdde5c 2011 m_h = POK_LCD_H;
Pokitto 63:7d1c08cdde5c 2012 } else {
Pokitto 63:7d1c08cdde5c 2013 m_mode=false;
Pokitto 63:7d1c08cdde5c 2014 m_w = getWidth();
Pokitto 63:7d1c08cdde5c 2015 m_h = getHeight();
Pokitto 63:7d1c08cdde5c 2016 }
Pokitto 63:7d1c08cdde5c 2017 }
Pokitto 63:7d1c08cdde5c 2018
Pokitto 63:7d1c08cdde5c 2019 void Display::write(uint8_t c) {
Pokitto 63:7d1c08cdde5c 2020 int charstep=0;
Pokitto 63:7d1c08cdde5c 2021 if(font[3]) {
Pokitto 63:7d1c08cdde5c 2022 // only caps in this font
Pokitto 63:7d1c08cdde5c 2023 if (c>=97) c-=32;
Pokitto 63:7d1c08cdde5c 2024 }
Pokitto 63:7d1c08cdde5c 2025 switch(c) {
Pokitto 63:7d1c08cdde5c 2026 case '\0': //null
Pokitto 63:7d1c08cdde5c 2027 break;
Pokitto 63:7d1c08cdde5c 2028 case '\n': //line feed
Pokitto 63:7d1c08cdde5c 2029 cursorX = 0;
Pokitto 63:7d1c08cdde5c 2030 inc_txtline();
Pokitto 63:7d1c08cdde5c 2031 break;
Pokitto 63:7d1c08cdde5c 2032 case 8: //backspace
Pokitto 63:7d1c08cdde5c 2033 cursorX -= font[0];
Pokitto 63:7d1c08cdde5c 2034 charstep=print_char(cursorX,cursorY,' ');
Pokitto 63:7d1c08cdde5c 2035 break;
Pokitto 63:7d1c08cdde5c 2036 case 13: //carriage return
Pokitto 63:7d1c08cdde5c 2037 cursorX = 0;
Pokitto 63:7d1c08cdde5c 2038 break;
Pokitto 63:7d1c08cdde5c 2039 case 14: //form feed new page(clear screen)
Pokitto 63:7d1c08cdde5c 2040 //clear_screen();
Pokitto 63:7d1c08cdde5c 2041 break;
Pokitto 63:7d1c08cdde5c 2042 default:
Pokitto 63:7d1c08cdde5c 2043 if (cursorX >= (m_w - font[0])) {
Pokitto 63:7d1c08cdde5c 2044 cursorX = 0;
Pokitto 63:7d1c08cdde5c 2045 if (textWrap) inc_txtline();
Pokitto 63:7d1c08cdde5c 2046 else return; // stop outputting text
Pokitto 63:7d1c08cdde5c 2047 charstep=print_char(cursorX,cursorY,c);
Pokitto 63:7d1c08cdde5c 2048 }
Pokitto 63:7d1c08cdde5c 2049 else
Pokitto 63:7d1c08cdde5c 2050 charstep=print_char(cursorX,cursorY,c);
Pokitto 63:7d1c08cdde5c 2051 #ifndef FULLWIDTHSPACES
Pokitto 63:7d1c08cdde5c 2052 if (c==' ' && adjustCharStep) charstep=(charstep>>1)+1;
Pokitto 63:7d1c08cdde5c 2053 #endif
Pokitto 63:7d1c08cdde5c 2054 cursorX += charstep;
Pokitto 63:7d1c08cdde5c 2055 }
Pokitto 63:7d1c08cdde5c 2056 }
Pokitto 63:7d1c08cdde5c 2057
Pokitto 63:7d1c08cdde5c 2058 void Display::inc_txtline() {
Pokitto 63:7d1c08cdde5c 2059 if (cursorY > m_h - 2*font[1]) //= (height - (font[1]+1)))
Pokitto 63:7d1c08cdde5c 2060 #if SCROLL_TEXT > 0
Pokitto 63:7d1c08cdde5c 2061 scroll(font[1] + adjustLineStep);
Pokitto 63:7d1c08cdde5c 2062 #else
Pokitto 63:7d1c08cdde5c 2063 cursorY = 0;
Pokitto 63:7d1c08cdde5c 2064 #endif
Pokitto 63:7d1c08cdde5c 2065 else
Pokitto 63:7d1c08cdde5c 2066 cursorY += font[1] + adjustLineStep;
Pokitto 63:7d1c08cdde5c 2067 }
Pokitto 63:7d1c08cdde5c 2068
Pokitto 63:7d1c08cdde5c 2069 /* default implementation: may be overridden */
Pokitto 63:7d1c08cdde5c 2070 void Display::write(const char *str)
Pokitto 63:7d1c08cdde5c 2071 {
Pokitto 63:7d1c08cdde5c 2072 while (*str)
Pokitto 63:7d1c08cdde5c 2073 write(*str++);
Pokitto 63:7d1c08cdde5c 2074 }
Pokitto 63:7d1c08cdde5c 2075
Pokitto 63:7d1c08cdde5c 2076 /* default implementation: may be overridden */
Pokitto 63:7d1c08cdde5c 2077 void Display::write(const uint8_t *buffer, uint8_t size)
Pokitto 63:7d1c08cdde5c 2078 {
Pokitto 63:7d1c08cdde5c 2079 while (size--)
Pokitto 63:7d1c08cdde5c 2080 write(*buffer++);
Pokitto 63:7d1c08cdde5c 2081 }
Pokitto 63:7d1c08cdde5c 2082
Pokitto 63:7d1c08cdde5c 2083 void Display::print(const char str[])
Pokitto 63:7d1c08cdde5c 2084 {
Pokitto 63:7d1c08cdde5c 2085 write(str);
Pokitto 63:7d1c08cdde5c 2086 }
Pokitto 63:7d1c08cdde5c 2087
Pokitto 63:7d1c08cdde5c 2088 void Display::print(char c, int base)
Pokitto 63:7d1c08cdde5c 2089 {
Pokitto 63:7d1c08cdde5c 2090 print((long) c, base);
Pokitto 63:7d1c08cdde5c 2091 }
Pokitto 63:7d1c08cdde5c 2092
Pokitto 63:7d1c08cdde5c 2093 void Display::print(unsigned char b, int base)
Pokitto 63:7d1c08cdde5c 2094 {
Pokitto 63:7d1c08cdde5c 2095 print((unsigned long) b, base);
Pokitto 63:7d1c08cdde5c 2096 }
Pokitto 63:7d1c08cdde5c 2097
Pokitto 63:7d1c08cdde5c 2098 void Display::print(int n, int base)
Pokitto 63:7d1c08cdde5c 2099 {
Pokitto 63:7d1c08cdde5c 2100 print((long) n, base);
Pokitto 63:7d1c08cdde5c 2101 }
Pokitto 63:7d1c08cdde5c 2102
Pokitto 63:7d1c08cdde5c 2103 void Display::print(unsigned int n, int base)
Pokitto 63:7d1c08cdde5c 2104 {
Pokitto 63:7d1c08cdde5c 2105 print((unsigned long) n, base);
Pokitto 63:7d1c08cdde5c 2106 }
Pokitto 63:7d1c08cdde5c 2107
Pokitto 63:7d1c08cdde5c 2108 void Display::print(long n, int base)
Pokitto 63:7d1c08cdde5c 2109 {
Pokitto 63:7d1c08cdde5c 2110 if (base == 0) {
Pokitto 63:7d1c08cdde5c 2111 write(n);
Pokitto 63:7d1c08cdde5c 2112 } else if (base == 10) {
Pokitto 63:7d1c08cdde5c 2113 if (n < 0) {
Pokitto 63:7d1c08cdde5c 2114 print('-');
Pokitto 63:7d1c08cdde5c 2115 n = -n;
Pokitto 63:7d1c08cdde5c 2116 }
Pokitto 63:7d1c08cdde5c 2117 printNumber(n, 10);
Pokitto 63:7d1c08cdde5c 2118 } else {
Pokitto 63:7d1c08cdde5c 2119 printNumber(n, base);
Pokitto 63:7d1c08cdde5c 2120 }
Pokitto 63:7d1c08cdde5c 2121 }
Pokitto 63:7d1c08cdde5c 2122
Pokitto 63:7d1c08cdde5c 2123 void Display::print(unsigned long n, int base)
Pokitto 63:7d1c08cdde5c 2124 {
Pokitto 63:7d1c08cdde5c 2125 if (base == 0) write(n);
Pokitto 63:7d1c08cdde5c 2126 else printNumber(n, base);
Pokitto 63:7d1c08cdde5c 2127 }
Pokitto 63:7d1c08cdde5c 2128
Pokitto 63:7d1c08cdde5c 2129 void Display::print(double n, int digits)
Pokitto 63:7d1c08cdde5c 2130 {
Pokitto 63:7d1c08cdde5c 2131 printFloat(n, digits);
Pokitto 63:7d1c08cdde5c 2132 }
Pokitto 63:7d1c08cdde5c 2133
Pokitto 63:7d1c08cdde5c 2134 void Display::println(void)
Pokitto 63:7d1c08cdde5c 2135 {
Pokitto 63:7d1c08cdde5c 2136 print('\r');
Pokitto 63:7d1c08cdde5c 2137 print('\n');
Pokitto 63:7d1c08cdde5c 2138 }
Pokitto 63:7d1c08cdde5c 2139
Pokitto 63:7d1c08cdde5c 2140 void Display::println(const char c[])
Pokitto 63:7d1c08cdde5c 2141 {
Pokitto 63:7d1c08cdde5c 2142 print(c);
Pokitto 63:7d1c08cdde5c 2143 println();
Pokitto 63:7d1c08cdde5c 2144 }
Pokitto 63:7d1c08cdde5c 2145
Pokitto 63:7d1c08cdde5c 2146 void Display::println(char c, int base)
Pokitto 63:7d1c08cdde5c 2147 {
Pokitto 63:7d1c08cdde5c 2148 print(c, base);
Pokitto 63:7d1c08cdde5c 2149 println();
Pokitto 63:7d1c08cdde5c 2150 }
Pokitto 63:7d1c08cdde5c 2151
Pokitto 63:7d1c08cdde5c 2152 void Display::println(unsigned char b, int base)
Pokitto 63:7d1c08cdde5c 2153 {
Pokitto 63:7d1c08cdde5c 2154 print(b, base);
Pokitto 63:7d1c08cdde5c 2155 println();
Pokitto 63:7d1c08cdde5c 2156 }
Pokitto 63:7d1c08cdde5c 2157
Pokitto 63:7d1c08cdde5c 2158 void Display::println(int n, int base)
Pokitto 63:7d1c08cdde5c 2159 {
Pokitto 63:7d1c08cdde5c 2160 print(n, base);
Pokitto 63:7d1c08cdde5c 2161 println();
Pokitto 63:7d1c08cdde5c 2162 }
Pokitto 63:7d1c08cdde5c 2163
Pokitto 63:7d1c08cdde5c 2164 void Display::println(unsigned int n, int base)
Pokitto 63:7d1c08cdde5c 2165 {
Pokitto 63:7d1c08cdde5c 2166 print(n, base);
Pokitto 63:7d1c08cdde5c 2167 println();
Pokitto 63:7d1c08cdde5c 2168 }
Pokitto 63:7d1c08cdde5c 2169
Pokitto 63:7d1c08cdde5c 2170 void Display::println(long n, int base)
Pokitto 63:7d1c08cdde5c 2171 {
Pokitto 63:7d1c08cdde5c 2172 print(n, base);
Pokitto 63:7d1c08cdde5c 2173 println();
Pokitto 63:7d1c08cdde5c 2174 }
Pokitto 63:7d1c08cdde5c 2175
Pokitto 63:7d1c08cdde5c 2176 void Display::println(unsigned long n, int base)
Pokitto 63:7d1c08cdde5c 2177 {
Pokitto 63:7d1c08cdde5c 2178 print(n, base);
Pokitto 63:7d1c08cdde5c 2179 println();
Pokitto 63:7d1c08cdde5c 2180 }
Pokitto 63:7d1c08cdde5c 2181
Pokitto 63:7d1c08cdde5c 2182 void Display::println(double n, int digits)
Pokitto 63:7d1c08cdde5c 2183 {
Pokitto 63:7d1c08cdde5c 2184 print(n, digits);
Pokitto 63:7d1c08cdde5c 2185 println();
Pokitto 63:7d1c08cdde5c 2186 }
Pokitto 63:7d1c08cdde5c 2187
Pokitto 63:7d1c08cdde5c 2188 void Display::set_cursor(uint8_t x, uint8_t y) {
Pokitto 63:7d1c08cdde5c 2189 cursorX = x;
Pokitto 63:7d1c08cdde5c 2190 cursorY = y;
Pokitto 63:7d1c08cdde5c 2191 }
Pokitto 63:7d1c08cdde5c 2192
Pokitto 63:7d1c08cdde5c 2193 void Display::print(uint8_t x, uint8_t y, const char str[]) {
Pokitto 63:7d1c08cdde5c 2194 cursorX = x;
Pokitto 63:7d1c08cdde5c 2195 cursorY = y;
Pokitto 63:7d1c08cdde5c 2196 write(str);
Pokitto 63:7d1c08cdde5c 2197
Pokitto 63:7d1c08cdde5c 2198 }
Pokitto 63:7d1c08cdde5c 2199 void Display::print(uint8_t x, uint8_t y, char c, int base) {
Pokitto 63:7d1c08cdde5c 2200 cursorX = x;
Pokitto 63:7d1c08cdde5c 2201 cursorY = y;
Pokitto 63:7d1c08cdde5c 2202 print((long) c, base);
Pokitto 63:7d1c08cdde5c 2203 }
Pokitto 63:7d1c08cdde5c 2204 void Display::print(uint8_t x, uint8_t y, unsigned char b, int base) {
Pokitto 63:7d1c08cdde5c 2205 cursorX = x;
Pokitto 63:7d1c08cdde5c 2206 cursorY = y;
Pokitto 63:7d1c08cdde5c 2207 print((unsigned long) b, base);
Pokitto 63:7d1c08cdde5c 2208 }
Pokitto 63:7d1c08cdde5c 2209 void Display::print(uint8_t x, uint8_t y, int n, int base) {
Pokitto 63:7d1c08cdde5c 2210 cursorX = x;
Pokitto 63:7d1c08cdde5c 2211 cursorY = y;
Pokitto 63:7d1c08cdde5c 2212 print((long) n, base);
Pokitto 63:7d1c08cdde5c 2213 }
Pokitto 63:7d1c08cdde5c 2214 void Display::print(uint8_t x, uint8_t y, unsigned int n, int base) {
Pokitto 63:7d1c08cdde5c 2215 cursorX = x;
Pokitto 63:7d1c08cdde5c 2216 cursorY = y;
Pokitto 63:7d1c08cdde5c 2217 print((unsigned long) n, base);
Pokitto 63:7d1c08cdde5c 2218 }
Pokitto 63:7d1c08cdde5c 2219 void Display::print(uint8_t x, uint8_t y, long n, int base) {
Pokitto 63:7d1c08cdde5c 2220 cursorX = x;
Pokitto 63:7d1c08cdde5c 2221 cursorY = y;
Pokitto 63:7d1c08cdde5c 2222 print(n,base);
Pokitto 63:7d1c08cdde5c 2223 }
Pokitto 63:7d1c08cdde5c 2224 void Display::print(uint8_t x, uint8_t y, unsigned long n, int base) {
Pokitto 63:7d1c08cdde5c 2225 cursorX = x;
Pokitto 63:7d1c08cdde5c 2226 cursorY = y;
Pokitto 63:7d1c08cdde5c 2227 print(n,base);
Pokitto 63:7d1c08cdde5c 2228 }
Pokitto 63:7d1c08cdde5c 2229 void Display::print(uint8_t x, uint8_t y, double n, int digits) {
Pokitto 63:7d1c08cdde5c 2230 cursorX = x;
Pokitto 63:7d1c08cdde5c 2231 cursorY = y;
Pokitto 63:7d1c08cdde5c 2232 print(n,digits);
Pokitto 63:7d1c08cdde5c 2233 }
Pokitto 63:7d1c08cdde5c 2234
Pokitto 63:7d1c08cdde5c 2235 void Display::println(uint8_t x, uint8_t y, const char c[])
Pokitto 63:7d1c08cdde5c 2236 {
Pokitto 63:7d1c08cdde5c 2237 cursorX = x;
Pokitto 63:7d1c08cdde5c 2238 cursorY = y;
Pokitto 63:7d1c08cdde5c 2239 print(c);
Pokitto 63:7d1c08cdde5c 2240 println();
Pokitto 63:7d1c08cdde5c 2241 }
Pokitto 63:7d1c08cdde5c 2242
Pokitto 63:7d1c08cdde5c 2243 void Display::println(uint8_t x, uint8_t y, char c, int base)
Pokitto 63:7d1c08cdde5c 2244 {
Pokitto 63:7d1c08cdde5c 2245 cursorX = x;
Pokitto 63:7d1c08cdde5c 2246 cursorY = y;
Pokitto 63:7d1c08cdde5c 2247 print(c, base);
Pokitto 63:7d1c08cdde5c 2248 println();
Pokitto 63:7d1c08cdde5c 2249 }
Pokitto 63:7d1c08cdde5c 2250
Pokitto 63:7d1c08cdde5c 2251 void Display::println(uint8_t x, uint8_t y, unsigned char b, int base)
Pokitto 63:7d1c08cdde5c 2252 {
Pokitto 63:7d1c08cdde5c 2253 cursorX = x;
Pokitto 63:7d1c08cdde5c 2254 cursorY = y;
Pokitto 63:7d1c08cdde5c 2255 print(b, base);
Pokitto 63:7d1c08cdde5c 2256 println();
Pokitto 63:7d1c08cdde5c 2257 }
Pokitto 63:7d1c08cdde5c 2258
Pokitto 63:7d1c08cdde5c 2259 void Display::println(uint8_t x, uint8_t y, int n, int base)
Pokitto 63:7d1c08cdde5c 2260 {
Pokitto 63:7d1c08cdde5c 2261 cursorX = x;
Pokitto 63:7d1c08cdde5c 2262 cursorY = y;
Pokitto 63:7d1c08cdde5c 2263 print(n, base);
Pokitto 63:7d1c08cdde5c 2264 println();
Pokitto 63:7d1c08cdde5c 2265 }
Pokitto 63:7d1c08cdde5c 2266
Pokitto 63:7d1c08cdde5c 2267 void Display::println(uint8_t x, uint8_t y, unsigned int n, int base)
Pokitto 63:7d1c08cdde5c 2268 {
Pokitto 63:7d1c08cdde5c 2269 cursorX = x;
Pokitto 63:7d1c08cdde5c 2270 cursorY = y;
Pokitto 63:7d1c08cdde5c 2271 print(n, base);
Pokitto 63:7d1c08cdde5c 2272 println();
Pokitto 63:7d1c08cdde5c 2273 }
Pokitto 63:7d1c08cdde5c 2274
Pokitto 63:7d1c08cdde5c 2275 void Display::println(uint8_t x, uint8_t y, long n, int base)
Pokitto 63:7d1c08cdde5c 2276 {
Pokitto 63:7d1c08cdde5c 2277 cursorX = x;
Pokitto 63:7d1c08cdde5c 2278 cursorY = y;
Pokitto 63:7d1c08cdde5c 2279 print(n, base);
Pokitto 63:7d1c08cdde5c 2280 println();
Pokitto 63:7d1c08cdde5c 2281 }
Pokitto 63:7d1c08cdde5c 2282
Pokitto 63:7d1c08cdde5c 2283 void Display::println(uint8_t x, uint8_t y, unsigned long n, int base)
Pokitto 63:7d1c08cdde5c 2284 {
Pokitto 63:7d1c08cdde5c 2285 cursorX = x;
Pokitto 63:7d1c08cdde5c 2286 cursorY = y;
Pokitto 63:7d1c08cdde5c 2287 print(n, base);
Pokitto 63:7d1c08cdde5c 2288 println();
Pokitto 63:7d1c08cdde5c 2289 }
Pokitto 63:7d1c08cdde5c 2290
Pokitto 63:7d1c08cdde5c 2291 void Display::println(uint8_t x, uint8_t y, double n, int digits)
Pokitto 63:7d1c08cdde5c 2292 {
Pokitto 63:7d1c08cdde5c 2293 cursorX = x;
Pokitto 63:7d1c08cdde5c 2294 cursorY = y;
Pokitto 63:7d1c08cdde5c 2295 print(n, digits);
Pokitto 63:7d1c08cdde5c 2296 println();
Pokitto 63:7d1c08cdde5c 2297 }
Pokitto 63:7d1c08cdde5c 2298
Pokitto 63:7d1c08cdde5c 2299 void Display::printNumber(unsigned long n, uint8_t base)
Pokitto 63:7d1c08cdde5c 2300 {
Pokitto 63:7d1c08cdde5c 2301 unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
Pokitto 63:7d1c08cdde5c 2302 unsigned long i = 0;
Pokitto 63:7d1c08cdde5c 2303
Pokitto 63:7d1c08cdde5c 2304 if (n == 0) {
Pokitto 63:7d1c08cdde5c 2305 print('0');
Pokitto 63:7d1c08cdde5c 2306 return;
Pokitto 63:7d1c08cdde5c 2307 }
Pokitto 63:7d1c08cdde5c 2308
Pokitto 63:7d1c08cdde5c 2309 while (n > 0) {
Pokitto 63:7d1c08cdde5c 2310 buf[i++] = n % base;
Pokitto 63:7d1c08cdde5c 2311 n /= base;
Pokitto 63:7d1c08cdde5c 2312 }
Pokitto 63:7d1c08cdde5c 2313
Pokitto 63:7d1c08cdde5c 2314 for (; i > 0; i--)
Pokitto 63:7d1c08cdde5c 2315 print((char) (buf[i - 1] < 10 ?
Pokitto 63:7d1c08cdde5c 2316 '0' + buf[i - 1] :
Pokitto 63:7d1c08cdde5c 2317 'A' + buf[i - 1] - 10));
Pokitto 63:7d1c08cdde5c 2318 }
Pokitto 63:7d1c08cdde5c 2319
Pokitto 63:7d1c08cdde5c 2320 void Display::printFloat(double number, uint8_t digits)
Pokitto 63:7d1c08cdde5c 2321 {
Pokitto 63:7d1c08cdde5c 2322 // Handle negative numbers
Pokitto 63:7d1c08cdde5c 2323 if (number < 0.0)
Pokitto 63:7d1c08cdde5c 2324 {
Pokitto 63:7d1c08cdde5c 2325 print('-');
Pokitto 63:7d1c08cdde5c 2326 number = -number;
Pokitto 63:7d1c08cdde5c 2327 }
Pokitto 63:7d1c08cdde5c 2328
Pokitto 63:7d1c08cdde5c 2329 // Round correctly so that print(1.999, 2) prints as "2.00"
Pokitto 63:7d1c08cdde5c 2330 double rounding = 0.5;
Pokitto 63:7d1c08cdde5c 2331 for (uint8_t i=0; i<digits; ++i)
Pokitto 63:7d1c08cdde5c 2332 rounding /= 10.0;
Pokitto 63:7d1c08cdde5c 2333
Pokitto 63:7d1c08cdde5c 2334 number += rounding;
Pokitto 63:7d1c08cdde5c 2335
Pokitto 63:7d1c08cdde5c 2336 // Extract the integer part of the number and print it
Pokitto 63:7d1c08cdde5c 2337 unsigned long int_part = (unsigned long)number;
Pokitto 63:7d1c08cdde5c 2338 double remainder = number - (double)int_part;
Pokitto 63:7d1c08cdde5c 2339 print(int_part);
Pokitto 63:7d1c08cdde5c 2340
Pokitto 63:7d1c08cdde5c 2341 // Print the decimal point, but only if there are digits beyond
Pokitto 63:7d1c08cdde5c 2342 if (digits > 0)
Pokitto 63:7d1c08cdde5c 2343 print(".");
Pokitto 63:7d1c08cdde5c 2344
Pokitto 63:7d1c08cdde5c 2345 // Extract digits from the remainder one at a time
Pokitto 63:7d1c08cdde5c 2346 while (digits-- > 0)
Pokitto 63:7d1c08cdde5c 2347 {
Pokitto 63:7d1c08cdde5c 2348 remainder *= 10.0;
Pokitto 63:7d1c08cdde5c 2349 int toPrint = int(remainder);
Pokitto 63:7d1c08cdde5c 2350 print(toPrint);
Pokitto 63:7d1c08cdde5c 2351 remainder -= toPrint;
Pokitto 63:7d1c08cdde5c 2352 }
Pokitto 63:7d1c08cdde5c 2353 }
Pokitto 63:7d1c08cdde5c 2354
Pokitto 63:7d1c08cdde5c 2355
Pokitto 63:7d1c08cdde5c 2356 void Display::draw4BitColumn(int16_t x, int16_t y, uint8_t h, uint8_t* bitmap)
Pokitto 63:7d1c08cdde5c 2357 {
Pokitto 63:7d1c08cdde5c 2358 int8_t scry;
Pokitto 63:7d1c08cdde5c 2359 uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
Pokitto 63:7d1c08cdde5c 2360
Pokitto 63:7d1c08cdde5c 2361 /** ONLY 4-bit mode for time being **/
Pokitto 63:7d1c08cdde5c 2362
Pokitto 63:7d1c08cdde5c 2363 if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
Pokitto 63:7d1c08cdde5c 2364 for (scry = y; scry < h+y; scry++) {
Pokitto 63:7d1c08cdde5c 2365 uint8_t sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 2366 uint8_t targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 2367 targetpixel = (targetpixel&0x0F) | (sourcepixel << 4);
Pokitto 63:7d1c08cdde5c 2368 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 2369 bitmap++;
Pokitto 63:7d1c08cdde5c 2370 scrptr+=55;
Pokitto 63:7d1c08cdde5c 2371 }
Pokitto 63:7d1c08cdde5c 2372 } else { /** ODD pixel starting line **/
Pokitto 63:7d1c08cdde5c 2373 for (scry = y; scry < h+y; scry++) {
Pokitto 63:7d1c08cdde5c 2374 uint8_t sourcepixel = *bitmap;
Pokitto 63:7d1c08cdde5c 2375 uint8_t targetpixel = *scrptr;
Pokitto 63:7d1c08cdde5c 2376 // store source pixel in lower nibble of target
Pokitto 63:7d1c08cdde5c 2377 targetpixel = (targetpixel & 0xF0) | (sourcepixel);
Pokitto 63:7d1c08cdde5c 2378 *scrptr = targetpixel;
Pokitto 63:7d1c08cdde5c 2379 scrptr+=55;
Pokitto 63:7d1c08cdde5c 2380 bitmap++;
Pokitto 63:7d1c08cdde5c 2381 }
Pokitto 63:7d1c08cdde5c 2382 }
Pokitto 63:7d1c08cdde5c 2383 }
Pokitto 63:7d1c08cdde5c 2384
Pokitto 63:7d1c08cdde5c 2385 /**
Pokitto 63:7d1c08cdde5c 2386 * Setup or disable the sprite. Note that enabled sprites must always have subsequent indices, starting from the index zero.
Pokitto 63:7d1c08cdde5c 2387 * You cannot have gaps in indices of enabled sprites.
Pokitto 63:7d1c08cdde5c 2388 * The max number of sprites can be changed by a SPRITE_COUNT define, the default is 4.
Pokitto 63:7d1c08cdde5c 2389 * Note: the sprites currently work only in the 220 x 176 x 2bpp mode.
Pokitto 63:7d1c08cdde5c 2390 * @param index The sprite index. The lower index is drawn first, i.e. is on bottom.
Pokitto 63:7d1c08cdde5c 2391 * @param bitmap A pointer to a 2bpp bitmap. A NULL value means that the sprite is disabled. The ownership is not transferred, so the caller must keep the bitmap alive.
Pokitto 63:7d1c08cdde5c 2392 * @param palette4x16bit Four color palette of 16bit elements. The first color value is considered as transparent. The palette is copied to the sprite struct, so the caller do not have to keep it alive.
Pokitto 63:7d1c08cdde5c 2393 * @param x The initial x
Pokitto 63:7d1c08cdde5c 2394 * @param y The initial y
Pokitto 63:7d1c08cdde5c 2395 * @param doResetDirtyRect (default=true) True, if the previous coordinates are reseted.
Pokitto 63:7d1c08cdde5c 2396 */
Pokitto 63:7d1c08cdde5c 2397 void Display::setSpriteBitmap(uint8_t index, const uint8_t* bitmap, const uint16_t* palette4x16bit, int16_t x, int16_t y, bool doResetDirtyRect ) {
Pokitto 63:7d1c08cdde5c 2398
Pokitto 63:7d1c08cdde5c 2399 setSprite(index, &(bitmap[2]), palette4x16bit, x, y, bitmap[0], bitmap[1], doResetDirtyRect);
Pokitto 63:7d1c08cdde5c 2400 }
Pokitto 63:7d1c08cdde5c 2401
Pokitto 63:7d1c08cdde5c 2402 /**
Pokitto 63:7d1c08cdde5c 2403 * Setup or disable the sprite. Note that enabled sprites must always have subsequent indices, starting from the index zero.
Pokitto 63:7d1c08cdde5c 2404 * You cannot have gaps in indices of enabled sprites.
Pokitto 63:7d1c08cdde5c 2405 * The max number of sprites can be changed by a SPRITE_COUNT define, the default is 4.
Pokitto 63:7d1c08cdde5c 2406 * Note: the sprites currently work only in the 220 x 176 x 2bpp mode.
Pokitto 63:7d1c08cdde5c 2407 * @param index The sprite index. The lower index is drawn first, i.e. is on bottom. Note that
Pokitto 63:7d1c08cdde5c 2408 * @param data A pointer to a 2bpp pixel data of size w x h. A NULL value means that the sprite is disabled. The ownership is not transferred, so the caller must keep the data alive.
Pokitto 63:7d1c08cdde5c 2409 * @param palette4x16bit Four color palette of 16bit elements. The first color value is considered as transparent. The palette is copied to the sprite struct, so the caller do not have to keep it alive.
Pokitto 63:7d1c08cdde5c 2410 * @param x The initial x
Pokitto 63:7d1c08cdde5c 2411 * @param y The initial y
Pokitto 63:7d1c08cdde5c 2412 * @param w Width
Pokitto 63:7d1c08cdde5c 2413 * @param h Height
Pokitto 63:7d1c08cdde5c 2414 */
Pokitto 63:7d1c08cdde5c 2415 void Display::setSprite(uint8_t index, const uint8_t* data, const uint16_t* palette4x16bit, int16_t x, int16_t y, uint8_t w, uint8_t h, bool doResetDirtyRect ) {
Pokitto 63:7d1c08cdde5c 2416
Pokitto 63:7d1c08cdde5c 2417 if(index >= SPRITE_COUNT) return;
Pokitto 63:7d1c08cdde5c 2418 m_sprites[index].bitmapData = data;
Pokitto 63:7d1c08cdde5c 2419 m_sprites[index].x = x;
Pokitto 63:7d1c08cdde5c 2420 m_sprites[index].y = y;
Pokitto 63:7d1c08cdde5c 2421 if (doResetDirtyRect) {
Pokitto 63:7d1c08cdde5c 2422 m_sprites[index].oldx = x;
Pokitto 63:7d1c08cdde5c 2423 m_sprites[index].oldy = y;
Pokitto 63:7d1c08cdde5c 2424 }
Pokitto 63:7d1c08cdde5c 2425 m_sprites[index].w = w;
Pokitto 63:7d1c08cdde5c 2426 m_sprites[index].h = h;
Pokitto 63:7d1c08cdde5c 2427 if( palette4x16bit ) memcpy(m_sprites[index].palette, palette4x16bit, 4*2);
Pokitto 63:7d1c08cdde5c 2428 }
Pokitto 63:7d1c08cdde5c 2429
Pokitto 63:7d1c08cdde5c 2430 /**
Pokitto 63:7d1c08cdde5c 2431 * Set the sprite position.
Pokitto 63:7d1c08cdde5c 2432 * @param index The sprite index
Pokitto 63:7d1c08cdde5c 2433 * @param x
Pokitto 63:7d1c08cdde5c 2434 * @param y
Pokitto 63:7d1c08cdde5c 2435 */
Pokitto 63:7d1c08cdde5c 2436 void Display::setSpritePos(uint8_t index, int16_t x, int16_t y) {
Pokitto 63:7d1c08cdde5c 2437
Pokitto 63:7d1c08cdde5c 2438 if(index >= SPRITE_COUNT) return;
Pokitto 63:7d1c08cdde5c 2439 m_sprites[index].x = x;
Pokitto 63:7d1c08cdde5c 2440 m_sprites[index].y = y;
Pokitto 63:7d1c08cdde5c 2441 }
Pokitto 63:7d1c08cdde5c 2442
Pokitto 63:7d1c08cdde5c 2443 void Display::lcdRefresh(unsigned char* scr, bool useDirectDrawMode) {
Pokitto 63:7d1c08cdde5c 2444
Pokitto 63:7d1c08cdde5c 2445 #if POK_SCREENMODE == MODE_HI_4COLOR
Pokitto 63:7d1c08cdde5c 2446 // If there is one or more sprites, use sprite enabled drawing.
Pokitto 63:7d1c08cdde5c 2447 if (m_sprites[0].bitmapData != NULL)
Pokitto 63:7d1c08cdde5c 2448 lcdRefreshMode1Spr(scr, 0, 0, LCDWIDTH, LCDHEIGHT, paletteptr, m_sprites, useDirectDrawMode);
Pokitto 63:7d1c08cdde5c 2449 else if (!useDirectDrawMode)
Pokitto 63:7d1c08cdde5c 2450 lcdRefreshMode1(m_scrbuf, 0, 0, LCDWIDTH, LCDHEIGHT, paletteptr);
Pokitto 63:7d1c08cdde5c 2451 #endif
Pokitto 63:7d1c08cdde5c 2452
Pokitto 63:7d1c08cdde5c 2453 // For the screen modes that do not support sprites, return if the direct draw mode is used.
Pokitto 63:7d1c08cdde5c 2454 if (useDirectDrawMode) return;
Pokitto 63:7d1c08cdde5c 2455 #if POK_SCREENMODE == MODE13
Pokitto 63:7d1c08cdde5c 2456 lcdRefreshMode13(m_scrbuf, paletteptr, palOffset);
Pokitto 63:7d1c08cdde5c 2457 #endif
Pokitto 63:7d1c08cdde5c 2458
Pokitto 63:7d1c08cdde5c 2459 #if POK_SCREENMODE == MIXMODE
Pokitto 63:7d1c08cdde5c 2460 lcdRefreshMixMode(m_scrbuf, paletteptr, scanType);
Pokitto 63:7d1c08cdde5c 2461 #endif
Pokitto 63:7d1c08cdde5c 2462
Pokitto 63:7d1c08cdde5c 2463 #if POK_SCREENMODE == MODE64
Pokitto 63:7d1c08cdde5c 2464 lcdRefreshMode64(m_scrbuf, paletteptr);
Pokitto 63:7d1c08cdde5c 2465 #endif
Pokitto 63:7d1c08cdde5c 2466
Pokitto 63:7d1c08cdde5c 2467 #if POK_SCREENMODE == MODE_GAMEBOY
Pokitto 63:7d1c08cdde5c 2468 lcdRefreshModeGBC(scr, paletteptr);
Pokitto 63:7d1c08cdde5c 2469 #endif
Pokitto 63:7d1c08cdde5c 2470
Pokitto 63:7d1c08cdde5c 2471 #if POK_SCREENMODE == MODE_FAST_16COLOR
Pokitto 63:7d1c08cdde5c 2472 lcdRefreshMode2(scr, paletteptr);
Pokitto 63:7d1c08cdde5c 2473 #endif
Pokitto 63:7d1c08cdde5c 2474
Pokitto 63:7d1c08cdde5c 2475 #if POK_SCREENMODE == MODE_GAMEBUINO_16COLOR
Pokitto 63:7d1c08cdde5c 2476 lcdRefreshGB(scr, paletteptr);
Pokitto 63:7d1c08cdde5c 2477 #endif
Pokitto 63:7d1c08cdde5c 2478
Pokitto 63:7d1c08cdde5c 2479 #if POK_SCREENMODE == MODE_ARDUBOY_16COLOR
Pokitto 63:7d1c08cdde5c 2480 lcdRefreshAB(scr, paletteptr);
Pokitto 63:7d1c08cdde5c 2481 #endif
Pokitto 63:7d1c08cdde5c 2482
Pokitto 63:7d1c08cdde5c 2483 }
Pokitto 63:7d1c08cdde5c 2484
Pokitto 63:7d1c08cdde5c 2485 void Display::setFrameBufferTo(uint8_t* sb) {
Pokitto 63:7d1c08cdde5c 2486 m_scrbuf = sb;
Pokitto 63:7d1c08cdde5c 2487 };
Pokitto 63:7d1c08cdde5c 2488
Pokitto 63:7d1c08cdde5c 2489 void Display::setTileBufferTo(uint8_t* tb) {
Pokitto 63:7d1c08cdde5c 2490 m_tilebuf = tb;
Pokitto 63:7d1c08cdde5c 2491 };
Pokitto 63:7d1c08cdde5c 2492
Pokitto 63:7d1c08cdde5c 2493 void Display::loadTileset(const uint8_t* ts) {
Pokitto 63:7d1c08cdde5c 2494 m_tileset = (uint8_t*) ts;
Pokitto 63:7d1c08cdde5c 2495 };
Pokitto 63:7d1c08cdde5c 2496
Pokitto 63:7d1c08cdde5c 2497 void Display::setTile(uint16_t i, uint8_t t) {
Pokitto 63:7d1c08cdde5c 2498 if (!m_tilebuf) return;
Pokitto 63:7d1c08cdde5c 2499 m_tilebuf[i]=t;
Pokitto 63:7d1c08cdde5c 2500 };
Pokitto 63:7d1c08cdde5c 2501
Pokitto 63:7d1c08cdde5c 2502
Pokitto 63:7d1c08cdde5c 2503
Pokitto 63:7d1c08cdde5c 2504 // Convert an integer to a hexadecimal string
Pokitto 63:7d1c08cdde5c 2505 char* itoa_hex(int num, char* dest, int destLen) {
Pokitto 63:7d1c08cdde5c 2506 int i = destLen-1;
Pokitto 63:7d1c08cdde5c 2507 do {
Pokitto 63:7d1c08cdde5c 2508 char c = (num % 16) + '0';
Pokitto 63:7d1c08cdde5c 2509 if (c > '9') c += 7;
Pokitto 63:7d1c08cdde5c 2510 dest[i--] = c;
Pokitto 63:7d1c08cdde5c 2511 num /= 16;
Pokitto 63:7d1c08cdde5c 2512 } while (num && i >= 0);
Pokitto 63:7d1c08cdde5c 2513 return &(dest[i+1]);
Pokitto 63:7d1c08cdde5c 2514 }
Pokitto 63:7d1c08cdde5c 2515
Pokitto 63:7d1c08cdde5c 2516 // Draw the crash screen and wait forever
Pokitto 63:7d1c08cdde5c 2517 void ShowCrashScreenAndWait( const char* texLine1, const char* texLine2, const char* texLine3, const char* texLine4, const char* texLine5 ) {
Pokitto 63:7d1c08cdde5c 2518
Pokitto 63:7d1c08cdde5c 2519 // draw screen red
Pokitto 63:7d1c08cdde5c 2520 lcdFillSurface(COLOR_RED);
Pokitto 63:7d1c08cdde5c 2521
Pokitto 63:7d1c08cdde5c 2522 // Draw text
Pokitto 63:7d1c08cdde5c 2523 Display::directcolor = COLOR_WHITE;
Pokitto 63:7d1c08cdde5c 2524 Display::invisiblecolor = COLOR_RED;
Pokitto 63:7d1c08cdde5c 2525 Display::directbgcolor = COLOR_RED; // Cannot be black as that is a transparent color
Pokitto 63:7d1c08cdde5c 2526 Display::directtextrotated = false;
Pokitto 63:7d1c08cdde5c 2527 Display::adjustCharStep = 0;
Pokitto 63:7d1c08cdde5c 2528 Display::adjustLineStep = 0;
Pokitto 63:7d1c08cdde5c 2529 Display::setFont(fntC64UIGfx); // A special font set that contains UI gfx in lower case letters.
Pokitto 63:7d1c08cdde5c 2530 Display::fixedWidthFont = true; // Needed for the non-proportional C64 font (default value=false)
Pokitto 63:7d1c08cdde5c 2531 Display::enableDirectPrinting(true);
Pokitto 63:7d1c08cdde5c 2532
Pokitto 63:7d1c08cdde5c 2533 // Draw texts
Pokitto 63:7d1c08cdde5c 2534 int yOffsetInPixels = 5;
Pokitto 63:7d1c08cdde5c 2535 Display::set_cursor(0, 9 + yOffsetInPixels);
Pokitto 63:7d1c08cdde5c 2536 Display::print(" "); Display::println(texLine1);
Pokitto 63:7d1c08cdde5c 2537 Display::print(" "); Display::println(texLine2);
Pokitto 63:7d1c08cdde5c 2538 Display::print(" "); Display::println(texLine3);
Pokitto 63:7d1c08cdde5c 2539 Display::println();
Pokitto 63:7d1c08cdde5c 2540 Display::print(" *"); Display::println(texLine4);
Pokitto 63:7d1c08cdde5c 2541 Display::print(" *"); Display::println(texLine5);
Pokitto 63:7d1c08cdde5c 2542
Pokitto 63:7d1c08cdde5c 2543 Display::set_cursor(0, 0 + yOffsetInPixels);
Pokitto 63:7d1c08cdde5c 2544
Pokitto 63:7d1c08cdde5c 2545 // Frame
Pokitto 63:7d1c08cdde5c 2546 Display::println(" abbbbbbbbbbbbbbbbbbbbbbbbc");
Pokitto 63:7d1c08cdde5c 2547 Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
Pokitto 63:7d1c08cdde5c 2548 Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
Pokitto 63:7d1c08cdde5c 2549 Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
Pokitto 63:7d1c08cdde5c 2550 Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
Pokitto 63:7d1c08cdde5c 2551 Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
Pokitto 63:7d1c08cdde5c 2552 Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
Pokitto 63:7d1c08cdde5c 2553 Display::println(" dbbbzybbbbbbbbbbbbbbbbbbbe");
Pokitto 63:7d1c08cdde5c 2554 Display::println(" {e");
Pokitto 63:7d1c08cdde5c 2555
Pokitto 63:7d1c08cdde5c 2556 // Pokitto image
Pokitto 63:7d1c08cdde5c 2557 Display::println ("");
Pokitto 63:7d1c08cdde5c 2558 Display::println (" ijkl");
Pokitto 63:7d1c08cdde5c 2559 Display::println (" mnop");
Pokitto 63:7d1c08cdde5c 2560 Display::println (" qrst");
Pokitto 63:7d1c08cdde5c 2561 Display::println (" uvwx");
Pokitto 63:7d1c08cdde5c 2562
Pokitto 63:7d1c08cdde5c 2563 // loop forever
Pokitto 63:7d1c08cdde5c 2564 while(1){;}
Pokitto 63:7d1c08cdde5c 2565 }
Pokitto 63:7d1c08cdde5c 2566
Pokitto 63:7d1c08cdde5c 2567 // Check the stack size and show a crash screen if the stack is too big.
Pokitto 63:7d1c08cdde5c 2568 void CheckStack() {
Pokitto 63:7d1c08cdde5c 2569 #ifndef POK_SIM
Pokitto 63:7d1c08cdde5c 2570 #ifndef __ARMCC_VERSION
Pokitto 63:7d1c08cdde5c 2571 int currStackTop;
Pokitto 63:7d1c08cdde5c 2572 const int freeStackThreshold = 200;
Pokitto 63:7d1c08cdde5c 2573 if ((int)&currStackTop - (int)_ebss < freeStackThreshold) {
Pokitto 63:7d1c08cdde5c 2574
Pokitto 63:7d1c08cdde5c 2575 // Create info string: "<stack size>:<current stack pointer>", e.g. "12345ABC:12345ABC"
Pokitto 63:7d1c08cdde5c 2576 const int infoStringLen = 8+1+8;
Pokitto 63:7d1c08cdde5c 2577 static char infoString[infoStringLen+1];
Pokitto 63:7d1c08cdde5c 2578 memset(infoString,0,infoStringLen+1);
Pokitto 63:7d1c08cdde5c 2579 const int stackSize = (int)_vStackTop - (int)&currStackTop;
Pokitto 63:7d1c08cdde5c 2580 const int tmpStrLen = 8;
Pokitto 63:7d1c08cdde5c 2581 static char tmpStr[tmpStrLen+1];
Pokitto 63:7d1c08cdde5c 2582 memset(tmpStr,0,tmpStrLen+1);
Pokitto 63:7d1c08cdde5c 2583 char* subStr = itoa_hex(stackSize, tmpStr, tmpStrLen); // keep ending null
Pokitto 63:7d1c08cdde5c 2584 strcat(infoString, subStr); // Add stack size as hex string
Pokitto 63:7d1c08cdde5c 2585 strcat(infoString, ":");
Pokitto 63:7d1c08cdde5c 2586 subStr = itoa_hex((int)&currStackTop, tmpStr, tmpStrLen); // keep ending null
Pokitto 63:7d1c08cdde5c 2587 strcat(infoString, subStr); // Add stack pointer address as hex string
Pokitto 63:7d1c08cdde5c 2588
Pokitto 63:7d1c08cdde5c 2589 // Draw the crash screen and wait forever. Use static const strings to avoid more stack usage.
Pokitto 63:7d1c08cdde5c 2590 static const char* texLine1 = "OOPS! PLEASE, RESTART";
Pokitto 63:7d1c08cdde5c 2591 static const char* texLine2 = "POKITTO OR RELOAD";
Pokitto 63:7d1c08cdde5c 2592 static const char* texLine3 = "SOFTWARE.";
Pokitto 63:7d1c08cdde5c 2593 static const char* texLine4 = "STACK TOO BIG!";
Pokitto 63:7d1c08cdde5c 2594 ShowCrashScreenAndWait(texLine1, texLine2, texLine3, texLine4, infoString);
Pokitto 63:7d1c08cdde5c 2595 }
Pokitto 63:7d1c08cdde5c 2596 #endif
Pokitto 63:7d1c08cdde5c 2597 #endif
Pokitto 63:7d1c08cdde5c 2598 }
Pokitto 63:7d1c08cdde5c 2599
Pokitto 63:7d1c08cdde5c 2600 /** Eof */
Pokitto 63:7d1c08cdde5c 2601
Pokitto 63:7d1c08cdde5c 2602
Pokitto 63:7d1c08cdde5c 2603
Pokitto 63:7d1c08cdde5c 2604