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 Oct 07 10:19:52 2018 +0000
Revision:
60:8b6a110feeea
Parent:
52:c04087025cab
Child:
64:1d52d8287c39
Rid of all warnings on build all

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 60:8b6a110feeea 535 if ((bgcolor>>1) & 0x1) memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME),0xFF,j);// G
Pokitto 60:8b6a110feeea 536 else memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME),0x00,j);// G
Pokitto 60:8b6a110feeea 537 if ((bgcolor>>2) & 0x1) memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME*2),0xFF,j);// B
Pokitto 60:8b6a110feeea 538 else memset((void*)((uint8_t*)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 60:8b6a110feeea 1495 int16_t i, j, byteNum, 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
Pokitto 52:c04087025cab 1500 uint8_t bitcount=0;
Pokitto 52:c04087025cab 1501 for (j = 0; j <= h/8; j++) {
Pokitto 52:c04087025cab 1502 uint8_t r_val = *(bitmap + j * byteWidth + byteNum);
Pokitto 52:c04087025cab 1503 uint8_t g_val = *(bitmap + bitFrame + j * byteWidth + byteNum);
Pokitto 52:c04087025cab 1504 uint8_t b_val = *(bitmap + (bitFrame<<1) + j * byteWidth + byteNum);
Pokitto 52:c04087025cab 1505 for (bitcount=0; bitcount<8; bitcount++) {
Pokitto 52:c04087025cab 1506 uint8_t col = (r_val&0x1) | ((g_val&0x1)<<1) | ((b_val&0x1)<<2);
Pokitto 52:c04087025cab 1507 r_val >>= 1; g_val >>= 1; b_val >>= 1;
Pokitto 52:c04087025cab 1508 drawPixel(x + i, y + j+bitcount,col);
Pokitto 52:c04087025cab 1509 }
Pokitto 52:c04087025cab 1510 }
Pokitto 52:c04087025cab 1511 }
Pokitto 52:c04087025cab 1512
Pokitto 52:c04087025cab 1513 return;
Pokitto 52:c04087025cab 1514 }
Pokitto 52:c04087025cab 1515
Pokitto 52:c04087025cab 1516
Pokitto 52:c04087025cab 1517 /** 4bpp fast version */
Pokitto 52:c04087025cab 1518 else if (m_colordepth==4) {
Pokitto 52:c04087025cab 1519
Pokitto 52:c04087025cab 1520 /** 4bpp fast version */
Pokitto 52:c04087025cab 1521 int16_t scrx,scry,xclip,xjump,scrxjump;
Pokitto 52:c04087025cab 1522 xclip=xjump=scrxjump=0;
Pokitto 52:c04087025cab 1523 /** y clipping */
Pokitto 52:c04087025cab 1524 if (y<0) { h+=y; bitmap -= y*(w>>1); y=0;}
Pokitto 52:c04087025cab 1525 else if (y+h>height) { h -=(y-height);}
Pokitto 52:c04087025cab 1526 /** x clipping */
Pokitto 52:c04087025cab 1527 if (x<0) { xclip=(x&1)<<1; w+=x; xjump = ((-x)>>1); bitmap += xjump; x=0;}
Pokitto 52:c04087025cab 1528 else if (x+w>width) {
Pokitto 52:c04087025cab 1529 xclip = (x&1)<<1;
Pokitto 52:c04087025cab 1530 scrxjump = x&1;
Pokitto 52:c04087025cab 1531 xjump=((x+w-width)>>1)+scrxjump;
Pokitto 52:c04087025cab 1532 w = width-x;}
Pokitto 52:c04087025cab 1533
Pokitto 52:c04087025cab 1534 uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
Pokitto 52:c04087025cab 1535 /** ONLY 4-bit mode for time being **/
Pokitto 52:c04087025cab 1536 for (scry = y; scry < y+h; scry+=1) {
Pokitto 52:c04087025cab 1537 if (scry>=height) return;
Pokitto 52:c04087025cab 1538 if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
Pokitto 52:c04087025cab 1539 for (scrx = x; scrx < w+x-xclip; scrx+=2) {
Pokitto 52:c04087025cab 1540 uint8_t sourcepixel = *bitmap;
Pokitto 52:c04087025cab 1541 if (xclip) {
Pokitto 52:c04087025cab 1542 sourcepixel <<=4;
Pokitto 52:c04087025cab 1543 sourcepixel |= ((*(bitmap+1))>>4);
Pokitto 52:c04087025cab 1544 }
Pokitto 52:c04087025cab 1545 uint8_t targetpixel = *scrptr;
Pokitto 52:c04087025cab 1546 if ((sourcepixel>>4) != invisiblecolor ) targetpixel = (targetpixel&0x0F) | (sourcepixel & 0xF0);
Pokitto 52:c04087025cab 1547 if ((sourcepixel&0x0F) != invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel & 0x0F);
Pokitto 52:c04087025cab 1548 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1549 bitmap++;
Pokitto 52:c04087025cab 1550 scrptr++;
Pokitto 52:c04087025cab 1551 }
Pokitto 52:c04087025cab 1552 if (xclip){
Pokitto 52:c04087025cab 1553 if (w&1) {
Pokitto 52:c04087025cab 1554 /**last pixel is odd pixel due to clipping & odd width*/
Pokitto 52:c04087025cab 1555 uint8_t sourcepixel = *bitmap;
Pokitto 52:c04087025cab 1556 if ((sourcepixel&0x0F) != invisiblecolor) {
Pokitto 52:c04087025cab 1557 sourcepixel <<=4;
Pokitto 52:c04087025cab 1558 uint8_t targetpixel = *scrptr;// & 0x0F;
Pokitto 52:c04087025cab 1559 targetpixel |= sourcepixel;
Pokitto 52:c04087025cab 1560 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1561 }
Pokitto 52:c04087025cab 1562 //scrptr++;
Pokitto 52:c04087025cab 1563 }
Pokitto 52:c04087025cab 1564 bitmap++;
Pokitto 52:c04087025cab 1565 scrptr++;
Pokitto 52:c04087025cab 1566 }
Pokitto 52:c04087025cab 1567 bitmap += xjump; // needed if x<0 clipping occurs
Pokitto 52:c04087025cab 1568 } else { /** ODD pixel starting line **/
Pokitto 52:c04087025cab 1569 for (scrx = x; scrx < w+x-xclip; scrx+=2) {
Pokitto 52:c04087025cab 1570 uint8_t sourcepixel = *bitmap;
Pokitto 52:c04087025cab 1571 uint8_t targetpixel = *scrptr;
Pokitto 52:c04087025cab 1572 // store higher nibble of source pixel in lower nibble of target
Pokitto 52:c04087025cab 1573 if((sourcepixel>>4)!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel >> 4 );
Pokitto 52:c04087025cab 1574 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1575 scrptr++;
Pokitto 52:c04087025cab 1576 targetpixel = *scrptr;
Pokitto 52:c04087025cab 1577 // store lower nibble of source pixel in higher nibble of target
Pokitto 52:c04087025cab 1578 if((sourcepixel&0x0F)!=invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel << 4);
Pokitto 52:c04087025cab 1579 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1580 bitmap++;
Pokitto 52:c04087025cab 1581 }
Pokitto 52:c04087025cab 1582 bitmap+=xjump;
Pokitto 52:c04087025cab 1583 }
Pokitto 52:c04087025cab 1584 // increment the y jump in the scrptr
Pokitto 52:c04087025cab 1585 scrptr = scrptr + ((width - w)>>1)+scrxjump;
Pokitto 52:c04087025cab 1586 }
Pokitto 52:c04087025cab 1587
Pokitto 52:c04087025cab 1588 return;
Pokitto 52:c04087025cab 1589 }
Pokitto 52:c04087025cab 1590
Pokitto 52:c04087025cab 1591 /** 4bpp fast version */
Pokitto 52:c04087025cab 1592
Pokitto 52:c04087025cab 1593 if (m_colordepth==8) {
Pokitto 60:8b6a110feeea 1594 int16_t scrx,scry,xjump,scrxjump;
Pokitto 60:8b6a110feeea 1595 xjump=scrxjump=0;
Pokitto 52:c04087025cab 1596 /** y clipping */
Pokitto 52:c04087025cab 1597 if (y<0) { h+=y; bitmap -= y*w; y=0;}
Pokitto 52:c04087025cab 1598 else if (y+h>height) { h -=(y-height);}
Pokitto 52:c04087025cab 1599 /** x clipping */
Pokitto 60:8b6a110feeea 1600 if (x<0) { w+=x; xjump = (-x); bitmap += xjump; x=0;}
Pokitto 52:c04087025cab 1601 else if (x+w>width) {
Pokitto 52:c04087025cab 1602 scrxjump = x;
Pokitto 52:c04087025cab 1603 xjump=(x+w-width)+scrxjump;
Pokitto 52:c04087025cab 1604 w = width-x;}
Pokitto 52:c04087025cab 1605
Pokitto 52:c04087025cab 1606 uint8_t* scrptr = m_scrbuf + (y*width + x);
Pokitto 52:c04087025cab 1607 for (scry = y; scry < y+h; scry+=1) {
Pokitto 52:c04087025cab 1608 if (scry>=height) return;
Pokitto 52:c04087025cab 1609 for (scrx = x; scrx < w+x; scrx++) {
Pokitto 52:c04087025cab 1610 uint8_t sourcepixel = *bitmap;
Pokitto 52:c04087025cab 1611 uint8_t targetpixel = *scrptr;
Pokitto 52:c04087025cab 1612 if (sourcepixel != invisiblecolor ) targetpixel = sourcepixel;
Pokitto 52:c04087025cab 1613 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1614 bitmap++;
Pokitto 52:c04087025cab 1615 scrptr++;
Pokitto 52:c04087025cab 1616 }
Pokitto 52:c04087025cab 1617 bitmap += xjump; // needed if x<0 clipping occurs
Pokitto 52:c04087025cab 1618 scrptr = scrptr + (width - w)+scrxjump;
Pokitto 52:c04087025cab 1619 }
Pokitto 52:c04087025cab 1620 return;
Pokitto 52:c04087025cab 1621 }
Pokitto 52:c04087025cab 1622
Pokitto 52:c04087025cab 1623
Pokitto 52:c04087025cab 1624 }
Pokitto 52:c04087025cab 1625
Pokitto 52:c04087025cab 1626 void Display::drawRleBitmap(int16_t x, int16_t y, const uint8_t* rlebitmap)
Pokitto 52:c04087025cab 1627 {
Pokitto 52:c04087025cab 1628 // ONLY can copy 4-bit bitmap to 4-bit screen mode for time being
Pokitto 52:c04087025cab 1629 #if (POK_SCREENMODE != MODE_FAST_16COLOR)
Pokitto 52:c04087025cab 1630 return;
Pokitto 52:c04087025cab 1631 #endif
Pokitto 52:c04087025cab 1632
Pokitto 52:c04087025cab 1633 int16_t w = *rlebitmap;
Pokitto 52:c04087025cab 1634 int16_t h = *(rlebitmap + 1);
Pokitto 52:c04087025cab 1635 rlebitmap = rlebitmap + 2; //add an offset to the pointer to start after the width and height
Pokitto 52:c04087025cab 1636
Pokitto 52:c04087025cab 1637 // visibility check
Pokitto 52:c04087025cab 1638 if (y<-h || y>height) return; //invisible
Pokitto 52:c04087025cab 1639 if (x<-w || x>width) return; //invisible
Pokitto 52:c04087025cab 1640
Pokitto 52:c04087025cab 1641 // Clipping is not supported
Pokitto 52:c04087025cab 1642 if ((x < 0) || (x+w > width) || (y < 0) || (y+h > height)) return;
Pokitto 52:c04087025cab 1643
Pokitto 52:c04087025cab 1644 // Currently only support RLE bitmaps in 16 color mode.
Pokitto 52:c04087025cab 1645 if (m_colordepth != 4) //
Pokitto 52:c04087025cab 1646 return;
Pokitto 52:c04087025cab 1647
Pokitto 52:c04087025cab 1648 // Go through each line.
Pokitto 52:c04087025cab 1649 uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
Pokitto 52:c04087025cab 1650 bool is_endofbitmap = false;
Pokitto 52:c04087025cab 1651 for (int16_t scry = y; scry < y+h && !is_endofbitmap;) {
Pokitto 52:c04087025cab 1652
Pokitto 52:c04087025cab 1653 // Process one line. Go through each pixel run and escape command in RLE data.
Pokitto 52:c04087025cab 1654 for (int16_t scrx = x;;) {
Pokitto 52:c04087025cab 1655 uint8_t rle_count = *rlebitmap++;
Pokitto 52:c04087025cab 1656
Pokitto 52:c04087025cab 1657 if (rle_count == 0) {
Pokitto 52:c04087025cab 1658
Pokitto 52:c04087025cab 1659 /* Escape or absolute mode */
Pokitto 52:c04087025cab 1660
Pokitto 52:c04087025cab 1661 uint8_t rle_escape_or_runsize = *rlebitmap++;
Pokitto 52:c04087025cab 1662 if ( rle_escape_or_runsize == RLE_ESC_EOL) {
Pokitto 52:c04087025cab 1663 // End of line.
Pokitto 52:c04087025cab 1664 break;
Pokitto 52:c04087025cab 1665 }
Pokitto 52:c04087025cab 1666 else if ( rle_escape_or_runsize == RLE_ESC_EOB) {
Pokitto 52:c04087025cab 1667 // End of bitmap.
Pokitto 52:c04087025cab 1668 is_endofbitmap = true;
Pokitto 52:c04087025cab 1669 break;
Pokitto 52:c04087025cab 1670 }
Pokitto 52:c04087025cab 1671 else if ( rle_escape_or_runsize == RLE_ESC_OFFSET) {
Pokitto 52:c04087025cab 1672 // Move position in target.
Pokitto 52:c04087025cab 1673 // TODO: not tested yet.
Pokitto 52:c04087025cab 1674 uint8_t xoffset = *rlebitmap++;
Pokitto 52:c04087025cab 1675 uint8_t yoffset = *rlebitmap++;
Pokitto 52:c04087025cab 1676 scrptr += (xoffset>1);
Pokitto 52:c04087025cab 1677 scrx += xoffset;
Pokitto 52:c04087025cab 1678 scrptr += yoffset*width;
Pokitto 52:c04087025cab 1679 scry += yoffset;
Pokitto 52:c04087025cab 1680 }
Pokitto 52:c04087025cab 1681 else {
Pokitto 52:c04087025cab 1682
Pokitto 52:c04087025cab 1683 /* Absolute mode. Copy pixels from the source bitmap to the target screen. */
Pokitto 52:c04087025cab 1684
Pokitto 52:c04087025cab 1685 int16_t runsize = rle_escape_or_runsize;
Pokitto 52:c04087025cab 1686 uint8_t targetpixel = *scrptr; // initial value
Pokitto 52:c04087025cab 1687 uint8_t sourcepixel = *rlebitmap; // initial value
Pokitto 52:c04087025cab 1688 for( int16_t runx = 0; runx < runsize; ) {
Pokitto 52:c04087025cab 1689 if (scrx&0x1) { // screen pixel is in the low nibble
Pokitto 52:c04087025cab 1690 if (runx&0x1) { // bitmap pixel is in the low nibble
Pokitto 52:c04087025cab 1691 if ((sourcepixel&0x0F) != invisiblecolor)
Pokitto 52:c04087025cab 1692 targetpixel = (targetpixel&0xF0) | (sourcepixel&0x0F); // Copy low to low nibble.
Pokitto 52:c04087025cab 1693 rlebitmap++;
Pokitto 52:c04087025cab 1694 }
Pokitto 52:c04087025cab 1695 else // bitmap pixel is in the high nibble
Pokitto 52:c04087025cab 1696 if ((sourcepixel>>4) != invisiblecolor)
Pokitto 52:c04087025cab 1697 targetpixel = (targetpixel&0xF0) | (sourcepixel>>4); // Copy high to low nibble.
Pokitto 52:c04087025cab 1698
Pokitto 52:c04087025cab 1699 // Copy the byte to the target.
Pokitto 52:c04087025cab 1700 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1701 scrptr++;
Pokitto 52:c04087025cab 1702 }
Pokitto 52:c04087025cab 1703 else { // screen pixel is in the high nibble
Pokitto 52:c04087025cab 1704 targetpixel = *scrptr;
Pokitto 52:c04087025cab 1705 sourcepixel = *rlebitmap;
Pokitto 52:c04087025cab 1706 if (runx&0x1) { // bitmap pixel is sourcepixel = *rlebitmapin the low nibble
Pokitto 52:c04087025cab 1707 if ((sourcepixel&0x0F) != invisiblecolor )
Pokitto 52:c04087025cab 1708 targetpixel = (targetpixel&0x0F) | ((sourcepixel<<4)&0xF0); // Copy low to high nibble.
Pokitto 52:c04087025cab 1709 rlebitmap++; // read the new source byte
Pokitto 52:c04087025cab 1710 }
Pokitto 52:c04087025cab 1711 else // bitmap pixel is in the high nibble
Pokitto 52:c04087025cab 1712 if ((sourcepixel>>4) != invisiblecolor )
Pokitto 52:c04087025cab 1713 targetpixel = (targetpixel&0x0F) | (sourcepixel&0xF0); // Copy high to high nibble.
Pokitto 52:c04087025cab 1714 }
Pokitto 52:c04087025cab 1715 runx++;
Pokitto 52:c04087025cab 1716 scrx++;
Pokitto 52:c04087025cab 1717 } // end for
Pokitto 52:c04087025cab 1718
Pokitto 52:c04087025cab 1719 // If this is odd target index, copy the byte to the target.
Pokitto 52:c04087025cab 1720 if (scrx&0x1) {
Pokitto 52:c04087025cab 1721 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1722 scrptr++;
Pokitto 52:c04087025cab 1723 }
Pokitto 52:c04087025cab 1724
Pokitto 52:c04087025cab 1725 // In absolute mode the source size is always padded to the word boundary.
Pokitto 52:c04087025cab 1726 if (runsize%4) {
Pokitto 52:c04087025cab 1727 int16_t padpixcount = 4 - (runsize%4);
Pokitto 52:c04087025cab 1728 rlebitmap += padpixcount>>1; // skip n padding bytes
Pokitto 52:c04087025cab 1729 }
Pokitto 52:c04087025cab 1730 }
Pokitto 52:c04087025cab 1731 }
Pokitto 52:c04087025cab 1732 else {
Pokitto 52:c04087025cab 1733
Pokitto 52:c04087025cab 1734 /* Encoded mode. Duplicate one pixel pair to the all required pixels on the target screen */
Pokitto 52:c04087025cab 1735
Pokitto 52:c04087025cab 1736 int16_t runsize = rle_count;
Pokitto 52:c04087025cab 1737 uint8_t clonepixelpair = *rlebitmap++;
Pokitto 52:c04087025cab 1738 uint8_t targetpixel = *scrptr; // initial value
Pokitto 52:c04087025cab 1739 for( int16_t runx = 0; runx < runsize; ) {
Pokitto 52:c04087025cab 1740 if (scrx&0x1) { // screen pixel is in the low nibble
Pokitto 52:c04087025cab 1741 if (runx&0x1) { // bitmap pixel is in the low nibble
Pokitto 52:c04087025cab 1742 if ((clonepixelpair&0x0F) != invisiblecolor)
Pokitto 52:c04087025cab 1743 targetpixel = (targetpixel&0xF0) | (clonepixelpair&0x0F); // Copy low to low nibble.
Pokitto 52:c04087025cab 1744 }
Pokitto 52:c04087025cab 1745 else // bitmap pixel is in the high nibble
Pokitto 52:c04087025cab 1746 if ((clonepixelpair>>4) != invisiblecolor)
Pokitto 52:c04087025cab 1747 targetpixel = (targetpixel&0xF0) | (clonepixelpair>>4); // Copy high to low nibble.
Pokitto 52:c04087025cab 1748
Pokitto 52:c04087025cab 1749 // Copy the byte to the target.
Pokitto 52:c04087025cab 1750 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1751 scrptr++;
Pokitto 52:c04087025cab 1752 }
Pokitto 52:c04087025cab 1753 else { // screen pixel is in the high nibble
Pokitto 52:c04087025cab 1754 targetpixel = *scrptr;
Pokitto 52:c04087025cab 1755 if (runx&0x1) {// bitmap pixel is in the low nibble
Pokitto 52:c04087025cab 1756 if ((clonepixelpair&0x0F) != invisiblecolor )
Pokitto 52:c04087025cab 1757 targetpixel = (targetpixel&0x0F) | ((clonepixelpair<<4)&0xF0); // Copy low to high nibble.
Pokitto 52:c04087025cab 1758 }
Pokitto 52:c04087025cab 1759 else // bitmap pixel is in the high nibble
Pokitto 52:c04087025cab 1760 if ((clonepixelpair>>4) != invisiblecolor )
Pokitto 52:c04087025cab 1761 targetpixel = (targetpixel&0x0F) | (clonepixelpair&0xF0); // Copy high to high nibble.
Pokitto 52:c04087025cab 1762 }
Pokitto 52:c04087025cab 1763 runx++;
Pokitto 52:c04087025cab 1764 scrx++;
Pokitto 52:c04087025cab 1765
Pokitto 52:c04087025cab 1766 } // end for
Pokitto 52:c04087025cab 1767
Pokitto 52:c04087025cab 1768 // If this is odd target index, copy the byte to the target.
Pokitto 52:c04087025cab 1769 if (scrx&0x1) {
Pokitto 52:c04087025cab 1770 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1771 scrptr++;
Pokitto 52:c04087025cab 1772 }
Pokitto 52:c04087025cab 1773 } // end if
Pokitto 52:c04087025cab 1774 } // end while
Pokitto 52:c04087025cab 1775
Pokitto 52:c04087025cab 1776 // Increment the target screen pointer and index.
Pokitto 52:c04087025cab 1777 scrptr = scrptr + ((width - w)>>1);
Pokitto 52:c04087025cab 1778 scry++;
Pokitto 52:c04087025cab 1779 } // end for scry
Pokitto 52:c04087025cab 1780 }
Pokitto 52:c04087025cab 1781
Pokitto 52:c04087025cab 1782 void Display::drawBitmapXFlipped(int16_t x, int16_t y, const uint8_t* bitmap)
Pokitto 52:c04087025cab 1783 {
Pokitto 52:c04087025cab 1784 int16_t w = *bitmap;
Pokitto 52:c04087025cab 1785 int16_t h = *(bitmap + 1);
Pokitto 52:c04087025cab 1786 bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
Pokitto 52:c04087025cab 1787 /** visibility check */
Pokitto 52:c04087025cab 1788 if (y<-h || y>height) return; //invisible
Pokitto 52:c04087025cab 1789 if (x<-w || x>width) return; //invisible
Pokitto 52:c04087025cab 1790 /** 1 bpp mode */
Pokitto 52:c04087025cab 1791 if (m_colordepth<2) {
Pokitto 52:c04087025cab 1792 int16_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 52:c04087025cab 1793 for (i = 0; i < w; i++) {
Pokitto 52:c04087025cab 1794 byteNum = i / 8;
Pokitto 52:c04087025cab 1795 bitNum = i % 8;
Pokitto 52:c04087025cab 1796 for (j = 0; j < h; j++) {
Pokitto 52:c04087025cab 1797 uint8_t source = *(bitmap + j * byteWidth + byteNum);
Pokitto 52:c04087025cab 1798 if (source & (0x80 >> bitNum)) {
Pokitto 52:c04087025cab 1799 drawPixel(x + w - i, y + j);
Pokitto 52:c04087025cab 1800 }
Pokitto 52:c04087025cab 1801 }
Pokitto 52:c04087025cab 1802 }
Pokitto 52:c04087025cab 1803
Pokitto 52:c04087025cab 1804 return;
Pokitto 52:c04087025cab 1805 }
Pokitto 52:c04087025cab 1806 /** 2 bpp mode */
Pokitto 52:c04087025cab 1807 if (m_colordepth<4) {
Pokitto 52:c04087025cab 1808 int16_t i, j, byteNum, bitNum, byteWidth = w >> 2;
Pokitto 52:c04087025cab 1809 for (i = 0; i < w; i++) {
Pokitto 52:c04087025cab 1810 byteNum = i / 4;
Pokitto 52:c04087025cab 1811 bitNum = (i % 4)<<1;
Pokitto 52:c04087025cab 1812 for (j = 0; j < h; j++) {
Pokitto 52:c04087025cab 1813 uint8_t source = *(bitmap + j * byteWidth + byteNum);
Pokitto 52:c04087025cab 1814 uint8_t output = (source & (0xC0 >> bitNum));
Pokitto 52:c04087025cab 1815 output >>= (6-bitNum);
Pokitto 52:c04087025cab 1816 if (output != invisiblecolor) {
Pokitto 52:c04087025cab 1817 setColor(output);
Pokitto 52:c04087025cab 1818 drawPixel(x + i, y + j);
Pokitto 52:c04087025cab 1819 }
Pokitto 52:c04087025cab 1820 }
Pokitto 52:c04087025cab 1821 }
Pokitto 52:c04087025cab 1822
Pokitto 52:c04087025cab 1823 return;
Pokitto 52:c04087025cab 1824 }
Pokitto 52:c04087025cab 1825 /** 4bpp fast version */
Pokitto 52:c04087025cab 1826 int16_t scrx,scry,xclip,xjump,scrxjump;
Pokitto 52:c04087025cab 1827 xclip=xjump=scrxjump=0;
Pokitto 52:c04087025cab 1828 /** y clipping */
Pokitto 52:c04087025cab 1829 if (y<0) { h+=y; bitmap -= y*(w>>1); y=0;}
Pokitto 52:c04087025cab 1830 else if (y+h>height) { h -=(y-height);}
Pokitto 52:c04087025cab 1831 /** x clipping */
Pokitto 52:c04087025cab 1832 bitmap += ((w>>1)-1); //inverted!
Pokitto 52:c04087025cab 1833 if (x<0) {
Pokitto 52:c04087025cab 1834 xclip=(x&1)<<1;
Pokitto 52:c04087025cab 1835 w+=x;
Pokitto 52:c04087025cab 1836 xjump = ((-x)>>1);
Pokitto 52:c04087025cab 1837 //bitmap += xjump; // do not clip left edge of source, as bitmap is inverted !
Pokitto 52:c04087025cab 1838 x=0;
Pokitto 52:c04087025cab 1839 }
Pokitto 52:c04087025cab 1840 else if (x+w>width) {
Pokitto 52:c04087025cab 1841 xclip = (x&1)<<1;
Pokitto 52:c04087025cab 1842 scrxjump = x&1;
Pokitto 52:c04087025cab 1843 xjump=((x+w-width)>>1)+scrxjump;
Pokitto 52:c04087025cab 1844 w = width-x;}
Pokitto 52:c04087025cab 1845
Pokitto 52:c04087025cab 1846 //uint8_t* scrptr = m_scrbuf + (y*(width>>1) + ((x+width)>>1));
Pokitto 52:c04087025cab 1847 uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
Pokitto 52:c04087025cab 1848 /** ONLY 4-bit mode for time being **/
Pokitto 52:c04087025cab 1849 for (scry = y; scry < y+h; scry+=1) {
Pokitto 52:c04087025cab 1850 // for (scry = y; scry < y+2; scry+=1) {
Pokitto 52:c04087025cab 1851 if (scry>=height) return;
Pokitto 52:c04087025cab 1852 if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
Pokitto 52:c04087025cab 1853 //for (scrx = w+x-xclip-1; scrx >= x; scrx-=2) {
Pokitto 52:c04087025cab 1854 for (scrx = x; scrx < w+x-xclip; scrx+=2) {
Pokitto 52:c04087025cab 1855 uint8_t sourcepixel = *(bitmap);
Pokitto 52:c04087025cab 1856 if (xclip) {
Pokitto 52:c04087025cab 1857 sourcepixel <<=4;
Pokitto 52:c04087025cab 1858 sourcepixel |= ((*(bitmap-1))>>4);//inverted!
Pokitto 52:c04087025cab 1859 }
Pokitto 52:c04087025cab 1860 uint8_t targetpixel = *scrptr;
Pokitto 52:c04087025cab 1861 // NIBBLES ARE INVERTED BECAUSE PICTURE IS FLIPPED !!!
Pokitto 52:c04087025cab 1862 if ((sourcepixel>>4) != invisiblecolor ) targetpixel = (targetpixel&0xF0) | (sourcepixel>>4);
Pokitto 52:c04087025cab 1863 if ((sourcepixel&0x0F) != invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel<<4);
Pokitto 52:c04087025cab 1864 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1865 bitmap--;
Pokitto 52:c04087025cab 1866 scrptr++;
Pokitto 52:c04087025cab 1867 }
Pokitto 52:c04087025cab 1868 bitmap += w; // w*2 >> 1 because inverted and because 2 pixels per byte!!
Pokitto 52:c04087025cab 1869 if (xclip){
Pokitto 52:c04087025cab 1870 if (w&1) {
Pokitto 52:c04087025cab 1871 /**last pixel is odd pixel due to clipping & odd width*/
Pokitto 52:c04087025cab 1872 uint8_t sourcepixel = *bitmap;
Pokitto 52:c04087025cab 1873 if ((sourcepixel&0x0F) != invisiblecolor) {
Pokitto 52:c04087025cab 1874 sourcepixel <<=4;
Pokitto 52:c04087025cab 1875 uint8_t targetpixel = *scrptr;// & 0x0F;
Pokitto 52:c04087025cab 1876 targetpixel |= sourcepixel;
Pokitto 52:c04087025cab 1877 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1878 }
Pokitto 52:c04087025cab 1879 //scrptr++;
Pokitto 52:c04087025cab 1880 }
Pokitto 52:c04087025cab 1881 bitmap++;
Pokitto 52:c04087025cab 1882 scrptr++;
Pokitto 52:c04087025cab 1883 }
Pokitto 52:c04087025cab 1884 bitmap += xjump; // needed if x<0 clipping occurs
Pokitto 52:c04087025cab 1885 } else { /** ODD pixel starting line **/
Pokitto 52:c04087025cab 1886 for (scrx = x; scrx < w+x-xclip; scrx+=2 ) {
Pokitto 52:c04087025cab 1887 uint8_t sourcepixel = *bitmap;
Pokitto 52:c04087025cab 1888 uint8_t targetpixel = *scrptr;
Pokitto 52:c04087025cab 1889 // inverted !!! store lower nibble of source pixel in lower nibble of target
Pokitto 52:c04087025cab 1890 if((sourcepixel&0x0F)!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel & 0x0F );
Pokitto 52:c04087025cab 1891 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1892 scrptr++;
Pokitto 52:c04087025cab 1893 targetpixel = *scrptr;
Pokitto 52:c04087025cab 1894 // inverted ! store higher nibble of source pixel in higher nibble of target
Pokitto 52:c04087025cab 1895 if((sourcepixel>>4)!=invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel & 0xF0);
Pokitto 52:c04087025cab 1896 *scrptr = targetpixel;
Pokitto 52:c04087025cab 1897 bitmap--;
Pokitto 52:c04087025cab 1898 }
Pokitto 52:c04087025cab 1899 bitmap += w; // w*2 >> 1 because inverted and because 2 pixels per byte!!
Pokitto 52:c04087025cab 1900 bitmap+=xjump;
Pokitto 52:c04087025cab 1901 }
Pokitto 52:c04087025cab 1902 // increment the y jump in the scrptr
Pokitto 52:c04087025cab 1903 scrptr = scrptr + ((width - w)>>1)+scrxjump;
Pokitto 52:c04087025cab 1904 }
Pokitto 52:c04087025cab 1905 }
Pokitto 52:c04087025cab 1906
Pokitto 52:c04087025cab 1907 void Display::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t rotation, uint8_t flip) {
Pokitto 52:c04087025cab 1908 #if PROJ_GAMEBUINO == 0
Pokitto 52:c04087025cab 1909 if (!flip) drawBitmap(x,y,bitmap);
Pokitto 52:c04087025cab 1910 else drawBitmapXFlipped(x,y,bitmap);
Pokitto 52:c04087025cab 1911 #else
Pokitto 52:c04087025cab 1912 if((rotation == NOROT) && (flip == NOFLIP)){
Pokitto 52:c04087025cab 1913 drawBitmap(x,y,bitmap); //use the faster algorithm
Pokitto 52:c04087025cab 1914 return;
Pokitto 52:c04087025cab 1915 }
Pokitto 52:c04087025cab 1916 uint8_t w = bitmap[0];
Pokitto 52:c04087025cab 1917 uint8_t h = bitmap[1];
Pokitto 52:c04087025cab 1918 bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
Pokitto 52:c04087025cab 1919 int8_t i, j, //coordinates in the raw bitmap
Pokitto 52:c04087025cab 1920 k, l, //coordinates in the rotated/flipped bitmap
Pokitto 52:c04087025cab 1921 byteNum, bitNum, byteWidth = (w + 7) >> 3;
Pokitto 52:c04087025cab 1922
Pokitto 52:c04087025cab 1923 rotation %= 4;
Pokitto 52:c04087025cab 1924
Pokitto 52:c04087025cab 1925 for (i = 0; i < w; i++) {
Pokitto 52:c04087025cab 1926 byteNum = i / 8;
Pokitto 52:c04087025cab 1927 bitNum = i % 8;
Pokitto 52:c04087025cab 1928 for (j = 0; j < h; j++) {
Pokitto 52:c04087025cab 1929 if (bitmap[j * byteWidth + byteNum] & (B10000000 >> bitNum)) {
Pokitto 52:c04087025cab 1930 switch (rotation) {
Pokitto 52:c04087025cab 1931 case NOROT: //no rotation
Pokitto 52:c04087025cab 1932 k = i;
Pokitto 52:c04087025cab 1933 l = j;
Pokitto 52:c04087025cab 1934 break;
Pokitto 52:c04087025cab 1935 case ROTCCW: //90° counter-clockwise
Pokitto 52:c04087025cab 1936 k = j;
Pokitto 52:c04087025cab 1937 l = w - i - 1;
Pokitto 52:c04087025cab 1938 break;
Pokitto 52:c04087025cab 1939 case ROT180: //180°
Pokitto 52:c04087025cab 1940 k = w - i - 1;
Pokitto 52:c04087025cab 1941 l = h - j - 1;
Pokitto 52:c04087025cab 1942 break;
Pokitto 52:c04087025cab 1943 case ROTCW: //90° clockwise
Pokitto 52:c04087025cab 1944 k = h - j - 1;
Pokitto 52:c04087025cab 1945 l = i;
Pokitto 52:c04087025cab 1946 break;
Pokitto 52:c04087025cab 1947 }
Pokitto 52:c04087025cab 1948 if (flip) {
Pokitto 52:c04087025cab 1949 flip %= 4;
Pokitto 52:c04087025cab 1950 if (flip & B00000001) { //horizontal flip
Pokitto 52:c04087025cab 1951 k = w - k;
Pokitto 52:c04087025cab 1952 }
Pokitto 52:c04087025cab 1953 if (flip & B00000010) { //vertical flip
Pokitto 52:c04087025cab 1954 l = h - l;
Pokitto 52:c04087025cab 1955 }
Pokitto 52:c04087025cab 1956 }
Pokitto 52:c04087025cab 1957 k += x; //place the bitmap on the screen
Pokitto 52:c04087025cab 1958 l += y;
Pokitto 52:c04087025cab 1959 drawPixel(k, l);
Pokitto 52:c04087025cab 1960 }
Pokitto 52:c04087025cab 1961 }
Pokitto 52:c04087025cab 1962 }
Pokitto 52:c04087025cab 1963 #endif //PROJ_GAMEBUINO
Pokitto 52:c04087025cab 1964
Pokitto 52:c04087025cab 1965 }
Pokitto 52:c04087025cab 1966
Pokitto 52:c04087025cab 1967 uint8_t* Display::getBuffer() {
Pokitto 52:c04087025cab 1968 return m_scrbuf;
Pokitto 52:c04087025cab 1969 }
Pokitto 52:c04087025cab 1970
Pokitto 52:c04087025cab 1971 uint8_t Display::getBitmapPixel(const uint8_t* bitmap, uint16_t x, uint16_t y) {
Pokitto 52:c04087025cab 1972 uint16_t w = *bitmap;
Pokitto 52:c04087025cab 1973 uint8_t sourcebyte = bitmap[2+(y * ((w+7)>>3))+ (x>>3)];
Pokitto 52:c04087025cab 1974 return sourcebyte & (0x80>>(x&7));
Pokitto 52:c04087025cab 1975 }
Pokitto 52:c04087025cab 1976
Pokitto 52:c04087025cab 1977 int Display::print_char(uint8_t x, uint8_t y, unsigned char c) {
Pokitto 52:c04087025cab 1978 c -= font[2];
Pokitto 52:c04087025cab 1979 if (m_mode) return directChar(x,y,c);
Pokitto 52:c04087025cab 1980 return bufferChar(x,y,c);
Pokitto 52:c04087025cab 1981 }
Pokitto 52:c04087025cab 1982
Pokitto 52:c04087025cab 1983 void Display::drawChar(int8_t x, int8_t y, unsigned char c, uint8_t size) {
Pokitto 52:c04087025cab 1984 print_char(x,y,c);
Pokitto 52:c04087025cab 1985 return;
Pokitto 52:c04087025cab 1986 }
Pokitto 52:c04087025cab 1987
Pokitto 52:c04087025cab 1988
Pokitto 52:c04087025cab 1989 bool Display::isDirectPrintingEnabled() {
Pokitto 52:c04087025cab 1990 return m_mode;
Pokitto 52:c04087025cab 1991 }
Pokitto 52:c04087025cab 1992
Pokitto 52:c04087025cab 1993 void Display::enableDirectPrinting(uint8_t m) {
Pokitto 52:c04087025cab 1994 if (m) {
Pokitto 52:c04087025cab 1995 m_mode=true;
Pokitto 52:c04087025cab 1996 m_w = POK_LCD_W;
Pokitto 52:c04087025cab 1997 m_h = POK_LCD_H;
Pokitto 52:c04087025cab 1998 } else {
Pokitto 52:c04087025cab 1999 m_mode=false;
Pokitto 52:c04087025cab 2000 m_w = getWidth();
Pokitto 52:c04087025cab 2001 m_h = getHeight();
Pokitto 52:c04087025cab 2002 }
Pokitto 52:c04087025cab 2003 }
Pokitto 52:c04087025cab 2004
Pokitto 52:c04087025cab 2005 void Display::write(uint8_t c) {
Pokitto 52:c04087025cab 2006 int charstep=0;
Pokitto 52:c04087025cab 2007 if(font[3]) {
Pokitto 52:c04087025cab 2008 // only caps in this font
Pokitto 52:c04087025cab 2009 if (c>=97) c-=32;
Pokitto 52:c04087025cab 2010 }
Pokitto 52:c04087025cab 2011 switch(c) {
Pokitto 52:c04087025cab 2012 case '\0': //null
Pokitto 52:c04087025cab 2013 break;
Pokitto 52:c04087025cab 2014 case '\n': //line feed
Pokitto 52:c04087025cab 2015 cursorX = 0;
Pokitto 52:c04087025cab 2016 inc_txtline();
Pokitto 52:c04087025cab 2017 break;
Pokitto 52:c04087025cab 2018 case 8: //backspace
Pokitto 52:c04087025cab 2019 cursorX -= font[0];
Pokitto 52:c04087025cab 2020 charstep=print_char(cursorX,cursorY,' ');
Pokitto 52:c04087025cab 2021 break;
Pokitto 52:c04087025cab 2022 case 13: //carriage return
Pokitto 52:c04087025cab 2023 cursorX = 0;
Pokitto 52:c04087025cab 2024 break;
Pokitto 52:c04087025cab 2025 case 14: //form feed new page(clear screen)
Pokitto 52:c04087025cab 2026 //clear_screen();
Pokitto 52:c04087025cab 2027 break;
Pokitto 52:c04087025cab 2028 default:
Pokitto 52:c04087025cab 2029 if (cursorX >= (m_w - font[0])) {
Pokitto 52:c04087025cab 2030 cursorX = 0;
Pokitto 52:c04087025cab 2031 if (textWrap) inc_txtline();
Pokitto 52:c04087025cab 2032 else return; // stop outputting text
Pokitto 52:c04087025cab 2033 charstep=print_char(cursorX,cursorY,c);
Pokitto 52:c04087025cab 2034 }
Pokitto 52:c04087025cab 2035 else
Pokitto 52:c04087025cab 2036 charstep=print_char(cursorX,cursorY,c);
Pokitto 52:c04087025cab 2037 #ifndef FULLWIDTHSPACES
Pokitto 52:c04087025cab 2038 if (c==' ' && adjustCharStep) charstep=(charstep>>1)+1;
Pokitto 52:c04087025cab 2039 #endif
Pokitto 52:c04087025cab 2040 cursorX += charstep;
Pokitto 52:c04087025cab 2041 }
Pokitto 52:c04087025cab 2042 }
Pokitto 52:c04087025cab 2043
Pokitto 52:c04087025cab 2044 void Display::inc_txtline() {
Pokitto 52:c04087025cab 2045 if (cursorY > m_h - 2*font[1]) //= (height - (font[1]+1)))
Pokitto 52:c04087025cab 2046 #if SCROLL_TEXT > 0
Pokitto 52:c04087025cab 2047 scroll(font[1] + adjustLineStep);
Pokitto 52:c04087025cab 2048 #else
Pokitto 52:c04087025cab 2049 cursorY = 0;
Pokitto 52:c04087025cab 2050 #endif
Pokitto 52:c04087025cab 2051 else
Pokitto 52:c04087025cab 2052 cursorY += font[1] + adjustLineStep;
Pokitto 52:c04087025cab 2053 }
Pokitto 52:c04087025cab 2054
Pokitto 52:c04087025cab 2055 /* default implementation: may be overridden */
Pokitto 52:c04087025cab 2056 void Display::write(const char *str)
Pokitto 52:c04087025cab 2057 {
Pokitto 52:c04087025cab 2058 while (*str)
Pokitto 52:c04087025cab 2059 write(*str++);
Pokitto 52:c04087025cab 2060 }
Pokitto 52:c04087025cab 2061
Pokitto 52:c04087025cab 2062 /* default implementation: may be overridden */
Pokitto 52:c04087025cab 2063 void Display::write(const uint8_t *buffer, uint8_t size)
Pokitto 52:c04087025cab 2064 {
Pokitto 52:c04087025cab 2065 while (size--)
Pokitto 52:c04087025cab 2066 write(*buffer++);
Pokitto 52:c04087025cab 2067 }
Pokitto 52:c04087025cab 2068
Pokitto 52:c04087025cab 2069 void Display::print(const char str[])
Pokitto 52:c04087025cab 2070 {
Pokitto 52:c04087025cab 2071 write(str);
Pokitto 52:c04087025cab 2072 }
Pokitto 52:c04087025cab 2073
Pokitto 52:c04087025cab 2074 void Display::print(char c, int base)
Pokitto 52:c04087025cab 2075 {
Pokitto 52:c04087025cab 2076 print((long) c, base);
Pokitto 52:c04087025cab 2077 }
Pokitto 52:c04087025cab 2078
Pokitto 52:c04087025cab 2079 void Display::print(unsigned char b, int base)
Pokitto 52:c04087025cab 2080 {
Pokitto 52:c04087025cab 2081 print((unsigned long) b, base);
Pokitto 52:c04087025cab 2082 }
Pokitto 52:c04087025cab 2083
Pokitto 52:c04087025cab 2084 void Display::print(int n, int base)
Pokitto 52:c04087025cab 2085 {
Pokitto 52:c04087025cab 2086 print((long) n, base);
Pokitto 52:c04087025cab 2087 }
Pokitto 52:c04087025cab 2088
Pokitto 52:c04087025cab 2089 void Display::print(unsigned int n, int base)
Pokitto 52:c04087025cab 2090 {
Pokitto 52:c04087025cab 2091 print((unsigned long) n, base);
Pokitto 52:c04087025cab 2092 }
Pokitto 52:c04087025cab 2093
Pokitto 52:c04087025cab 2094 void Display::print(long n, int base)
Pokitto 52:c04087025cab 2095 {
Pokitto 52:c04087025cab 2096 if (base == 0) {
Pokitto 52:c04087025cab 2097 write(n);
Pokitto 52:c04087025cab 2098 } else if (base == 10) {
Pokitto 52:c04087025cab 2099 if (n < 0) {
Pokitto 52:c04087025cab 2100 print('-');
Pokitto 52:c04087025cab 2101 n = -n;
Pokitto 52:c04087025cab 2102 }
Pokitto 52:c04087025cab 2103 printNumber(n, 10);
Pokitto 52:c04087025cab 2104 } else {
Pokitto 52:c04087025cab 2105 printNumber(n, base);
Pokitto 52:c04087025cab 2106 }
Pokitto 52:c04087025cab 2107 }
Pokitto 52:c04087025cab 2108
Pokitto 52:c04087025cab 2109 void Display::print(unsigned long n, int base)
Pokitto 52:c04087025cab 2110 {
Pokitto 52:c04087025cab 2111 if (base == 0) write(n);
Pokitto 52:c04087025cab 2112 else printNumber(n, base);
Pokitto 52:c04087025cab 2113 }
Pokitto 52:c04087025cab 2114
Pokitto 52:c04087025cab 2115 void Display::print(double n, int digits)
Pokitto 52:c04087025cab 2116 {
Pokitto 52:c04087025cab 2117 printFloat(n, digits);
Pokitto 52:c04087025cab 2118 }
Pokitto 52:c04087025cab 2119
Pokitto 52:c04087025cab 2120 void Display::println(void)
Pokitto 52:c04087025cab 2121 {
Pokitto 52:c04087025cab 2122 print('\r');
Pokitto 52:c04087025cab 2123 print('\n');
Pokitto 52:c04087025cab 2124 }
Pokitto 52:c04087025cab 2125
Pokitto 52:c04087025cab 2126 void Display::println(const char c[])
Pokitto 52:c04087025cab 2127 {
Pokitto 52:c04087025cab 2128 print(c);
Pokitto 52:c04087025cab 2129 println();
Pokitto 52:c04087025cab 2130 }
Pokitto 52:c04087025cab 2131
Pokitto 52:c04087025cab 2132 void Display::println(char c, int base)
Pokitto 52:c04087025cab 2133 {
Pokitto 52:c04087025cab 2134 print(c, base);
Pokitto 52:c04087025cab 2135 println();
Pokitto 52:c04087025cab 2136 }
Pokitto 52:c04087025cab 2137
Pokitto 52:c04087025cab 2138 void Display::println(unsigned char b, int base)
Pokitto 52:c04087025cab 2139 {
Pokitto 52:c04087025cab 2140 print(b, base);
Pokitto 52:c04087025cab 2141 println();
Pokitto 52:c04087025cab 2142 }
Pokitto 52:c04087025cab 2143
Pokitto 52:c04087025cab 2144 void Display::println(int n, int base)
Pokitto 52:c04087025cab 2145 {
Pokitto 52:c04087025cab 2146 print(n, base);
Pokitto 52:c04087025cab 2147 println();
Pokitto 52:c04087025cab 2148 }
Pokitto 52:c04087025cab 2149
Pokitto 52:c04087025cab 2150 void Display::println(unsigned int n, int base)
Pokitto 52:c04087025cab 2151 {
Pokitto 52:c04087025cab 2152 print(n, base);
Pokitto 52:c04087025cab 2153 println();
Pokitto 52:c04087025cab 2154 }
Pokitto 52:c04087025cab 2155
Pokitto 52:c04087025cab 2156 void Display::println(long n, int base)
Pokitto 52:c04087025cab 2157 {
Pokitto 52:c04087025cab 2158 print(n, base);
Pokitto 52:c04087025cab 2159 println();
Pokitto 52:c04087025cab 2160 }
Pokitto 52:c04087025cab 2161
Pokitto 52:c04087025cab 2162 void Display::println(unsigned long n, int base)
Pokitto 52:c04087025cab 2163 {
Pokitto 52:c04087025cab 2164 print(n, base);
Pokitto 52:c04087025cab 2165 println();
Pokitto 52:c04087025cab 2166 }
Pokitto 52:c04087025cab 2167
Pokitto 52:c04087025cab 2168 void Display::println(double n, int digits)
Pokitto 52:c04087025cab 2169 {
Pokitto 52:c04087025cab 2170 print(n, digits);
Pokitto 52:c04087025cab 2171 println();
Pokitto 52:c04087025cab 2172 }
Pokitto 52:c04087025cab 2173
Pokitto 52:c04087025cab 2174 void Display::set_cursor(uint8_t x, uint8_t y) {
Pokitto 52:c04087025cab 2175 cursorX = x;
Pokitto 52:c04087025cab 2176 cursorY = y;
Pokitto 52:c04087025cab 2177 }
Pokitto 52:c04087025cab 2178
Pokitto 52:c04087025cab 2179 void Display::print(uint8_t x, uint8_t y, const char str[]) {
Pokitto 52:c04087025cab 2180 cursorX = x;
Pokitto 52:c04087025cab 2181 cursorY = y;
Pokitto 52:c04087025cab 2182 write(str);
Pokitto 52:c04087025cab 2183
Pokitto 52:c04087025cab 2184 }
Pokitto 52:c04087025cab 2185 void Display::print(uint8_t x, uint8_t y, char c, int base) {
Pokitto 52:c04087025cab 2186 cursorX = x;
Pokitto 52:c04087025cab 2187 cursorY = y;
Pokitto 52:c04087025cab 2188 print((long) c, base);
Pokitto 52:c04087025cab 2189 }
Pokitto 52:c04087025cab 2190 void Display::print(uint8_t x, uint8_t y, unsigned char b, int base) {
Pokitto 52:c04087025cab 2191 cursorX = x;
Pokitto 52:c04087025cab 2192 cursorY = y;
Pokitto 52:c04087025cab 2193 print((unsigned long) b, base);
Pokitto 52:c04087025cab 2194 }
Pokitto 52:c04087025cab 2195 void Display::print(uint8_t x, uint8_t y, int n, int base) {
Pokitto 52:c04087025cab 2196 cursorX = x;
Pokitto 52:c04087025cab 2197 cursorY = y;
Pokitto 52:c04087025cab 2198 print((long) n, base);
Pokitto 52:c04087025cab 2199 }
Pokitto 52:c04087025cab 2200 void Display::print(uint8_t x, uint8_t y, unsigned int n, int base) {
Pokitto 52:c04087025cab 2201 cursorX = x;
Pokitto 52:c04087025cab 2202 cursorY = y;
Pokitto 52:c04087025cab 2203 print((unsigned long) n, base);
Pokitto 52:c04087025cab 2204 }
Pokitto 52:c04087025cab 2205 void Display::print(uint8_t x, uint8_t y, long n, int base) {
Pokitto 52:c04087025cab 2206 cursorX = x;
Pokitto 52:c04087025cab 2207 cursorY = y;
Pokitto 52:c04087025cab 2208 print(n,base);
Pokitto 52:c04087025cab 2209 }
Pokitto 52:c04087025cab 2210 void Display::print(uint8_t x, uint8_t y, unsigned long n, int base) {
Pokitto 52:c04087025cab 2211 cursorX = x;
Pokitto 52:c04087025cab 2212 cursorY = y;
Pokitto 52:c04087025cab 2213 print(n,base);
Pokitto 52:c04087025cab 2214 }
Pokitto 52:c04087025cab 2215 void Display::print(uint8_t x, uint8_t y, double n, int digits) {
Pokitto 52:c04087025cab 2216 cursorX = x;
Pokitto 52:c04087025cab 2217 cursorY = y;
Pokitto 52:c04087025cab 2218 print(n,digits);
Pokitto 52:c04087025cab 2219 }
Pokitto 52:c04087025cab 2220
Pokitto 52:c04087025cab 2221 void Display::println(uint8_t x, uint8_t y, const char c[])
Pokitto 52:c04087025cab 2222 {
Pokitto 52:c04087025cab 2223 cursorX = x;
Pokitto 52:c04087025cab 2224 cursorY = y;
Pokitto 52:c04087025cab 2225 print(c);
Pokitto 52:c04087025cab 2226 println();
Pokitto 52:c04087025cab 2227 }
Pokitto 52:c04087025cab 2228
Pokitto 52:c04087025cab 2229 void Display::println(uint8_t x, uint8_t y, char c, int base)
Pokitto 52:c04087025cab 2230 {
Pokitto 52:c04087025cab 2231 cursorX = x;
Pokitto 52:c04087025cab 2232 cursorY = y;
Pokitto 52:c04087025cab 2233 print(c, base);
Pokitto 52:c04087025cab 2234 println();
Pokitto 52:c04087025cab 2235 }
Pokitto 52:c04087025cab 2236
Pokitto 52:c04087025cab 2237 void Display::println(uint8_t x, uint8_t y, unsigned char b, int base)
Pokitto 52:c04087025cab 2238 {
Pokitto 52:c04087025cab 2239 cursorX = x;
Pokitto 52:c04087025cab 2240 cursorY = y;
Pokitto 52:c04087025cab 2241 print(b, base);
Pokitto 52:c04087025cab 2242 println();
Pokitto 52:c04087025cab 2243 }
Pokitto 52:c04087025cab 2244
Pokitto 52:c04087025cab 2245 void Display::println(uint8_t x, uint8_t y, int n, int base)
Pokitto 52:c04087025cab 2246 {
Pokitto 52:c04087025cab 2247 cursorX = x;
Pokitto 52:c04087025cab 2248 cursorY = y;
Pokitto 52:c04087025cab 2249 print(n, base);
Pokitto 52:c04087025cab 2250 println();
Pokitto 52:c04087025cab 2251 }
Pokitto 52:c04087025cab 2252
Pokitto 52:c04087025cab 2253 void Display::println(uint8_t x, uint8_t y, unsigned int n, int base)
Pokitto 52:c04087025cab 2254 {
Pokitto 52:c04087025cab 2255 cursorX = x;
Pokitto 52:c04087025cab 2256 cursorY = y;
Pokitto 52:c04087025cab 2257 print(n, base);
Pokitto 52:c04087025cab 2258 println();
Pokitto 52:c04087025cab 2259 }
Pokitto 52:c04087025cab 2260
Pokitto 52:c04087025cab 2261 void Display::println(uint8_t x, uint8_t y, long n, int base)
Pokitto 52:c04087025cab 2262 {
Pokitto 52:c04087025cab 2263 cursorX = x;
Pokitto 52:c04087025cab 2264 cursorY = y;
Pokitto 52:c04087025cab 2265 print(n, base);
Pokitto 52:c04087025cab 2266 println();
Pokitto 52:c04087025cab 2267 }
Pokitto 52:c04087025cab 2268
Pokitto 52:c04087025cab 2269 void Display::println(uint8_t x, uint8_t y, unsigned long n, int base)
Pokitto 52:c04087025cab 2270 {
Pokitto 52:c04087025cab 2271 cursorX = x;
Pokitto 52:c04087025cab 2272 cursorY = y;
Pokitto 52:c04087025cab 2273 print(n, base);
Pokitto 52:c04087025cab 2274 println();
Pokitto 52:c04087025cab 2275 }
Pokitto 52:c04087025cab 2276
Pokitto 52:c04087025cab 2277 void Display::println(uint8_t x, uint8_t y, double n, int digits)
Pokitto 52:c04087025cab 2278 {
Pokitto 52:c04087025cab 2279 cursorX = x;
Pokitto 52:c04087025cab 2280 cursorY = y;
Pokitto 52:c04087025cab 2281 print(n, digits);
Pokitto 52:c04087025cab 2282 println();
Pokitto 52:c04087025cab 2283 }
Pokitto 52:c04087025cab 2284
Pokitto 52:c04087025cab 2285 void Display::printNumber(unsigned long n, uint8_t base)
Pokitto 52:c04087025cab 2286 {
Pokitto 52:c04087025cab 2287 unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
Pokitto 52:c04087025cab 2288 unsigned long i = 0;
Pokitto 52:c04087025cab 2289
Pokitto 52:c04087025cab 2290 if (n == 0) {
Pokitto 52:c04087025cab 2291 print('0');
Pokitto 52:c04087025cab 2292 return;
Pokitto 52:c04087025cab 2293 }
Pokitto 52:c04087025cab 2294
Pokitto 52:c04087025cab 2295 while (n > 0) {
Pokitto 52:c04087025cab 2296 buf[i++] = n % base;
Pokitto 52:c04087025cab 2297 n /= base;
Pokitto 52:c04087025cab 2298 }
Pokitto 52:c04087025cab 2299
Pokitto 52:c04087025cab 2300 for (; i > 0; i--)
Pokitto 52:c04087025cab 2301 print((char) (buf[i - 1] < 10 ?
Pokitto 52:c04087025cab 2302 '0' + buf[i - 1] :
Pokitto 52:c04087025cab 2303 'A' + buf[i - 1] - 10));
Pokitto 52:c04087025cab 2304 }
Pokitto 52:c04087025cab 2305
Pokitto 52:c04087025cab 2306 void Display::printFloat(double number, uint8_t digits)
Pokitto 52:c04087025cab 2307 {
Pokitto 52:c04087025cab 2308 // Handle negative numbers
Pokitto 52:c04087025cab 2309 if (number < 0.0)
Pokitto 52:c04087025cab 2310 {
Pokitto 52:c04087025cab 2311 print('-');
Pokitto 52:c04087025cab 2312 number = -number;
Pokitto 52:c04087025cab 2313 }
Pokitto 52:c04087025cab 2314
Pokitto 52:c04087025cab 2315 // Round correctly so that print(1.999, 2) prints as "2.00"
Pokitto 52:c04087025cab 2316 double rounding = 0.5;
Pokitto 52:c04087025cab 2317 for (uint8_t i=0; i<digits; ++i)
Pokitto 52:c04087025cab 2318 rounding /= 10.0;
Pokitto 52:c04087025cab 2319
Pokitto 52:c04087025cab 2320 number += rounding;
Pokitto 52:c04087025cab 2321
Pokitto 52:c04087025cab 2322 // Extract the integer part of the number and print it
Pokitto 52:c04087025cab 2323 unsigned long int_part = (unsigned long)number;
Pokitto 52:c04087025cab 2324 double remainder = number - (double)int_part;
Pokitto 52:c04087025cab 2325 print(int_part);
Pokitto 52:c04087025cab 2326
Pokitto 52:c04087025cab 2327 // Print the decimal point, but only if there are digits beyond
Pokitto 52:c04087025cab 2328 if (digits > 0)
Pokitto 52:c04087025cab 2329 print(".");
Pokitto 52:c04087025cab 2330
Pokitto 52:c04087025cab 2331 // Extract digits from the remainder one at a time
Pokitto 52:c04087025cab 2332 while (digits-- > 0)
Pokitto 52:c04087025cab 2333 {
Pokitto 52:c04087025cab 2334 remainder *= 10.0;
Pokitto 52:c04087025cab 2335 int toPrint = int(remainder);
Pokitto 52:c04087025cab 2336 print(toPrint);
Pokitto 52:c04087025cab 2337 remainder -= toPrint;
Pokitto 52:c04087025cab 2338 }
Pokitto 52:c04087025cab 2339 }
Pokitto 52:c04087025cab 2340
Pokitto 52:c04087025cab 2341 void Display::draw4BitColumn(int16_t x, int16_t y, uint8_t h, uint8_t* bitmap)
Pokitto 52:c04087025cab 2342 {
Pokitto 52:c04087025cab 2343 int8_t scry;
Pokitto 52:c04087025cab 2344 uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
Pokitto 52:c04087025cab 2345
Pokitto 52:c04087025cab 2346 /** ONLY 4-bit mode for time being **/
Pokitto 52:c04087025cab 2347
Pokitto 52:c04087025cab 2348 if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
Pokitto 52:c04087025cab 2349 for (scry = y; scry < h+y; scry++) {
Pokitto 52:c04087025cab 2350 uint8_t sourcepixel = *bitmap;
Pokitto 52:c04087025cab 2351 uint8_t targetpixel = *scrptr;
Pokitto 52:c04087025cab 2352 targetpixel = (targetpixel&0x0F) | (sourcepixel << 4);
Pokitto 52:c04087025cab 2353 *scrptr = targetpixel;
Pokitto 52:c04087025cab 2354 bitmap++;
Pokitto 52:c04087025cab 2355 scrptr+=55;
Pokitto 52:c04087025cab 2356 }
Pokitto 52:c04087025cab 2357 } else { /** ODD pixel starting line **/
Pokitto 52:c04087025cab 2358 for (scry = y; scry < h+y; scry++) {
Pokitto 52:c04087025cab 2359 uint8_t sourcepixel = *bitmap;
Pokitto 52:c04087025cab 2360 uint8_t targetpixel = *scrptr;
Pokitto 52:c04087025cab 2361 // store source pixel in lower nibble of target
Pokitto 52:c04087025cab 2362 targetpixel = (targetpixel & 0xF0) | (sourcepixel);
Pokitto 52:c04087025cab 2363 *scrptr = targetpixel;
Pokitto 52:c04087025cab 2364 scrptr+=55;
Pokitto 52:c04087025cab 2365 bitmap++;
Pokitto 52:c04087025cab 2366 }
Pokitto 52:c04087025cab 2367 }
Pokitto 52:c04087025cab 2368 }
Pokitto 52:c04087025cab 2369
Pokitto 52:c04087025cab 2370 /**
Pokitto 52:c04087025cab 2371 * Setup or disable the sprite. Note that enabled sprites must always have subsequent indices, starting from the index zero.
Pokitto 52:c04087025cab 2372 * You cannot have gaps in indices of enabled sprites.
Pokitto 52:c04087025cab 2373 * The max number of sprites can be changed by a SPRITE_COUNT define, the default is 4.
Pokitto 52:c04087025cab 2374 * Note: the sprites currently work only in the 220 x 176 x 2bpp mode.
Pokitto 52:c04087025cab 2375 * @param index The sprite index. The lower index is drawn first, i.e. is on bottom.
Pokitto 52:c04087025cab 2376 * @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 2377 * @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 2378 * @param x The initial x
Pokitto 52:c04087025cab 2379 * @param y The initial y
Pokitto 52:c04087025cab 2380 * @param doResetDirtyRect (default=true) True, if the previous coordinates are reseted.
Pokitto 52:c04087025cab 2381 */
Pokitto 52:c04087025cab 2382 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 2383
Pokitto 52:c04087025cab 2384 setSprite(index, &(bitmap[2]), palette4x16bit, x, y, bitmap[0], bitmap[1], doResetDirtyRect);
Pokitto 52:c04087025cab 2385 }
Pokitto 52:c04087025cab 2386
Pokitto 52:c04087025cab 2387 /**
Pokitto 52:c04087025cab 2388 * Setup or disable the sprite. Note that enabled sprites must always have subsequent indices, starting from the index zero.
Pokitto 52:c04087025cab 2389 * You cannot have gaps in indices of enabled sprites.
Pokitto 52:c04087025cab 2390 * The max number of sprites can be changed by a SPRITE_COUNT define, the default is 4.
Pokitto 52:c04087025cab 2391 * Note: the sprites currently work only in the 220 x 176 x 2bpp mode.
Pokitto 52:c04087025cab 2392 * @param index The sprite index. The lower index is drawn first, i.e. is on bottom. Note that
Pokitto 52:c04087025cab 2393 * @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 2394 * @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 2395 * @param x The initial x
Pokitto 52:c04087025cab 2396 * @param y The initial y
Pokitto 52:c04087025cab 2397 * @param w Width
Pokitto 52:c04087025cab 2398 * @param h Height
Pokitto 52:c04087025cab 2399 */
Pokitto 52:c04087025cab 2400 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 2401
Pokitto 52:c04087025cab 2402 if(index >= SPRITE_COUNT) return;
Pokitto 52:c04087025cab 2403 m_sprites[index].bitmapData = data;
Pokitto 52:c04087025cab 2404 m_sprites[index].x = x;
Pokitto 52:c04087025cab 2405 m_sprites[index].y = y;
Pokitto 52:c04087025cab 2406 if (doResetDirtyRect) {
Pokitto 52:c04087025cab 2407 m_sprites[index].oldx = x;
Pokitto 52:c04087025cab 2408 m_sprites[index].oldy = y;
Pokitto 52:c04087025cab 2409 }
Pokitto 52:c04087025cab 2410 m_sprites[index].w = w;
Pokitto 52:c04087025cab 2411 m_sprites[index].h = h;
Pokitto 52:c04087025cab 2412 if( palette4x16bit ) memcpy(m_sprites[index].palette, palette4x16bit, 4*2);
Pokitto 52:c04087025cab 2413 }
Pokitto 52:c04087025cab 2414
Pokitto 52:c04087025cab 2415 /**
Pokitto 52:c04087025cab 2416 * Set the sprite position.
Pokitto 52:c04087025cab 2417 * @param index The sprite index
Pokitto 52:c04087025cab 2418 * @param x
Pokitto 52:c04087025cab 2419 * @param y
Pokitto 52:c04087025cab 2420 */
Pokitto 52:c04087025cab 2421 void Display::setSpritePos(uint8_t index, int16_t x, int16_t y) {
Pokitto 52:c04087025cab 2422
Pokitto 52:c04087025cab 2423 if(index >= SPRITE_COUNT) return;
Pokitto 52:c04087025cab 2424 m_sprites[index].x = x;
Pokitto 52:c04087025cab 2425 m_sprites[index].y = y;
Pokitto 52:c04087025cab 2426 }
Pokitto 52:c04087025cab 2427
Pokitto 52:c04087025cab 2428 void Display::lcdRefresh(unsigned char* scr, bool useDirectDrawMode) {
Pokitto 52:c04087025cab 2429
Pokitto 52:c04087025cab 2430 #if POK_SCREENMODE == MODE_HI_4COLOR
Pokitto 52:c04087025cab 2431 // If there is one or more sprites, use sprite enabled drawing.
Pokitto 52:c04087025cab 2432 if (m_sprites[0].bitmapData != NULL)
Pokitto 52:c04087025cab 2433 lcdRefreshMode1Spr(scr, 0, 0, LCDWIDTH, LCDHEIGHT, paletteptr, m_sprites, useDirectDrawMode);
Pokitto 52:c04087025cab 2434 else if (!useDirectDrawMode)
Pokitto 52:c04087025cab 2435 lcdRefreshMode1(m_scrbuf, 0, 0, LCDWIDTH, LCDHEIGHT, paletteptr);
Pokitto 52:c04087025cab 2436 #endif
Pokitto 52:c04087025cab 2437
Pokitto 52:c04087025cab 2438 // For the screen modes that do not support sprites, return if the direct draw mode is used.
Pokitto 52:c04087025cab 2439 if (useDirectDrawMode) return;
Pokitto 52:c04087025cab 2440 #if POK_SCREENMODE == MODE13
Pokitto 52:c04087025cab 2441 lcdRefreshMode13(m_scrbuf, paletteptr, palOffset);
Pokitto 52:c04087025cab 2442 #endif
Pokitto 52:c04087025cab 2443
Pokitto 52:c04087025cab 2444 #if POK_SCREENMODE == MODE_GAMEBOY
Pokitto 52:c04087025cab 2445 lcdRefreshModeGBC(scr, paletteptr);
Pokitto 52:c04087025cab 2446 #endif
Pokitto 52:c04087025cab 2447
Pokitto 52:c04087025cab 2448 #if POK_SCREENMODE == MODE_FAST_16COLOR
Pokitto 52:c04087025cab 2449 lcdRefreshMode2(scr, paletteptr);
Pokitto 52:c04087025cab 2450 #endif
Pokitto 52:c04087025cab 2451
Pokitto 52:c04087025cab 2452 #if POK_SCREENMODE == MODE_GAMEBUINO_16COLOR
Pokitto 52:c04087025cab 2453 lcdRefreshGB(scr, paletteptr);
Pokitto 52:c04087025cab 2454 #endif
Pokitto 52:c04087025cab 2455
Pokitto 52:c04087025cab 2456 #if POK_SCREENMODE == MODE_ARDUBOY_16COLOR
Pokitto 52:c04087025cab 2457 lcdRefreshAB(scr, paletteptr);
Pokitto 52:c04087025cab 2458 #endif
Pokitto 52:c04087025cab 2459
Pokitto 52:c04087025cab 2460 }
Pokitto 52:c04087025cab 2461
Pokitto 52:c04087025cab 2462 void Display::setFrameBufferTo(uint8_t* sb) {
Pokitto 52:c04087025cab 2463 m_scrbuf = sb;
Pokitto 52:c04087025cab 2464 };
Pokitto 52:c04087025cab 2465
Pokitto 52:c04087025cab 2466 void Display::setTileBufferTo(uint8_t* tb) {
Pokitto 52:c04087025cab 2467 m_tilebuf = tb;
Pokitto 52:c04087025cab 2468 };
Pokitto 52:c04087025cab 2469
Pokitto 52:c04087025cab 2470 void Display::loadTileset(const uint8_t* ts) {
Pokitto 52:c04087025cab 2471 m_tileset = (uint8_t*) ts;
Pokitto 52:c04087025cab 2472 };
Pokitto 52:c04087025cab 2473
Pokitto 52:c04087025cab 2474 void Display::setTile(uint16_t i, uint8_t t) {
Pokitto 52:c04087025cab 2475 if (!m_tilebuf) return;
Pokitto 52:c04087025cab 2476 m_tilebuf[i]=t;
Pokitto 52:c04087025cab 2477 };
Pokitto 52:c04087025cab 2478
Pokitto 52:c04087025cab 2479 // Convert an integer to a hexadecimal string
Pokitto 52:c04087025cab 2480 char* itoa_hex(int num, char* dest, int destLen) {
Pokitto 52:c04087025cab 2481 int i = destLen-1;
Pokitto 52:c04087025cab 2482 do {
Pokitto 52:c04087025cab 2483 char c = (num % 16) + '0';
Pokitto 52:c04087025cab 2484 if (c > '9') c += 7;
Pokitto 52:c04087025cab 2485 dest[i--] = c;
Pokitto 52:c04087025cab 2486 num /= 16;
Pokitto 52:c04087025cab 2487 } while (num && i >= 0);
Pokitto 52:c04087025cab 2488 return &(dest[i+1]);
Pokitto 52:c04087025cab 2489 }
Pokitto 52:c04087025cab 2490
Pokitto 52:c04087025cab 2491 // Draw the crash screen and wait forever
Pokitto 52:c04087025cab 2492 void ShowCrashScreenAndWait( const char* texLine1, const char* texLine2, const char* texLine3, const char* texLine4, const char* texLine5 ) {
Pokitto 52:c04087025cab 2493
Pokitto 52:c04087025cab 2494 // draw screen red
Pokitto 52:c04087025cab 2495 lcdFillSurface(COLOR_RED);
Pokitto 52:c04087025cab 2496
Pokitto 52:c04087025cab 2497 // Draw text
Pokitto 52:c04087025cab 2498 Display::directcolor = COLOR_WHITE;
Pokitto 52:c04087025cab 2499 Display::invisiblecolor = COLOR_RED;
Pokitto 52:c04087025cab 2500 Display::directbgcolor = COLOR_RED; // Cannot be black as that is a transparent color
Pokitto 52:c04087025cab 2501 Display::directtextrotated = false;
Pokitto 52:c04087025cab 2502 Display::adjustCharStep = 0;
Pokitto 52:c04087025cab 2503 Display::adjustLineStep = 0;
Pokitto 52:c04087025cab 2504 Display::setFont(fntC64UIGfx); // A special font set that contains UI gfx in lower case letters.
Pokitto 52:c04087025cab 2505 Display::fixedWidthFont = true; // Needed for the non-proportional C64 font (default value=false)
Pokitto 52:c04087025cab 2506 Display::enableDirectPrinting(true);
Pokitto 52:c04087025cab 2507
Pokitto 52:c04087025cab 2508 // Draw texts
Pokitto 52:c04087025cab 2509 int yOffsetInPixels = 5;
Pokitto 52:c04087025cab 2510 Display::set_cursor(0, 9 + yOffsetInPixels);
Pokitto 52:c04087025cab 2511 Display::print(" "); Display::println(texLine1);
Pokitto 52:c04087025cab 2512 Display::print(" "); Display::println(texLine2);
Pokitto 52:c04087025cab 2513 Display::print(" "); Display::println(texLine3);
Pokitto 52:c04087025cab 2514 Display::println();
Pokitto 52:c04087025cab 2515 Display::print(" *"); Display::println(texLine4);
Pokitto 52:c04087025cab 2516 Display::print(" *"); Display::println(texLine5);
Pokitto 52:c04087025cab 2517
Pokitto 52:c04087025cab 2518 Display::set_cursor(0, 0 + yOffsetInPixels);
Pokitto 52:c04087025cab 2519
Pokitto 52:c04087025cab 2520 // Frame
Pokitto 52:c04087025cab 2521 Display::println(" abbbbbbbbbbbbbbbbbbbbbbbbc");
Pokitto 52:c04087025cab 2522 Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
Pokitto 52:c04087025cab 2523 Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
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::println(" dbbbzybbbbbbbbbbbbbbbbbbbe");
Pokitto 52:c04087025cab 2529 Display::println(" {e");
Pokitto 52:c04087025cab 2530
Pokitto 52:c04087025cab 2531 // Pokitto image
Pokitto 52:c04087025cab 2532 Display::println ("");
Pokitto 52:c04087025cab 2533 Display::println (" ijkl");
Pokitto 52:c04087025cab 2534 Display::println (" mnop");
Pokitto 52:c04087025cab 2535 Display::println (" qrst");
Pokitto 52:c04087025cab 2536 Display::println (" uvwx");
Pokitto 52:c04087025cab 2537
Pokitto 52:c04087025cab 2538 // loop forever
Pokitto 52:c04087025cab 2539 while(1){;}
Pokitto 52:c04087025cab 2540 }
Pokitto 52:c04087025cab 2541
Pokitto 52:c04087025cab 2542 // Check the stack size and show a crash screen if the stack is too big.
Pokitto 52:c04087025cab 2543 void CheckStack() {
Pokitto 52:c04087025cab 2544 #ifndef POK_SIM
Pokitto 52:c04087025cab 2545 #ifndef __ARMCC_VERSION
Pokitto 52:c04087025cab 2546 int currStackTop;
Pokitto 52:c04087025cab 2547 const int freeStackThreshold = 200;
Pokitto 52:c04087025cab 2548 if ((int)&currStackTop - (int)_ebss < freeStackThreshold) {
Pokitto 52:c04087025cab 2549
Pokitto 52:c04087025cab 2550 // Create info string: "<stack size>:<current stack pointer>", e.g. "12345ABC:12345ABC"
Pokitto 52:c04087025cab 2551 const int infoStringLen = 8+1+8;
Pokitto 52:c04087025cab 2552 static char infoString[infoStringLen+1];
Pokitto 52:c04087025cab 2553 memset(infoString,0,infoStringLen+1);
Pokitto 52:c04087025cab 2554 const int stackSize = (int)_vStackTop - (int)&currStackTop;
Pokitto 52:c04087025cab 2555 const int tmpStrLen = 8;
Pokitto 52:c04087025cab 2556 static char tmpStr[tmpStrLen+1];
Pokitto 52:c04087025cab 2557 memset(tmpStr,0,tmpStrLen+1);
Pokitto 52:c04087025cab 2558 char* subStr = itoa_hex(stackSize, tmpStr, tmpStrLen); // keep ending null
Pokitto 52:c04087025cab 2559 strcat(infoString, subStr); // Add stack size as hex string
Pokitto 52:c04087025cab 2560 strcat(infoString, ":");
Pokitto 52:c04087025cab 2561 subStr = itoa_hex((int)&currStackTop, tmpStr, tmpStrLen); // keep ending null
Pokitto 52:c04087025cab 2562 strcat(infoString, subStr); // Add stack pointer address as hex string
Pokitto 52:c04087025cab 2563
Pokitto 52:c04087025cab 2564 // Draw the crash screen and wait forever. Use static const strings to avoid more stack usage.
Pokitto 52:c04087025cab 2565 static const char* texLine1 = "OOPS! PLEASE, RESTART";
Pokitto 52:c04087025cab 2566 static const char* texLine2 = "POKITTO OR RELOAD";
Pokitto 52:c04087025cab 2567 static const char* texLine3 = "SOFTWARE.";
Pokitto 52:c04087025cab 2568 static const char* texLine4 = "STACK TOO BIG!";
Pokitto 52:c04087025cab 2569 ShowCrashScreenAndWait(texLine1, texLine2, texLine3, texLine4, infoString);
Pokitto 52:c04087025cab 2570 }
Pokitto 52:c04087025cab 2571 #endif
Pokitto 52:c04087025cab 2572 #endif
Pokitto 52:c04087025cab 2573 }
Pokitto 52:c04087025cab 2574
Pokitto 52:c04087025cab 2575 /** Eof */
Pokitto 52:c04087025cab 2576
Pokitto 52:c04087025cab 2577
Pokitto 52:c04087025cab 2578
Pokitto 52:c04087025cab 2579