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