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

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

PokittoLib

Library for programming Pokitto hardware

How to Use

  1. Import this library to online compiler (see button "import" on the right hand side
  2. DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
  3. Change My_settings.h according to your project
  4. Start coding!
Committer:
Pokitto
Date:
Wed Dec 25 23:59:52 2019 +0000
Revision:
71:531419862202
Parent:
69:f9f49ff29720
Changed Mode2 C++ refresh code (graphical errors)

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