Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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:
- 35:4f7edccf8ed6
- Parent:
- 31:f4b9b85c7b62
- Child:
- 42:798b5d67b372
--- a/POKITTO_CORE/PokittoDisplay.cpp Sat Mar 24 13:17:22 2018 +0000
+++ b/POKITTO_CORE/PokittoDisplay.cpp Mon Apr 02 22:37:04 2018 +0000
@@ -78,6 +78,10 @@
#include "SimLCD.h"
#endif
+//extern "C" void CheckStack();
+//extern char _ebss[]; // In map file
+//extern char _vStackTop[]; // In map file
+
Pokitto::Core core;
Pokitto::Sound _pdsound;
@@ -147,6 +151,18 @@
uint8_t Display::width = 160;
uint8_t Display::height = 144;
uint8_t Display::screenbuffer[160*144/4];
+#elif (POK_SCREENMODE == MODE14)
+ uint8_t Display::width = 220;
+ uint8_t Display::height = 176;
+ uint8_t Display::screenbuffer[14520];
+#elif (POK_SCREENMODE == MODE13)
+ uint8_t Display::width = 110;
+ uint8_t Display::height = 88;
+ uint8_t Display::screenbuffer[110*88]; // 8bit 110x88
+#elif (POK_SCREENMODE == MODE15)
+ uint8_t Display::width = 220;
+ uint8_t Display::height = 176;
+ uint8_t Display::screenbuffer[0x4BA0];
#else
uint8_t Display::width = 84;
uint8_t Display::height = 48;
@@ -264,6 +280,9 @@
// For the screen modes that do not support sprites, return if the direct draw mode is used.
if (! useDirectDrawMode) {
+ #if POK_SCREENMODE == MODE13
+ lcdRefreshMode13(m_scrbuf, paletteptr, palOffset);
+ #endif
#if POK_SCREENMODE == MODE_GAMEBOY
lcdRefreshModeGBC(m_scrbuf, paletteptr);
@@ -285,6 +304,14 @@
lcdRefreshAB(m_scrbuf, paletteptr);
#endif
+ #if POK_SCREENMODE == MODE14
+ lcdRefreshMode14(m_scrbuf, paletteptr);
+ #endif
+
+ #if POK_SCREENMODE == MODE15
+ lcdRefreshMode15(paletteptr, m_scrbuf);
+ #endif
+
#if POK_SCREENMODE == MODE_TILED_1BIT
lcdRefreshT1(m_tilebuf, m_tilecolorbuf, m_tileset, paletteptr);
#endif
@@ -301,37 +328,42 @@
#endif // POK_SHOW_VOLUME
/** draw FPS if visible **/
- #ifdef PROJ_USE_FPS_COUNTER
+ #ifdef PROJ_SHOW_FPS_COUNTER
+
+ if(core.fps_counter_updated) {
- // Store current state
- bool temp = isDirectPrintingEnabled();
- uint16_t oldcol = directcolor;
- uint16_t oldinvisiblecolor = invisiblecolor;
- uint16_t oldbgcol = directbgcolor;
- bool olddirecttextrotated = directtextrotated;
- int8_t oldadjustCharStep = adjustCharStep;
- const unsigned char * oldFont = font;
+ // Store current state
+ bool temp = isDirectPrintingEnabled();
+ uint16_t oldcol = directcolor;
+ uint16_t oldinvisiblecolor = invisiblecolor;
+ uint16_t oldbgcol = directbgcolor;
+ bool olddirecttextrotated = directtextrotated;
+ int8_t oldadjustCharStep = adjustCharStep;
+ const unsigned char * oldFont = font;
- // Print FPS
- char str[16];
- sprintf(str,"FPS:%d ", (int)core.fps_counter);
- directcolor = COLOR_WHITE;
- invisiblecolor = COLOR_BLACK;
- directbgcolor = 0x0001; // Cannot be black as that is transparent color
- directtextrotated = true;
- adjustCharStep = 0;
- setFont(fontC64);
- enableDirectPrinting(true);
- print(0,0, str);
+ // Print FPS
+ char str[16];
+ sprintf(str,"FPS:%d ", (int)core.fps_counter);
+ directcolor = COLOR_WHITE;
+ invisiblecolor = COLOR_BLACK;
+ directbgcolor = 0x0001; // Cannot be black as that is transparent color
+ directtextrotated = true;
+ adjustCharStep = 0;
+ setFont(fontC64);
+ enableDirectPrinting(true);
+ print(0,0, str);
- // Restore state
- enableDirectPrinting(temp);
- directcolor = oldcol;
- invisiblecolor = oldinvisiblecolor;
- directbgcolor = oldbgcol;
- directtextrotated = olddirecttextrotated;
- adjustCharStep = oldadjustCharStep;
- setFont(font);
+ // Restore state
+ enableDirectPrinting(temp);
+ directcolor = oldcol;
+ invisiblecolor = oldinvisiblecolor;
+ directbgcolor = oldbgcol;
+ directtextrotated = olddirecttextrotated;
+ adjustCharStep = oldadjustCharStep;
+ setFont(font);
+
+ core.fps_counter_updated = false;
+ }
#endif
}
@@ -475,6 +507,16 @@
c = bgcolor & 0x3;
c = c | (c << 2);
c = c | (c << 4);
+ } else if (bpp==3){
+ 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*)m_scrbuf+POK_BITFRAME,0xFF,j);// G
+ else memset((void*)m_scrbuf+POK_BITFRAME,0x00,j);// G
+ if ((bgcolor>>2) & 0x1) memset((void*)m_scrbuf+POK_BITFRAME*2,0xFF,j);// B
+ else memset((void*)m_scrbuf+POK_BITFRAME*2,0x00,j);// B
+ setCursor(0,0);
+ return;
} else {
c = (c & 0x0F) | (c << 4);
}
@@ -602,6 +644,20 @@
else pixel = (pixel&0x3F)|(col<<6); // bits 6-7
m_scrbuf[i] = pixel;
#elif POK_COLORDEPTH == 3
+ uint8_t c = col;
+ uint8_t ct = col;
+
+ 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"
+ m_scrbuf[x + (y / 8) * LCDWIDTH + bitptr] &= ~_BV(y % 8);
+ } else { //black - or actually "Set bit"
+ m_scrbuf[x + (y / 8) * LCDWIDTH + bitptr] |= _BV(y % 8);
+ }
+ 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
#elif POK_COLORDEPTH == 4
uint16_t i = y*(width>>1) + (x>>1);
uint8_t pixel = m_scrbuf[i];
@@ -685,6 +741,11 @@
uint8_t Display::getPixel(int16_t x,int16_t y) {
if ((uint16_t)x >= width || (uint16_t)y >= height) return 0;
+ #if POK_COLORDEPTH == 8
+ uint16_t i = y*width+x;
+ return m_scrbuf[i];
+ #endif // POK_COLORDEPTH
+
#if POK_GAMEBUINO_SUPPORT
uint8_t color=0; //jonne
for (uint8_t cbit=0; cbit<POK_COLORDEPTH;cbit++) {
@@ -1363,7 +1424,7 @@
return;
}
/** 2 bpp mode */
- if (m_colordepth<4) {
+ else if (m_colordepth==2) {
if(clipH > 0) {
// Clip
@@ -1409,6 +1470,35 @@
}
return;
}
+
+ /** 3 bpp mode */
+ else if (m_colordepth==3) {
+ int16_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
+ 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++) {
+ uint8_t r_val = *(bitmap + j * byteWidth + byteNum);
+ uint8_t g_val = *(bitmap + bitFrame + j * byteWidth + byteNum);
+ uint8_t b_val = *(bitmap + (bitFrame<<1) + j * byteWidth + byteNum);
+ for (bitcount=0; bitcount<8; bitcount++) {
+ uint8_t col = (r_val&0x1) | ((g_val&0x1)<<1) | ((b_val&0x1)<<2);
+ r_val >>= 1; g_val >>= 1; b_val >>= 1;
+ drawPixel(x + i, y + j+bitcount,col);
+ }
+ }
+ }
+
+ return;
+ }
+
+
+ /** 4bpp fast version */
+ else if (m_colordepth==4) {
+
/** 4bpp fast version */
int16_t scrx,scry,xclip,xjump,scrxjump;
xclip=xjump=scrxjump=0;
@@ -1447,7 +1537,7 @@
uint8_t sourcepixel = *bitmap;
if ((sourcepixel&0x0F) != invisiblecolor) {
sourcepixel <<=4;
- uint8_t targetpixel = *scrptr & 0x0F;
+ uint8_t targetpixel = *scrptr;// & 0x0F;
targetpixel |= sourcepixel;
*scrptr = targetpixel;
}
@@ -1458,7 +1548,6 @@
}
bitmap += xjump; // needed if x<0 clipping occurs
} else { /** ODD pixel starting line **/
- //for (scrx = x; scrx < w+x-xclip; scrx+=2) {
for (scrx = x; scrx < w+x-xclip; scrx+=2) {
uint8_t sourcepixel = *bitmap;
uint8_t targetpixel = *scrptr;
@@ -1472,24 +1561,49 @@
*scrptr = targetpixel;
bitmap++;
}
- if (xclip){
- if (w&1) {
- /**last pixel is odd pixel due to clipping & odd width*/
- uint8_t sourcepixel = *bitmap;
- sourcepixel >>=4; //top nibble of sourcebyte from bitmap...
- if (sourcepixel != invisiblecolor) {
- uint8_t targetpixel = *scrptr & 0xF0; //...put into the low nibble of the target
- targetpixel |= sourcepixel;
- *scrptr = targetpixel;
- }
- //scrptr++;
- }
- }
bitmap+=xjump;
}
// increment the y jump in the scrptr
scrptr = scrptr + ((width - w)>>1)+scrxjump;
}
+
+ return;
+ }
+
+ /** 4bpp fast version */
+
+ if (m_colordepth==8) {
+ int16_t scrx,scry,xclip,xjump,scrxjump;
+ xclip=xjump=scrxjump=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) { xclip=x; w+=x; xjump = (-x); bitmap += xjump; x=0;}
+ else if (x+w>width) {
+ xclip = x;
+ scrxjump = x;
+ xjump=(x+w-width)+scrxjump;
+ w = width-x;}
+
+ uint8_t* scrptr = m_scrbuf + (y*width + x);
+ 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 x<0 clipping occurs
+ scrptr = scrptr + (width - w)+scrxjump;
+ }
+ return;
+ }
+
+
}
void Display::drawRleBitmap(int16_t x, int16_t y, const uint8_t* rlebitmap)
@@ -2276,7 +2390,7 @@
}
m_sprites[index].w = w;
m_sprites[index].h = h;
- memcpy(m_sprites[index].palette, palette4x16bit, 4*2);
+ if( palette4x16bit ) memcpy(m_sprites[index].palette, palette4x16bit, 4*2);
}
/**
@@ -2304,6 +2418,9 @@
// For the screen modes that do not support sprites, return if the direct draw mode is used.
if (useDirectDrawMode) return;
+#if POK_SCREENMODE == MODE13
+ lcdRefreshMode13(m_scrbuf, paletteptr, palOffset);
+#endif
#if POK_SCREENMODE == MODE_GAMEBOY
lcdRefreshModeGBC(scr, paletteptr);
@@ -2340,6 +2457,99 @@
m_tilebuf[i]=t;
};
+// Convert an integer to a hexadecimal string
+char* itoa_hex(int num, char* dest, int destLen) {
+ int i = destLen-1;
+ do {
+ char c = (num % 16) + '0';
+ if (c > '9') c += 7;
+ dest[i--] = c;
+ num /= 16;
+ } while (num && i >= 0);
+ return &(dest[i+1]);
+}
+
+// Draw the crash screen and wait forever
+void ShowCrashScreenAndWait( const char* texLine1, const char* texLine2, const char* texLine3, const char* texLine4, const char* texLine5 ) {
+
+ // draw screen red
+ lcdFillSurface(COLOR_RED);
+
+ // Draw text
+ Display::directcolor = COLOR_WHITE;
+ Display::invisiblecolor = COLOR_RED;
+ Display::directbgcolor = COLOR_RED; // Cannot be black as that is a transparent color
+ Display::directtextrotated = false;
+ Display::adjustCharStep = 0;
+ Display::adjustLineStep = 0;
+ Display::setFont(fntC64UIGfx); // A special font set that contains UI gfx in lower case letters.
+ Display::fixedWidthFont = true; // Needed for the non-proportional C64 font (default value=false)
+ Display::enableDirectPrinting(true);
+
+ // 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::println();
+ Display::print(" *"); Display::println(texLine4);
+ Display::print(" *"); Display::println(texLine5);
+
+ Display::set_cursor(0, 0 + yOffsetInPixels);
+
+ // Frame
+ Display::println(" abbbbbbbbbbbbbbbbbbbbbbbbc");
+ Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
+ Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
+ Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
+ Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
+ Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
+ Display::print (" |"); Display::println(26*8, Display::cursorY,"|");
+ Display::println(" dbbbzybbbbbbbbbbbbbbbbbbbe");
+ Display::println(" {e");
+
+ // Pokitto image
+ Display::println ("");
+ Display::println (" ijkl");
+ Display::println (" mnop");
+ Display::println (" qrst");
+ Display::println (" uvwx");
+
+ // loop forever
+ while(1){;}
+ }
+
+// Check the stack size and show a crash screen if the stack is too big.
+/*void CheckStack() {
+ #ifndef POK_SIM
+ int currStackTop;
+ const int freeStackThreshold = 400;
+ if ((int)&currStackTop - (int)_ebss < freeStackThreshold) {
+
+ // Create info string: "<stack size>:<current stack pointer>", e.g. "12345ABC:12345ABC"
+ const int infoStringLen = 8+1+8;
+ static char infoString[infoStringLen+1];
+ memset(infoString,0,infoStringLen+1);
+ const int stackSize = (int)_vStackTop - (int)&currStackTop;
+ const int tmpStrLen = 8;
+ static char tmpStr[tmpStrLen+1];
+ memset(tmpStr,0,tmpStrLen+1);
+ char* subStr = itoa_hex(stackSize, tmpStr, tmpStrLen); // keep ending null
+ strcat(infoString, subStr); // Add stack size as hex string
+ strcat(infoString, ":");
+ subStr = itoa_hex((int)&currStackTop, tmpStr, tmpStrLen); // keep ending null
+ strcat(infoString, subStr); // Add stack pointer address as hex string
+
+ // Draw the crash screen and wait forever. Use static const strings to avoid more stack usage.
+ static const char* texLine1 = "OOPS! PLEASE, RESTART";
+ static const char* texLine2 = "POKITTO OR RELOAD";
+ static const char* texLine3 = "SOFTWARE.";
+ static const char* texLine4 = "STACK TOO BIG!";
+ ShowCrashScreenAndWait(texLine1, texLine2, texLine3, texLine4, infoString);
+ }
+ #endif
+}*/
/** Eof */