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

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

PokittoLib

Library for programming Pokitto hardware

How to Use

  1. Import this library to online compiler (see button "import" on the right hand side
  2. DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
  3. Change My_settings.h according to your project
  4. Start coding!
Committer:
Pokitto
Date:
Tue Sep 19 08:47:36 2017 +0000
Revision:
2:968589ca3484
Parent:
0:e8b8f36b4505
Got rid of warnings at compile time

Who changed what in which revision?

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