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

Committer:
Pokitto
Date:
Tue Jan 30 10:41:47 2018 +0000
Revision:
31:f4b9b85c7b62
Child:
35:4f7edccf8ed6
Sound output improvements added:  louder, clearer, faster!

Who changed what in which revision?

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