PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)
Dependents: YATTT sd_map_test cPong SnowDemo ... more
PokittoLib
Library for programming Pokitto hardware
How to Use
- Import this library to online compiler (see button "import" on the right hand side
- DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
- Change My_settings.h according to your project
- Start coding!
Diff: POKITTO_CORE/PokittoDisplay.cpp
- Revision:
- 64:1d52d8287c39
- Parent:
- 60:8b6a110feeea
--- a/POKITTO_CORE/PokittoDisplay.cpp Sun Oct 07 10:19:52 2018 +0000 +++ b/POKITTO_CORE/PokittoDisplay.cpp Sat Mar 23 19:19:23 2019 +0000 @@ -71,6 +71,7 @@ #include "PokittoSound.h" #include <stdio.h> #include <string.h> +#include <ctype.h> #ifdef DISABLEAVRMIN #include <algorithm> using std::min; @@ -92,8 +93,6 @@ using namespace Pokitto; - - uint8_t* Display::m_scrbuf; uint8_t* Display::m_tileset; uint8_t* Display::m_tilebuf; @@ -124,7 +123,7 @@ const unsigned char* Display::font; int8_t Display::adjustCharStep = 1; int8_t Display::adjustLineStep = 1; -bool Display::fixedWidthFont = false; +bool Display::fixedWidthFont = false, Display::flipFontVertical = false; /** drawing canvas **/ //uint8_t* Display::canvas; // points to the active buffer. if null, draw direct to screen @@ -139,7 +138,7 @@ #elif (POK_SCREENMODE == MODE_HI_4COLOR) uint8_t Display::width = POK_LCD_W; uint8_t Display::height = POK_LCD_H; - uint8_t __attribute__((section (".bss"))) Display::screenbuffer[((POK_LCD_H)*POK_LCD_W)/4]; // maximum resolution + uint8_t __attribute__((section (".bss"))) __attribute__ ((aligned)) Display::screenbuffer[((POK_LCD_H)*POK_LCD_W)/4]; // maximum resolution #elif (POK_SCREENMODE == MODE_FAST_16COLOR) uint8_t Display::width = POK_LCD_W/2; uint8_t Display::height = POK_LCD_H/2; @@ -164,10 +163,19 @@ uint8_t Display::width = 110; uint8_t Display::height = 88; uint8_t Display::screenbuffer[110*88]; // 8bit 110x88 +#elif (POK_SCREENMODE == MIXMODE) + uint8_t Display::width = 110; + uint8_t Display::height = 88; + uint8_t Display::screenbuffer[110*88]; // 8bit 110x88 or 4bit 110x176 + uint8_t Display::scanType[88]; // scanline bit depth indicator +#elif (POK_SCREENMODE == MODE64) + uint8_t Display::width = 110; + uint8_t Display::height = 176; + uint8_t __attribute__ ((aligned)) Display::screenbuffer[110*176]; // 8bit 110x176 #elif (POK_SCREENMODE == MODE15) uint8_t Display::width = 220; uint8_t Display::height = 176; - uint8_t Display::screenbuffer[0x4BA0]; + uint8_t __attribute__ ((aligned)) Display::screenbuffer[0x4BA0]; #else uint8_t Display::width = 84; uint8_t Display::height = 48; @@ -206,7 +214,7 @@ #endif // POK_GAMEBUINO_SUPPORT // Reset sprites - m_tilecolorbuf = NULL; //!!HV + m_tilecolorbuf = NULL; for (uint8_t s = 0; s < SPRITE_COUNT; s++) m_sprites[s].bitmapData = NULL; } @@ -289,6 +297,14 @@ lcdRefreshMode13(m_scrbuf, paletteptr, palOffset); #endif + #if POK_SCREENMODE == MIXMODE + lcdRefreshMixMode(m_scrbuf, paletteptr, scanType); + #endif + + #if POK_SCREENMODE == MODE64 + lcdRefreshMode64(m_scrbuf, paletteptr); + #endif + #if POK_SCREENMODE == MODE_GAMEBOY lcdRefreshModeGBC(m_scrbuf, paletteptr); #endif @@ -352,7 +368,9 @@ directcolor = COLOR_WHITE; invisiblecolor = COLOR_BLACK; directbgcolor = 0x0001; // Cannot be black as that is transparent color - if (POK_SCREENMODE == MODE_FAST_16COLOR ) + if (POK_SCREENMODE == MODE_FAST_16COLOR || + POK_SCREENMODE == MODE13 + ) directtextrotated = false; else directtextrotated = true; @@ -484,39 +502,92 @@ // GLCD fonts are arranged LSB = topmost pixel of char, so its easy to just shift through the column uint16_t bitcolumn; //16 bits for 2x8 bit high characters + if( fontSize != 2 ) fontSize = 1; + + void (*drawPixelFG)(int16_t,int16_t, uint8_t) = &Display::drawPixelNOP; + void (*drawPixelBG)(int16_t,int16_t, uint8_t) = &Display::drawPixelNOP; + if( x>=0 && y >= 0 && x+w*fontSize<width && y+(h+1)*fontSize<height ){ + if( color != invisiblecolor ) + drawPixelFG = &Display::drawPixelRaw; + if( bgcolor != invisiblecolor ) + drawPixelBG = &Display::drawPixelRaw; + }else{ + if( color != invisiblecolor ) + drawPixelFG = &Display::drawPixel; + if( bgcolor != invisiblecolor ) + drawPixelBG = &Display::drawPixel; + } + + void (*drawPixel[])(int16_t,int16_t, uint8_t) = {drawPixelBG, drawPixelFG}; + uint8_t colors[] = {bgcolor, color}; + +#if PROJ_ARDUBOY > 0 +#else + if( fontSize != 2 ){ +#endif + + for (i = 0; i < numBytes; i++) { + bitcolumn = *bitmap++; + if (hbytes == 2) bitcolumn |= (*bitmap++)<<8; // add second byte for 16 bit high fonts + for (j = 0; j <= h; j++) { // was j<=h + uint8_t c = colors[ bitcolumn & 1 ]; + +#if PROJ_ARDUBOY > 0 + drawPixel[ bitcolumn&1 ](x, y + 7 - j,c); +#elif PROJ_SUPPORT_FONTROTATION > 0 + // if font flipping & rotation is allowed - do not slow down old programs! + if (flipFontVertical) { + drawPixel[ bitcolumn&1 ](x, y + h - j,c); + } else { + drawPixel[ bitcolumn&1 ](x, y + j,c); + } +#else + // "Normal" case + drawPixel[ bitcolumn&1 ](x, y + j,c); +#endif // PROJ_ARDUBOY + bitcolumn>>=1; + + } +#if PROJ_SUPPORT_FONTROTATION > 0 + if (flipFontVertical) x--; + else x++; +#else + x++; +#endif + } + +#if PROJ_SUPPORT_FONTROTATION > 0 + if (flipFontVertical) return -numBytes-adjustCharStep; + else return numBytes+adjustCharStep; // for character stepping +#else + return numBytes+adjustCharStep; +#endif + + +#if PROJ_ARDUBOY > 0 +#else + }else{ + for (i = 0; i < numBytes; i++) { - bitcolumn = *bitmap++; - if (hbytes == 2) bitcolumn |= (*bitmap++)<<8; // add second byte for 16 bit high fonts - for (j = 0; j <= h; j++) { // was j<=h - #if PROJ_ARDUBOY > 0 - if (bitcolumn&0x1) { - drawPixel(x + i, y + 7 - j,color); - } else drawPixel(x + i, y + 7 - j,bgcolor); - bitcolumn>>=1; - #else - if (fontSize==2) { - if (bitcolumn&0x1) { - drawPixel(x + (i<<1) , y + (j<<1),color); - drawPixel(x + (i<<1)+1, y + (j<<1),color); - drawPixel(x + (i<<1) , y + (j<<1)+1,color); - drawPixel(x + (i<<1)+1, y + (j<<1)+1,color); - } else { - drawPixel(x + (i<<1) , y + (j<<1),bgcolor); - drawPixel(x + (i<<1)+1, y + (j<<1),bgcolor); - drawPixel(x + (i<<1) , y + (j<<1)+1,bgcolor); - drawPixel(x + (i<<1)+1, y + (j<<1)+1,bgcolor); - } - } else { - if (bitcolumn&0x1) drawPixel(x + i, y + j,color); - else drawPixel(x + i, y + j,bgcolor); - } - bitcolumn>>=1; - #endif // PROJ_ARDUBOY + bitcolumn = *bitmap++; + if (hbytes == 2) bitcolumn |= (*bitmap++)<<8; // add second byte for 16 bit high fonts + for (j = 0; j <= h; j++) { // was j<=h + uint8_t c = colors[ bitcolumn & 1 ]; - } + drawPixel[ bitcolumn&1 ](x + (i<<1) , y + (j<<1), c); + drawPixel[ bitcolumn&1 ](x + (i<<1)+1, y + (j<<1), c); + drawPixel[ bitcolumn&1 ](x + (i<<1) , y + (j<<1)+1, c); + drawPixel[ bitcolumn&1 ](x + (i<<1)+1, y + (j<<1)+1, c); + bitcolumn>>=1; + + } + } + + return (numBytes+adjustCharStep)<<1; + } - if (fontSize==2) return (numBytes+adjustCharStep)<<1; - return numBytes+adjustCharStep; // for character stepping +#endif // PROJ_ARDUBOY + } void Display::clear() { @@ -532,13 +603,13 @@ uint16_t j = POK_BITFRAME; if (bgcolor & 0x1) memset((void*)m_scrbuf,0xFF,j);// R else memset((void*)m_scrbuf,0x00,j);// R - if ((bgcolor>>1) & 0x1) memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME),0xFF,j);// G - else memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME),0x00,j);// G - if ((bgcolor>>2) & 0x1) memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME*2),0xFF,j);// B - else memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME*2),0x00,j);// B + if ((bgcolor>>1) & 0x1) memset((char*)m_scrbuf+POK_BITFRAME,0xFF,j);// G + else memset((char*)m_scrbuf+POK_BITFRAME,0x00,j);// G + if ((bgcolor>>2) & 0x1) memset((char*)m_scrbuf+POK_BITFRAME*2,0xFF,j);// B + else memset((char*)m_scrbuf+POK_BITFRAME*2,0x00,j);// B setCursor(0,0); return; - } else { + } else if (bpp==4) { c = (c & 0x0F) | (c << 4); } uint16_t j = sizeof(screenbuffer); @@ -621,12 +692,10 @@ clipX = x; clipY = y; clipW = w; clipH = h; } +void Display::drawPixelNOP(int16_t x,int16_t y, uint8_t col) { +} -void Display::drawPixel(int16_t x,int16_t y, uint8_t col) { - if (col==invisiblecolor) return; // do not draw transparent pixels - if ((uint16_t)x >= width || (uint16_t)y >= height) return; - col &= (PALETTE_SIZE-1); - +void Display::drawPixelRaw(int16_t x,int16_t y, uint8_t col) { #if POK_COLORDEPTH == 8 m_scrbuf[x+width*y] = col; #endif @@ -689,75 +758,16 @@ #endif // POK_GAMEBUINO_SUPPORT } +void Display::drawPixel(int16_t x,int16_t y, uint8_t col) { + if (col==invisiblecolor) return; // do not draw transparent pixels + if ((uint16_t)x >= width || (uint16_t)y >= height) return; + col &= (PALETTE_SIZE-1); + drawPixelRaw( x, y, col ); +} + void Display::drawPixel(int16_t x,int16_t y) { if ((uint16_t)x >= width || (uint16_t)y >= height) return; - - #if POK_COLORDEPTH == 8 - m_scrbuf[x+width*y] = color; - #endif - - #if POK_GAMEBUINO_SUPPORT > 0 - - uint8_t c = color; - uint8_t ct = color; - if(ct == INVERT){ - ct = !getPixel(x, y); //jonne - was c = !getP... - } - - uint16_t bitptr=0; - for (uint8_t cbit=0;cbit<POK_COLORDEPTH;cbit++) { - c = ct & 1; // take the lowest bit of the color index number - if(c == 0){ //white - or actually "Clear bit" - #if DISPLAY_ROT == NOROT - m_scrbuf[x + (y / 8) * LCDWIDTH + bitptr] &= ~_BV(y % 8); - #elif DISPLAY_ROT == ROTCCW - m_scrbuf[LCDHEIGHT - y - 1 + (x / 8) * LCDWIDTH_NOROT + bitptr] &= ~_BV(x % 8); - #elif DISPLAY_ROT == ROT180 - m_scrbuf[LCDWIDTH - x - 1 + ((LCDHEIGHT - y - 1) / 8) * LCDWIDTH_NOROT + bitptr] &= ~_BV((LCDHEIGHT - y - 1) % 8); - #elif DISPLAY_ROT == ROTCW - m_scrbuf[y + ((LCDWIDTH - x - 1) / 8) * LCDWIDTH_NOROT + bitbtr] &= ~_BV((LCDWIDTH - x - 1) % 8); - #endif - //return; //jonne - } else { //black - or actually "Set bit" - #if DISPLAY_ROT == NOROT - m_scrbuf[x + (y / 8) * LCDWIDTH + bitptr] |= _BV(y % 8); - #elif DISPLAY_ROT == ROTCCW - m_scrbuf[LCDHEIGHT - y - 1 + (x / 8) * LCDWIDTH_NOROT + bitptr] |= _BV(x % 8); - #elif DISPLAY_ROT == ROT180 - m_scrbuf[LCDWIDTH - x - 1 + ((LCDHEIGHT - y - 1) / 8) * LCDWIDTH_NOROT + bitptr] |= _BV((LCDHEIGHT - y - 1) % 8); - #elif DISPLAY_ROT == ROTCW - m_scrbuf[y + ((LCDWIDTH - x - 1) / 8) * LCDWIDTH_NOROT + bitptr] |= _BV((LCDWIDTH - x -1) % 8); - #endif - //return; //jonne - } - ct >>=1; // shift to get next bit - bitptr += POK_BITFRAME; // move one screen worth of buffer forward to get to the next color bit - } // POK_COLOURDEPTH - - #else - - /** NOT Gamebuino */ - #if POK_COLORDEPTH == 1 - if (color) {m_scrbuf[(y >> 3) * width + x] |= (0x80 >> (y & 7)); return;} - m_scrbuf[(y >> 3) * width + x] &= ~(0x80 >> (y & 7)); - #elif POK_COLORDEPTH == 2 - uint16_t i = y*(width>>2) + (x>>2); - uint8_t pixel = m_scrbuf[i]; - uint8_t column = x&0x03; - if (column==3) pixel = (pixel&0xFC)|(color); // bits 0-1 - else if (column==2) pixel = (pixel&0xF3)|(color<<2); // bits 2-3 - else if (column==1) pixel = (pixel&0xCF)|(color<<4); // bits 4-5 - else pixel = (pixel&0x3F)|(color<<6); // bits 6-7 - m_scrbuf[i] = pixel; - #elif POK_COLORDEPTH == 3 - #elif POK_COLORDEPTH == 4 - uint16_t i = y*(width>>1) + (x>>1); - uint8_t pixel = m_scrbuf[i]; - if (x&1) pixel = (pixel&0xF0)|(color); - else pixel = (pixel&0x0F) | (color<<4); - m_scrbuf[i] = pixel; - #endif // POK_COLORDEPTH - #endif // POK_GAMEBUINO_SUPPORT + drawPixelRaw( x, y, color ); } uint8_t Display::getPixel(int16_t x,int16_t y) { @@ -1496,6 +1506,7 @@ int16_t bitFrame = w * h / 8; for (i = 0; i < w; i++) { byteNum = i / 8; + //bitNum = i % 8; uint8_t bitcount=0; for (j = 0; j <= h/8; j++) { @@ -1518,7 +1529,8 @@ else if (m_colordepth==4) { /** 4bpp fast version */ - int16_t scrx,scry,xclip,xjump,scrxjump; + int16_t scrx,scry,xjump,scrxjump; + int16_t xclip; xclip=xjump=scrxjump=0; /** y clipping */ if (y<0) { h+=y; bitmap -= y*(w>>1); y=0;} @@ -1555,8 +1567,9 @@ uint8_t sourcepixel = *bitmap; if ((sourcepixel&0x0F) != invisiblecolor) { sourcepixel <<=4; - uint8_t targetpixel = *scrptr;// & 0x0F; - targetpixel |= sourcepixel; + volatile uint8_t targetpixel = *scrptr;// & 0x0F; + targetpixel &= 0xF; //clear upper nibble + targetpixel |= sourcepixel; //now OR it *scrptr = targetpixel; } //scrptr++; @@ -1566,9 +1579,11 @@ } bitmap += xjump; // needed if x<0 clipping occurs } else { /** ODD pixel starting line **/ + uint8_t sourcepixel; + uint8_t targetpixel; for (scrx = x; scrx < w+x-xclip; scrx+=2) { - uint8_t sourcepixel = *bitmap; - uint8_t targetpixel = *scrptr; + sourcepixel = *bitmap; + targetpixel = *scrptr; // store higher nibble of source pixel in lower nibble of target if((sourcepixel>>4)!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel >> 4 ); *scrptr = targetpixel; @@ -1579,6 +1594,12 @@ *scrptr = targetpixel; bitmap++; } + if (xclip) { + // last line, store higher nibble of last source pixel in lower nibble of last address + sourcepixel = *bitmap >> 4; + if(sourcepixel!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | sourcepixel; + *scrptr = targetpixel; + } bitmap+=xjump; } // increment the y jump in the scrptr @@ -1591,16 +1612,15 @@ /** 4bpp fast version */ if (m_colordepth==8) { - int16_t scrx,scry,xjump,scrxjump; - xjump=scrxjump=0; + int16_t scrx,scry;//,scrxjump; + int16_t xjump=0; /** y clipping */ if (y<0) { h+=y; bitmap -= y*w; y=0;} else if (y+h>height) { h -=(y-height);} /** x clipping */ if (x<0) { w+=x; xjump = (-x); bitmap += xjump; x=0;} else if (x+w>width) { - scrxjump = x; - xjump=(x+w-width)+scrxjump; + xjump=(x+w-width); w = width-x;} uint8_t* scrptr = m_scrbuf + (y*width + x); @@ -1614,8 +1634,8 @@ bitmap++; scrptr++; } - bitmap += xjump; // needed if x<0 clipping occurs - scrptr = scrptr + (width - w)+scrxjump; + bitmap += xjump; // needed if horizontal clipping occurs + scrptr = scrptr + (width - w); } return; } @@ -1779,83 +1799,105 @@ } // end for scry } -void Display::drawBitmapXFlipped(int16_t x, int16_t y, const uint8_t* bitmap) +void Display::drawBitmapDataXFlipped(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t* bitmap) { - int16_t w = *bitmap; - int16_t h = *(bitmap + 1); - bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height /** visibility check */ if (y<-h || y>height) return; //invisible if (x<-w || x>width) return; //invisible /** 1 bpp mode */ - if (m_colordepth<2) { - int16_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3; - for (i = 0; i < w; i++) { - byteNum = i / 8; - bitNum = i % 8; - for (j = 0; j < h; j++) { - uint8_t source = *(bitmap + j * byteWidth + byteNum); - if (source & (0x80 >> bitNum)) { - drawPixel(x + w - i, y + j); + if (m_colordepth<2) + { + int16_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3; + for (i = 0; i < w; i++) + { + byteNum = i / 8; + bitNum = i % 8; + for (j = 0; j < h; j++) + { + uint8_t source = *(bitmap + j * byteWidth + byteNum); + if (source & (0x80 >> bitNum)) + { + drawPixel(x + w - i, y + j); + } } } - } - return; + return; } /** 2 bpp mode */ - if (m_colordepth<4) { - int16_t i, j, byteNum, bitNum, byteWidth = w >> 2; - for (i = 0; i < w; i++) { - byteNum = i / 4; - bitNum = (i % 4)<<1; - for (j = 0; j < h; j++) { - uint8_t source = *(bitmap + j * byteWidth + byteNum); - uint8_t output = (source & (0xC0 >> bitNum)); - output >>= (6-bitNum); - if (output != invisiblecolor) { - setColor(output); - drawPixel(x + i, y + j); + else if (m_colordepth==2) + { + int16_t i, j, byteNum, bitNum, byteWidth = w >> 2; + for (i = 0; i < w; i++) + { + byteNum = i / 4; + bitNum = (i % 4)<<1; + for (j = 0; j < h; j++) + { + uint8_t source = *(bitmap + j * byteWidth + byteNum); + uint8_t output = (source & (0xC0 >> bitNum)); + output >>= (6-bitNum); + if (output != invisiblecolor) + { + setColor(output); + drawPixel(x + i, y + j); + } } } - } - return; + return; } - /** 4bpp fast version */ - int16_t scrx,scry,xclip,xjump,scrxjump; - xclip=xjump=scrxjump=0; - /** y clipping */ - if (y<0) { h+=y; bitmap -= y*(w>>1); y=0;} - else if (y+h>height) { h -=(y-height);} - /** x clipping */ - bitmap += ((w>>1)-1); //inverted! - if (x<0) { + else if (m_colordepth==4) + { + /** 4bpp fast version */ + int16_t scrx,scry,xclip,xjump,scrxjump; + xclip=xjump=scrxjump=0; + /** y clipping */ + if (y<0) + { + h+=y; + bitmap -= y*(w>>1); + y=0; + } + else if (y+h>height) + { + h -=(y-height); + } + /** x clipping */ + bitmap += ((w>>1)-1); //inverted! + if (x<0) + { xclip=(x&1)<<1; w+=x; xjump = ((-x)>>1); //bitmap += xjump; // do not clip left edge of source, as bitmap is inverted ! x=0; - } - else if (x+w>width) { + } + else if (x+w>width) + { xclip = (x&1)<<1; scrxjump = x&1; xjump=((x+w-width)>>1)+scrxjump; - w = width-x;} + w = width-x; + } - //uint8_t* scrptr = m_scrbuf + (y*(width>>1) + ((x+width)>>1)); - uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1)); - /** ONLY 4-bit mode for time being **/ - for (scry = y; scry < y+h; scry+=1) { - // for (scry = y; scry < y+2; scry+=1) { + //uint8_t* scrptr = m_scrbuf + (y*(width>>1) + ((x+width)>>1)); + uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1)); + /** ONLY 4-bit mode for time being **/ + for (scry = y; scry < y+h; scry+=1) + { + // for (scry = y; scry < y+2; scry+=1) { if (scry>=height) return; - if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/ + if ((x&1)==0) /** EVEN pixel starting line, very simple, just copypaste **/ + { //for (scrx = w+x-xclip-1; scrx >= x; scrx-=2) { - for (scrx = x; scrx < w+x-xclip; scrx+=2) { + for (scrx = x; scrx < w+x-xclip; scrx+=2) + { uint8_t sourcepixel = *(bitmap); - if (xclip) { - sourcepixel <<=4; - sourcepixel |= ((*(bitmap-1))>>4);//inverted! + if (xclip) + { + sourcepixel <<=4; + sourcepixel |= ((*(bitmap-1))>>4);//inverted! } uint8_t targetpixel = *scrptr; // NIBBLES ARE INVERTED BECAUSE PICTURE IS FLIPPED !!! @@ -1866,11 +1908,14 @@ scrptr++; } bitmap += w; // w*2 >> 1 because inverted and because 2 pixels per byte!! - if (xclip){ - if (w&1) { + if (xclip) + { + if (w&1) + { /**last pixel is odd pixel due to clipping & odd width*/ uint8_t sourcepixel = *bitmap; - if ((sourcepixel&0x0F) != invisiblecolor) { + if ((sourcepixel&0x0F) != invisiblecolor) + { sourcepixel <<=4; uint8_t targetpixel = *scrptr;// & 0x0F; targetpixel |= sourcepixel; @@ -1882,8 +1927,11 @@ scrptr++; } bitmap += xjump; // needed if x<0 clipping occurs - } else { /** ODD pixel starting line **/ - for (scrx = x; scrx < w+x-xclip; scrx+=2 ) { + } + else /** ODD pixel starting line **/ + { + for (scrx = x; scrx < w+x-xclip; scrx+=2 ) + { uint8_t sourcepixel = *bitmap; uint8_t targetpixel = *scrptr; // inverted !!! store lower nibble of source pixel in lower nibble of target @@ -1901,7 +1949,62 @@ } // increment the y jump in the scrptr scrptr = scrptr + ((width - w)>>1)+scrxjump; + } } + /** 8 bpp mode */ + else if (m_colordepth==8) + { + int16_t scrx,scry;//,scrxjump; + int16_t xjump=0; + /** y clipping */ + if (y<0) + { + h+=y; + bitmap -= y*w; + y=0; + } + else if (y+h>height) + { + h -=(y-height); + } + /** x clipping */ + if (x<0) + { + w+=x; + xjump = (-x); + bitmap += xjump; + x=0; + } + else if (x+w>width) + { + xjump=(x+w-width); + w = width-x; + } + + uint8_t* scrptr = m_scrbuf + (y*width + x) + w; + for (scry = y; scry < y+h; scry+=1) + { + if (scry>=height) return; + for (scrx = x; scrx < w+x; scrx++) + { + uint8_t sourcepixel = *bitmap; + uint8_t targetpixel = *scrptr; + if (sourcepixel != invisiblecolor ) + targetpixel = sourcepixel; + *scrptr = targetpixel; + bitmap++; + scrptr--; + } + bitmap += xjump; // needed if horizontal clipping occurs + scrptr = scrptr + (width + w); + } + return; + } +} + +void Display::drawBitmapXFlipped(int16_t x, int16_t y, const uint8_t* bitmap) +{ + drawBitmapDataXFlipped(x, y, bitmap[0], bitmap[1], bitmap + 2); } void Display::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t rotation, uint8_t flip) { @@ -2338,6 +2441,7 @@ } } + void Display::draw4BitColumn(int16_t x, int16_t y, uint8_t h, uint8_t* bitmap) { int8_t scry; @@ -2441,6 +2545,14 @@ lcdRefreshMode13(m_scrbuf, paletteptr, palOffset); #endif +#if POK_SCREENMODE == MIXMODE + lcdRefreshMixMode(m_scrbuf, paletteptr, scanType); +#endif + +#if POK_SCREENMODE == MODE64 + lcdRefreshMode64(m_scrbuf, paletteptr); +#endif + #if POK_SCREENMODE == MODE_GAMEBOY lcdRefreshModeGBC(scr, paletteptr); #endif @@ -2476,6 +2588,8 @@ m_tilebuf[i]=t; }; + + // Convert an integer to a hexadecimal string char* itoa_hex(int num, char* dest, int destLen) { int i = destLen-1; @@ -2489,6 +2603,7 @@ } // Draw the crash screen and wait forever +#define STR_TO_UPPER(str_from, str_to) for( int32_t i=0; i <= strlen(str_from); i++ ) str_to[i] = toupper(str_from[i]); void ShowCrashScreenAndWait( const char* texLine1, const char* texLine2, const char* texLine3, const char* texLine4, const char* texLine5 ) { // draw screen red @@ -2505,15 +2620,17 @@ Display::fixedWidthFont = true; // Needed for the non-proportional C64 font (default value=false) Display::enableDirectPrinting(true); + char convertedStr[128] = {0}; + // Draw texts int yOffsetInPixels = 5; Display::set_cursor(0, 9 + yOffsetInPixels); - Display::print(" "); Display::println(texLine1); - Display::print(" "); Display::println(texLine2); - Display::print(" "); Display::println(texLine3); + Display::print(" "); STR_TO_UPPER(texLine1, convertedStr); Display::println(convertedStr); + Display::print(" "); STR_TO_UPPER(texLine2, convertedStr); Display::println(convertedStr); + Display::print(" "); STR_TO_UPPER(texLine3, convertedStr); Display::println(convertedStr); Display::println(); - Display::print(" *"); Display::println(texLine4); - Display::print(" *"); Display::println(texLine5); + Display::print(" *"); STR_TO_UPPER(texLine4, convertedStr); Display::println(convertedStr); + Display::print(" *"); STR_TO_UPPER(texLine5, convertedStr); Display::println(convertedStr); Display::set_cursor(0, 0 + yOffsetInPixels);