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:
Tue May 01 18:42:46 2018 +0000
Revision:
42:798b5d67b372
Parent:
35:4f7edccf8ed6
New volume control;

Who changed what in which revision?

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