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:
Sat Mar 23 19:19:23 2019 +0000
Revision:
64:1d52d8287c39
Parent:
60:8b6a110feeea
Mode 15 support added

Who changed what in which revision?

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