Jonne Valola / PokittoLib Featured

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

PokittoLib

Library for programming Pokitto hardware

How to Use

  1. Import this library to online compiler (see button "import" on the right hand side
  2. DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
  3. Change My_settings.h according to your project
  4. Start coding!

Files at this revision

API Documentation at this revision

Comitter:
Pokitto
Date:
Fri Dec 29 05:17:10 2017 +0000
Parent:
22:e826f80d8582
Child:
24:9561281d0378
Commit message:
PokittoLib mbed and Github are back in sync with all contributions from Hanski and Spinal included

Changed in this revision

POKITTO_CORE/PokittoButtons.cpp Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoConsole.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoCore.cpp Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoCore.h Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoDisplay.cpp Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoDisplay.h Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoSound.cpp Show diff for this revision Revisions of this file
POKITTO_HW/HWButtons.cpp Show diff for this revision Revisions of this file
POKITTO_HW/HWLCD.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_HW/HWLCD.h Show diff for this revision Revisions of this file
POKITTO_LIBS/ImageFormat/BmpImage.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/ImageFormat/ImageFormat.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/ImageFormat/defines_linux_SIM.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/ImageFormat/defines_win_SIM.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/ImageFormat/helpers.h Show annotated file Show diff for this revision Revisions of this file
Pokitto_settings.h Show annotated file Show diff for this revision Revisions of this file
--- a/POKITTO_CORE/PokittoButtons.cpp	Fri Dec 29 02:55:34 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,261 +0,0 @@
-/**************************************************************************/
-/*!
-    @file     PokittoButtons.cpp
-    @author   Jonne Valola
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2016, Jonne Valola
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-#include "PokittoCore.h"
-
-using namespace Pokitto;
-
-uint8_t Buttons::pins[NUM_BTN];
-uint8_t Buttons::states[NUM_BTN];
-uint8_t Buttons::buttons_state;
-uint8_t Buttons::buttons_held;
-uint8_t Buttons::buttons_released; // from LSB up,down,left,right,a,b,c
-uint16_t Buttons::cHWLongPress = CHWLONGPRESSTIMEOUT;
-
-
-void Buttons::begin() {
-    #ifndef POK_SIM
-    Pokitto::initButtons();
-    #endif // POK_SIM
-}
-
-void Buttons::update() {
-    #if POK_USE_CONSOLE > 0
-    if (console.conscounter) return;
-    #endif // POK_USE_CONSOLE
-    #ifndef POK_SIM
-        /** HARDWARE CODE **/
-    for (uint8_t thisButton = 0; thisButton < NUM_BTN; thisButton++) {
-        if (Pokitto::heldStates[thisButton]) { //if button pressed
-            states[thisButton]++; //increase button hold time
-        } else {
-            if (states[thisButton] == 0)//button idle
-                continue;
-            if (states[thisButton] == 0xFF)//if previously released
-                states[thisButton] = 0; //set to idle
-            else
-                states[thisButton] = 0xFF; //button just released
-        }
-        }
-    #else
-        /** POK_SIM code **/
-        simulator.pollButtons();
-        for (uint8_t thisButton = 0; thisButton < NUM_BTN; thisButton++) {
-        uint8_t temp=0;
-        switch (thisButton) {
-        case 0:
-            temp = simulator.leftHeld(); break;
-        case 1:
-            temp = simulator.upHeld(); break;
-        case 2:
-            temp = simulator.rightHeld(); break;
-        case 3:
-            temp = simulator.downHeld(); break;
-        case 4:
-            temp = simulator.aHeld(); break;
-        case 5:
-            temp = simulator.bHeld(); break;
-        case 6:
-            temp = simulator.cHeld(); break;
-        default:
-            break;
-        }
-
-        if (temp == HIGH) { //if button pressed
-            states[thisButton]++; //increase button hold time
-        } else {
-            if (states[thisButton] == 0)//button idle
-                continue;
-            if (states[thisButton] == 0xFF)//if previously released
-                states[thisButton] = 0; //set to idle
-            else
-                states[thisButton] = 0xFF; //button just released
-        }
-        }
-
-        #endif // POK_SIM
-}
-
-/*
- * Returns true when 'button' is pressed.
- * The button has to be released for it to be triggered again.
- */
-bool Buttons::pressed(uint8_t button) {
-    if (states[button] == 1)
-        return true;
-    else
-        return false;
-}
-
-/*
- * return true if 'button' is released
- */
-bool Buttons::released(uint8_t button) {
-    if (states[button] == 0xFF)
-        return true;
-    else
-        return false;
-}
-
-/**
- * returns true ONCE when 'button' is held for 'time' frames
- * @param button The button's ID
- * @param time How much frames button must be held, between 1 and 254.
- * @return true when 'button' is held for 'time' frames
- */
-bool Buttons::held(uint8_t button, uint8_t time){
-    if(states[button] == (time+1))
-        return true;
-    else
-        return false;
-}
-
-/**
- * returns true every 'period' frames when 'button' is held
- * @param button The button's ID
- * @param period How much frames button must be held, between 1 and 254.
- * @return true if the button is held for the given time
- */
-bool Buttons::repeat(uint8_t button, uint8_t period) {
-    if (period <= 1) {
-        if ((states[button] != 0xFF) && (states[button]))
-            return true;
-    } else {
-        if ((states[button] != 0xFF) && ((states[button] % period) == 1))
-            return true;
-    }
-    return false;
-}
-
-/**
- *
- * @param button The button's ID
- * @return The number of frames during which the button has been held.
- */
-uint8_t Buttons::timeHeld(uint8_t button){
-    if(states[button] != 0xFF)
-        return states[button];
-    else
-        return 0;
-
-}
-
-void Buttons::pollButtons() {
-    #ifdef POK_SIM
-    simulator.pollButtons();
-    #else
-    uint8_t buttons_state_old = buttons_state;
-    buttons_state = 0; // clear all
-    if (upBtn()) buttons_state |= (1<<UPBIT);
-    if (downBtn()) buttons_state |= (1<<DOWNBIT);
-    if (leftBtn()) buttons_state |= (1<<LEFTBIT);
-    if (rightBtn()) buttons_state |= (1<<RIGHTBIT);
-    if (aBtn()) buttons_state |= (1<<ABIT);
-    if (bBtn()) buttons_state |= (1<<BBIT);
-    if (cBtn()) buttons_state |= (1<<CBIT);
-    buttons_held = buttons_state & buttons_state_old; // only if both 1, end result is 1
-    buttons_released = ~buttons_state & buttons_state_old; // if now zero, then 1 AND previous 1 = 1
-    #endif // POK_SIM
-}
-
-uint8_t Buttons::aBtn() {
-    #ifdef POK_SIM
-    return simulator.aBtn();
-    #else
-    return Pokitto::heldStates[BTN_A];
-    #endif // POK_SIM
-}
-
-
-uint8_t Buttons::bBtn() {
-    #ifdef POK_SIM
-    return simulator.bBtn();
-    #else
-    return Pokitto::heldStates[BTN_B];
-    #endif // POK_SIM
-}
-
-uint8_t Buttons::cBtn() {
-    uint8_t c;
-    #ifdef POK_SIM
-    c = simulator.cBtn();
-    #else
-    c = Pokitto::heldStates[BTN_C];
-    #endif // POK_SIM
-    return c;
-}
-
-uint8_t Buttons::leftBtn() {
-    #ifdef POK_SIM
-    return simulator.leftBtn();
-    #else
-    return Pokitto::heldStates[BTN_LEFT];
-    #endif // POK_SIM
-}
-
-uint8_t Buttons::rightBtn() {
-    #ifdef POK_SIM
-    return simulator.rightBtn();
-    #else
-    return Pokitto::heldStates[BTN_RIGHT];
-    #endif // POK_SIM
-}
-
-uint8_t Buttons::upBtn() {
-    #ifdef POK_SIM
-    return simulator.upBtn();
-    #else
-    return Pokitto::heldStates[BTN_UP];
-    #endif // POK_SIM
-}
-
-uint8_t Buttons::downBtn() {
-    #ifdef POK_SIM
-    return simulator.downBtn();
-    #else
-    return Pokitto::heldStates[BTN_DOWN];
-    #endif // POK_SIM
-}
-
-
-
-
-
-
-
-
-//** EOF **//
-
--- a/POKITTO_CORE/PokittoConsole.cpp	Fri Dec 29 02:55:34 2017 +0000
+++ b/POKITTO_CORE/PokittoConsole.cpp	Fri Dec 29 05:17:10 2017 +0000
@@ -311,3 +311,4 @@
 
 
 
+
--- a/POKITTO_CORE/PokittoCore.cpp	Fri Dec 29 02:55:34 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1252 +0,0 @@
-/**************************************************************************/
-/*!
-    @file     PokittoCore.cpp
-    @author   Jonne Valola
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2016, Jonne Valola
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-#include "PokittoCore.h"
-#include "Pokitto_settings.h"
-#include "PokittoConsole.h"
-#include "PokittoFonts.h"
-#include "PokittoTimer.h"
-#include "PokittoLogos.h"
-#include <stdlib.h>
-#ifndef DISABLEAVRMIN
-#define max(a,b) ((a)>(b)?(a):(b))
-#endif // DISABLEAVRMIN
-
-char selectedfile[25];
-
-//#define F
-#ifdef __ARMCC_VERSION
-typedef void (*func_t)(void);
-#endif
-
-#ifndef POK_SIM
-#include "iap.h"
-/** start the user application
-* https://community.nxp.com/thread/417695
-*
-*/
-void start_application(unsigned long app_link_location){
-    //asm(" ldr sp, [r0,#0]");
-    //asm(" ldr pc, [r0,#4]");
-    //This code is not valid for the Cortex-m0+ instruction set.
-    // The equivalent for this (as used by the KL26) is
-__disable_irq();// Start by disabling interrupts, before changing interrupt vectors
-
-// delete buttons
-//pokDeleteButtons();
-
-// completely kill button interrupts in preparation for reset
-LPC_PINT->IENR = 0;
-LPC_PINT->IENF = 0;
-
-SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk & ~(SysTick_CTRL_ENABLE_Msk); //disable systick
-LPC_SYSCON->PDRUNCFG     |=  (1 << 10);       /* Power-down USB PHY         */
-LPC_SYSCON->PDRUNCFG     |=  (1 <<  8);       /* Power-down USB PLL         */
-
-// reset clock source to IRC
-LPC_SYSCON->MAINCLKUEN    = 0x01;             /* Update MCLK Clock Source   */
-LPC_SYSCON->MAINCLKUEN    = 0x00;             /* Toggle Update Register     */
-while (LPC_SYSCON->MAINCLKUEN & 0x01);     /* Wait Until Updated         */
-// switch clock selection to IRC
-LPC_SYSCON->MAINCLKSEL    = 0;             /* Select Clock Source        */
-LPC_SYSCON->MAINCLKUEN    = 0x01;             /* Update MCLK Clock Source   */
-LPC_SYSCON->MAINCLKUEN    = 0x00;             /* Toggle Update Register     */
-while (LPC_SYSCON->MAINCLKUEN & 0x01);     /* Wait Until Updated         */
-//disable PLL clock output
-LPC_SYSCON->SYSPLLCLKUEN = 0;
-while (LPC_SYSCON->SYSPLLCLKUEN & 0x00);
-LPC_SYSCON->SYSPLLCTRL = 0;
-
-//kill peripherals
-LPC_SYSCON->MAINCLKSEL = 0;
-LPC_SYSCON->PRESETCTRL = 0; //disable all peripherals
-
-//power down PLL
-volatile uint32_t tmp;
-tmp = (LPC_SYSCON->PDRUNCFG & 0x000025FFL);
-tmp |= ((1<<7) & 0x000025FFL);
-LPC_SYSCON->PDRUNCFG = (tmp | 0x0000C800L); /* Power-down SYSPLL          */
-
-//Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_IRC); //switch to IRC
-
-// clear all gpio states
-LPC_GPIO_PORT->PIN[0] = 0;
-LPC_GPIO_PORT->PIN[1] = 0;
-LPC_GPIO_PORT->PIN[2] = 0;
-
-SCB->VTOR = app_link_location;//APPL_ADDRESS; /* Change vector table address */
-#ifndef __ARMCC_VERSION
-asm(" mov r0, %[address]"::[address] "r" (app_link_location));
-asm(" ldr r1, [r0,#0]"); // get the stack pointer value from the program's reset vector
-asm(" mov sp, r1");      // copy the value to the stack pointer
-asm(" ldr r0, [r0,#4]"); // get the program counter value from the program's reset vector
-asm(" blx r0");          // jump to the' start address
-#else
-uint32_t *app_loc = (uint32_t*)app_link_location;
-__set_MSP (app_loc[0]);
-((func_t)(app_loc[1]))();
-#endif
-}
-#endif
-
-// returns a random integar between 0 and maxVal
-int random(int maxVal)
-{
-  return random( 0, maxVal);
-}
-
-// returns a random integar between minVal and maxVal
-int random(int minVal, int maxVal)
-{
-  // int rand(void); included by default from newlib
-  return rand() % (maxVal-minVal+1) + minVal;
-}
-
-using namespace Pokitto;
-
-bool Core::run_state; // this definition needed
-
-/** Components */
-Backlight Core::backlight;
-Buttons Core::buttons;
-Battery Core::battery;
-#if POK_ENABLE_SOUND > 0
-Sound Core::sound;
-#endif
-Display Core::display;
-
-//GB Related
-uint8_t Core::startMenuTimer;
-uint8_t Core::timePerFrame;
-uint32_t Core::nextFrameMillis;
-uint32_t Core::frameCount;
-const char* Core::popupText;
-uint8_t Core::popupTimeLeft;
-uint16_t Core::frameDurationMicros;
-uint32_t Core::frameStartMicros, Core::frameEndMicros;
-uint8_t Core::volbar_visible=0;
-
-
-Core::Core() {
-
-}
-
-
-int Core::updateLoader (uint32_t version, uint32_t jumpaddress) {
-    uint32_t counter=0;
-    uint8_t data[256];
-    /** prepare the flash writing **/
-    float progress=0;
-    int opg=-1;
-    uint32_t fsize=0;
-    fileEnd(); //
-    fsize = fileGetPosition();
-    if (fsize>0x40000-jumpaddress) fsize = 0x40000-jumpaddress; // shouldn't happen!!
-    fileRewind();
-    display.println("PLEASE WAIT");
-    while (1) {
-        //if (counter >= fsize-0x200) {
-        //    display.println("gotcha");
-        //}
-        if (counter >= fsize) {
-                break;
-        }
-        opg=progress;
-        if (fileReadBytes(&data[0],0x100)<0x100) {
-                if (fsize-counter>0x100) {
-                        display.println("ERROR READING LOA.DER FILE");
-                        return 1; // 1 means error
-                }
-        }
-        if (CopyPageToFlash(jumpaddress+counter,data)) {
-                    display.println("FLASH WRITE ERROR");
-                    return 1;
-        } else {
-            counter += 0x100;
-            display.print(".");
-        }
-        }
-    return 0; //success
-}
-
-void Core::showWarning() {
-    display.enableDirectPrinting(true);
-    display.directbgcolor = COLOR_BLACK;
-    display.clearLCD();
-    display.directcolor = COLOR_RED;
-    display.setFont(fntC64UIGfx);
-    display.adjustCharStep = 0;
-    display.adjustLineStep = 0;
-    display.setCursor(10*8,9);
-    display.print("WARNING!");
-    display.directcolor = COLOR_WHITE;
-    display.setCursor(5*8,4*9);
-    display.print("LOUD SOUND THROUGH");
-    display.setCursor(2*8,5*9);
-    display.print("HEADPHONES COULD DAMAGE");
-    display.setCursor(7*8,6*9);
-    display.print("YOUR HEARING.");
-    display.setCursor(5*8,8*9);
-    display.print("USE "); display.directcolor = COLOR_GREEN;
-    display.print("0-100% VOLUME");
-    display.directcolor = COLOR_WHITE;
-    display.setCursor(5*8,9*9);
-    display.print("FOR LISTENING WITH");
-    display.setCursor(8*8,10*9);
-    display.print("HEADPHONES");
-    display.setCursor(5*8,12*9);
-    display.print("USE "); display.directcolor = COLOR_RED;
-    display.print("> 100% VOLUME"); display.directcolor = COLOR_GREEN;
-    display.directcolor = COLOR_WHITE;
-    display.setCursor(1*8,13*9);
-    display.print("ONLY FOR LISTENING VIA THE");
-    display.setCursor(5*8,14*9);
-    display.print("BUILT-IN SPEAKER");
-    display.setCursor(5*8,17*9);
-    display.print("PRESS ");display.directcolor = COLOR_GREEN;
-    display.print("C ");display.directcolor = COLOR_WHITE;
-    display.print("TO ACCEPT");
-    while (!buttons.cBtn()) {
-        wait(100);
-    }
-    display.clearLCD();
-    display.enableDirectPrinting(false);
-}
-
-void Core::jumpToLoader() {
-    //display.setFont(font5x7);
-    //display.adjustCharStep=1;
-    //display.adjustLineStep=2;
-    display.fontSize=1;
-    display.directbgcolor=COLOR_BLACK;
-    display.directcolor=COLOR_GREEN;
-    display.clearLCD();
-    display.setCursor(0,0);
-    display.enableDirectPrinting(true);
-    #ifdef POK_SIM
-    display.println("LOADER IS NOT AVAILABLE ON THE SIMULATOR. PRESS A TO RETURN.");
-    #else
-    uint32_t* bootinfo;
-    uint32_t bootversion=0, sdversion=0, sdjump=0;
-    bool flashloader=false, checkforboot=true;
-    //check for loa.der on SD card
-    #if POK_ENABLE_LOADER_UPDATES > 0
-    pokInitSD();
-    if (fileOpen("LOA.DER", FILE_MODE_BINARY)==0) {
-        //LOA.DER found on SD
-        fileEnd(); // go to end
-        fileSeekRelative(-8); //rewind 8 bytes
-        uint32_t* tptr = &sdversion;
-        fileReadBytes((uint8_t*)tptr,4); //read version number of loader on SD card
-        tptr = &sdjump;
-        fileReadBytes((uint8_t*)tptr,4); //read jump address of loader on sd card
-        fileRewind();
-    }
-    #endif
-    //now start searching for bootkey
-    while (checkforboot)
-    {
-    checkforboot=false; flashloader=false;
-    bootinfo = (uint32_t*)0x3FFF4;
-    if (*bootinfo != 0xB007AB1E) bootinfo = (uint32_t*)0x3FF04; //allow couple of alternative locations
-    if (*bootinfo != 0xB007AB1E) bootinfo = (uint32_t*)0x3FE04; //allow couple of alternative locations
-    if (*bootinfo != 0xB007AB1E) bootinfo = (uint32_t*)0x3F004; //for futureproofing
-    if (*bootinfo != 0xB007AB1E) {
-        // no bootkey found at all
-        display.directcolor=COLOR_YELLOW;
-        display.println("NO LOADER INSTALLED");
-        if (sdversion==0 || sdjump < 0x38000) {
-                //file open of loader failed
-                display.println("NO VALID LOA.DER ON SD");
-                display.println("");
-                display.directcolor=COLOR_GREEN;
-                display.println("PUT LOA.DER ON SD & REBOOT");
-        } else flashloader=true;
-    } else {
-        //loader was found
-        //check if we should update the loader
-        display.directcolor=COLOR_CYAN;
-        display.print("LOADER V.");
-        display.directcolor=COLOR_WHITE;
-        display.println(*(bootinfo+1));
-        #if POK_ENABLE_LOADER_UPDATES
-        if (sdversion>(*(bootinfo+1))) flashloader=true;
-        else start_application(*(bootinfo+2)); //never returns
-        #else
-        start_application(*(bootinfo+2)); //never returns
-        #endif
-    }
-    // update loader if it was requested
-    if(flashloader) {
-            display.directcolor=COLOR_MAGENTA;
-            display.print("NEW LOADER ON SD V.");
-            display.directcolor=COLOR_WHITE;
-            display.println(sdversion);
-            display.directcolor=COLOR_GREEN;
-            display.println("UPDATE LOADER?\n(UP=YES, DOWN=CANCEL)");
-            while(1) {
-                    if (buttons.upBtn()) {
-                        if (updateLoader(sdversion,sdjump)) {
-                            display.println("PUT LOA.DER ON SD AND RETRY");
-                        } else {
-                        display.println("SUCCESS!!");
-                        checkforboot=true; //recheck
-                        }
-                    break;
-                    }
-                    if (buttons.downBtn()) return;
-            }
-    } // if flashloader
-    } // while checkforboot
-    #endif // POK_SIM
-    while (!buttons.aBtn()) {
-        buttons.pollButtons();
-        if (buttons.aBtn()) {
-            while (buttons.aBtn()) {
-                buttons.pollButtons();
-            }
-            return;
-        }
-    }
-}
-
-void Core::askLoader() {
-    display.enableDirectPrinting(true);
-    display.directbgcolor = COLOR_BLACK;
-    display.clearLCD();
-    display.directcolor = COLOR_RED;
-    display.setFont(fntC64UIGfx);
-    display.fontSize=1;
-    display.adjustCharStep = 0;
-    display.adjustLineStep = 0;
-    display.directcolor=COLOR_GREEN;
-    display.set_cursor(12*8,6*8);
-    display.print("ijkl");
-    display.set_cursor(12*8,7*8);
-    display.print("mnop");
-    display.set_cursor(12*8,8*8);
-    display.print("qrst");
-    display.set_cursor(12*8,9*8);
-    display.print("uvwx");
-    display.set_cursor(5*8,12*8);
-    display.print("PRESS");
-    display.directcolor=COLOR_WHITE;
-    display.print(" C ");
-    display.directcolor=COLOR_GREEN;
-    display.print("FOR LOADER");
-    display.directcolor=COLOR_WHITE;
-    display.fontSize=2;
-    int countd=POK_LOADER_COUNTDOWN; uint16_t c2 = getTime();
-    while (countd) {
-        buttons.pollButtons();
-        display.set_cursor(13*8,15*8);
-        display.print(countd);
-        if (getTime()>c2+1000) {
-            c2=getTime();
-            countd--;
-        }
-        if (cBtn()) {while (cBtn()) buttons.pollButtons();jumpToLoader();countd=0;}
-        if (aBtn()) {while (aBtn()) buttons.pollButtons();countd=0;}
-        if (bBtn()) {while (bBtn()) buttons.pollButtons();countd=0;}
-    }
-    display.fontSize=1;
-    display.clearLCD();
-    display.enableDirectPrinting(false);
-}
-
-
-void Core::drawvolbar(int x, int y, int level, bool text) {
-    uint16_t oldcol = display.directcolor;
-    if (text) display.directRectangle(0,0,50,50,COLOR_BLACK);
-    display.directcolor = COLOR_GREEN;
-    if (text) {
-            bool temp = display.isDirectPrintingEnabled();
-            display.enableDirectPrinting(true);
-            display.print(x-1,y-20,(int)sound.getVolume());
-            display.print("  ");
-            display.enableDirectPrinting(temp);
-    }
-    if (level<12) display.directcolor = COLOR_GRAY_80;
-    display.directBitmap(x,y,Pokitto_volumebar,1,1);
-    if (level<24) display.directcolor = COLOR_GRAY_80;
-    display.directBitmap(x+8,y,Pokitto_volumebar,1,1);
-    display.directBitmap(x+8,y-4,Pokitto_volumebar,1,1);
-    display.directcolor = COLOR_RED;
-    if (level<48) display.directcolor = COLOR_GRAY_80;
-    display.directBitmap(x+16,y,Pokitto_volumebar,1,1);
-    display.directBitmap(x+16,y-4,Pokitto_volumebar,1,1);
-    display.directBitmap(x+16,y-8,Pokitto_volumebar,1,1);
-
-    if (level<96) {
-            display.directcolor = COLOR_GRAY_80;
-    }
-    display.directBitmap(x+24,y,Pokitto_volumebar,1,1);
-    display.directBitmap(x+24,y-4,Pokitto_volumebar,1,1);
-    display.directBitmap(x+24,y-8,Pokitto_volumebar,1,1);
-    display.directBitmap(x+24,y-12,Pokitto_volumebar,1,1);
-    if (level<160) {
-            display.directcolor = COLOR_GRAY_80;
-    }
-    display.directBitmap(x+32,y,Pokitto_volumebar,1,1);
-    display.directBitmap(x+32,y-4,Pokitto_volumebar,1,1);
-    display.directBitmap(x+32,y-8,Pokitto_volumebar,1,1);
-    display.directBitmap(x+32,y-12,Pokitto_volumebar,1,1);
-    display.directBitmap(x+32,y-16,Pokitto_volumebar,1,1);
-    display.directcolor = oldcol;
-}
-
-
-#ifdef POK_SIM
-#define VINCMULT 1
-#else
-#define VINCMULT 50
-#endif //POK_SIM
-void Core::setVolLimit() {
-    display.enableDirectPrinting(true);
-    display.adjustCharStep = 0;
-    sound.setMaxVol(VOLUME_HEADPHONE_MAX);
-    int dstate=1;
-    bool wipe = true;
-    float vol = sound.getVolume(); float tvol;
-    volbar_visible=0;
-    while (core.isRunning() && dstate){
-        switch (dstate) {
-        case 1:
-            //redraw
-            if (wipe) {
-            display.clearLCD();
-            display.directcolor = COLOR_WHITE;
-            display.setCursor(4*8,2*8);
-            display.print("SELECT VOLUME LIMIT");
-            display.setCursor(5*8,17*9);
-            display.print("PRESS ");
-            display.directcolor = COLOR_GREEN;
-            display.print("A");
-            display.directcolor = COLOR_WHITE;
-            display.print(" TO ACCEPT");
-            display.directcolor = COLOR_GREEN;
-            // draw frame below first
-            display.setCursor(0,11*8);
-            display.println(" abbbbbbbbbbbbbbbbbbbbbbbc");
-            display.println(" |                       |");
-            display.println(" |                       |");
-            display.println(" |                       |");
-            display.println(" |                       |");
-            display.println(" dbbbbbbbbbbbbbbbbbbbbbbbe");
-            } // wipe = true
-            display.setCursor(6*8,17*9);
-            if (sound.getVolume()-5<=VOLUME_HEADPHONE_MAX) display.directcolor = COLOR_WHITE;
-            else display.directcolor = COLOR_RED;
-            display.directBitmap(21*8-4,6*8,Pokitto_headphones,1,2);
-            display.setCursor(3*8,6*8+6);
-            display.print("HEADPHONES");
-            display.setCursor(3*8,8*8+2);
-            if (sound.getVolume()-8>VOLUME_HEADPHONE_MAX) display.print("TOO LOUD!");
-            else display.print("OK        ");
-            display.directcolor = COLOR_GREEN;
-            display.directBitmap(21*8-4,12*8,Pokitto_speaker,1,2);
-            display.setCursor(3*8,12*8+6);
-            display.print("VOLUME MAX");
-            display.setCursor(3*8,14*8+2);
-            tvol = (vol/float(VOLUME_HEADPHONE_MAX))*100;
-            if (tvol > 100 && tvol < 120) tvol=100;
-            if (sound.getVolume()-5>VOLUME_HEADPHONE_MAX) { display.directcolor=COLOR_RED;}
-            else display.directcolor=COLOR_GREEN;
-            display.print(int(sound.getVolume()));
-            //display.print(int(tvol));
-            display.print("  ");
-            display.directcolor=COLOR_GREEN;
-            drawvolbar(14*8,14*8+4+2,sound.getVolume(),false);
-            //display.setCursor(1,10);
-            //display.print(vol);
-            dstate=2; break;
-        case 2:
-            buttons.pollButtons();
-            if (aBtn()) {dstate=0;while(aBtn()){buttons.pollButtons();};break;}
-            if (rightBtn()) {
-                    if (vol >= VOLUME_HEADPHONE_MAX && vol < VOLUME_HEADPHONE_MAX+1 ) vol += 0.00025f*VINCMULT;
-                    else if (vol >= VOLUME_HEADPHONE_MAX) vol += 0.025f*VINCMULT;
-                    else vol += 0.05f*VINCMULT;
-                    if (vol > VOLUME_HEADPHONE_MAX + 20) {
-                            sound.setMaxVol(VOLUME_SPEAKER_MAX);
-                    }
-                    if (vol > VOLUME_SPEAKER_MAX) vol=VOLUME_SPEAKER_MAX;
-                    sound.setVolume(vol);
-                    dstate=1; wipe=false;
-                    break;
-                    }
-            if (leftBtn()) {
-                    vol -= 0.025f*VINCMULT;
-                    if (vol <= VOLUME_HEADPHONE_MAX) sound.setMaxVol(VOLUME_HEADPHONE_MAX);
-                    if (vol < 0) vol=0;
-                    sound.setVolume(vol);
-                    dstate=1; wipe=false;
-                    break;
-                    }
-            break;
-        }
-    }
-}
-
-void Core::begin() {
-
-    init(); // original functions
-    timePerFrame = POK_FRAMEDURATION;
-	//nextFrameMillis = 0;
-	//frameCount = 0;
-	frameEndMicros = 1;
-	startMenuTimer = 255;
-	//read default settings from flash memory (set using settings.hex)
-	readSettings();
-	//init everything
-	backlight.begin();
-	backlight.set(BACKLIGHT_MAX);
-	buttons.begin();
-	buttons.update();
-	battery.begin();
-	display.begin();
-	#if POK_DISPLAYLOGO
-        showLogo();
-	#endif // POK_DISPLAYLOGO
-
-	display.enableDirectPrinting(true);
-    display.directbgcolor = COLOR_BLACK;
-    display.clearLCD();
-    display.setFont(fntC64UIGfx);
-
-    display.enableDirectPrinting(true);
-    display.directbgcolor = COLOR_BLACK;
-    display.directcolor = COLOR_GREEN;
-    display.clearLCD();
-    display.setFont(fntC64UIGfx);
-    display.adjustCharStep=0;
-    display.adjustLineStep=1;
-    #ifdef JUSTLOAD
-	jumpToLoader();
-	#endif
-
-    #ifndef DISABLE_LOADER
-    askLoader();
-    #endif
-
-	#ifndef DISABLE_SOUND_WARNING
-	//showWarning();
-	setVolLimit();
-	//sound.setVolume(sound.getVolume());//make sure we're at set volume before continue
-	sound.volumeUp();
-	#endif
-	display.enableDirectPrinting(false);
-	display.adjustCharStep=1;
-	display.adjustLineStep=1;
-	display.fontSize=1;
-	display.textWrap=true;
-	#if POK_GAMEBUINO_SUPPORT > 0
-	display.setFont(font5x7);
-	#else
-	display.setFont(fontC64);
-    #endif
-	#if POK_ENABLE_SOUND > 0
-        sound.begin();
-
-	//mute when B is held during start up or if battery is low
-	battery.update();
-	if(buttons.pressed(BTN_B) || (battery.level == 0)){
-		sound.setVolume(0);
-	}
-	else{ //play the startup sound on each channel for it to be louder
-		#if POK_GBSOUND > 0
-		#if(NUM_CHANNELS > 0)
-			sound.playPattern(startupSound, 0);
-		#endif
-		#if(NUM_CHANNELS > 1)
-			sound.playPattern(startupSound, 1);
-		#endif
-		#if(NUM_CHANNELS > 2)
-			sound.playPattern(startupSound, 2);
-		#endif
-		#if(NUM_CHANNELS > 3)
-			sound.playPattern(startupSound, 3);
-		#endif
-		#endif // POK_GBSOUND
-	}
-	#endif // POK ENABLE_SOUND
-}
-
-void Core::init() {
-    run_state = true;
-    display.enableDirectPrinting(false);
-    display.setFont(DEFAULT_FONT);
-    initClock();
-    initGPIO();
-    initButtons();
-    initRandom();
-    //initAudio();
-    //initDisplay();
-}
-
-void Core::init(uint8_t switches) {
-    run_state = true;
-    display.enableDirectPrinting(false);
-    display.setFont(DEFAULT_FONT);
-    initClock();
-    initGPIO();
-    initButtons();
-    initRandom();
-    //initAudio();
-    //initDisplay();
-}
-
-void Core::initButtons() {
-    #ifndef POK_SIM
-    Pokitto::initButtons();
-    #endif
-}
-
-bool Core::isRunning() {
-    #ifdef POK_SIM
-    run_state = simulator.isRunning();
-    #endif // POK_SIM
-    return run_state;
-}
-
-void Core::initDisplay() {
-    #if POK_DISPLAYLOGO > 0
-        showLogo();
-    #endif
-    #if POK_USE_CONSOLE > 0
-        console.AddMessage(MSOURCE_LCD,MSG_INIT_OK);
-    #endif
-}
-
-void Core::showLogo() {
-    uint32_t now;
-    uint8_t state=0; //jump directly to logo, bypass teeth
-    uint16_t counter=0, i=0;
-    uint16_t sc;
-    while (state < 255/6) {
-    now=getTime();
-    if (now>refreshtime) {
-            refreshtime=now+30;
-            switch (state) {
-            case 0:
-                /** POKITTO CLEAN **/
-                display.directbgcolor = COLOR_BLACK;
-                display.fillLCD(display.directbgcolor);
-                sc = COLOR_BLACK;
-                state++;
-                break;
-            case 1:
-                /** POKITTO FADE IN **/
-                display.directcolor = display.interpolateColor(sc, COLOR_GREEN, i);
-                display.directBitmap(POK_LCD_W/2 - (*Pokitto_logo/2),POK_LCD_H/2-(*(Pokitto_logo+1)/2),Pokitto_logo,1,1);
-                i += 28;
-                if (i>=0xFF) { state++; i=0;}
-                break;
-            case 2:
-                /** POKITTO WAIT **/
-                display.directcolor = COLOR_GREEN;
-                display.directBitmap(POK_LCD_W/2 - (*Pokitto_logo/2),POK_LCD_H/2-(*(Pokitto_logo+1)/2),Pokitto_logo,1,1);
-                i+= 0x3F;
-                if (i>0x3FF) state = 255;
-                break;
-            }
-            if(buttons.aBtn()) state=255;
-    }
-    }
-}
-
-void Core::readSettings() {
-    // ToDo
-        /*display.contrast = SCR_CONTRAST;
-		backlight.backlightMin = BACKLIGHT_MIN;
-		backlight.backlightMax = BACKLIGHT_MAX;
-		backlight.ambientLightMin = AMBIENTLIGHT_MIN;
-		backlight.ambientLightMax = AMBIENTLIGHT_MAX;
-*/
-		sound.setMaxVol(VOLUME_HEADPHONE_MAX);
-		sound.globalVolume = VOLUME_STARTUP;
-
-		startMenuTimer = START_MENU_TIMER;
-/*
-		battery.thresolds[0] = BAT_LVL_CRITIC;
-		battery.thresolds[1] = BAT_LVL_LOW;
-		battery.thresolds[2] = BAT_LVL_MED;
-		battery.thresolds[3] = BAT_LVL_FULL;*/
-}
-
-void Core::titleScreen(const char* name){
-	titleScreen(name, 0);
-}
-
-void Core::titleScreen(const uint8_t* logo){
-	titleScreen((""), logo);
-}
-
-void Core::titleScreen(){
-	titleScreen((""));
-}
-
-void Core::titleScreen(const char*  name, const uint8_t *logo){
-	display.setFont(font5x7);
-	if(startMenuTimer){
-		display.fontSize = 1;
-		display.textWrap = false;
-		display.persistence = false;
-		battery.show = false;
-		display.setColor(BLACK);
-		while(isRunning()){
-			if(update()){
-				uint8_t logoOffset = name[0]?display.fontHeight:0; //add an offset the logo when there is a name to display
-				//draw graphics
-				display.setColorDepth(1);
-				display.setColor(3);
-				//display.drawBitmap(0,0, gamebuinoLogo);
-				display.setColor(1);
-				if(logo){
-					display.drawBitmap(0, 12+logoOffset, logo);
-				}
-				display.cursorX = 0;
-				display.cursorY = 12;
-				display.print(name);
-
-				//A button
-				display.cursorX = LCDWIDTH - display.fontWidth*3 -1;
-				display.cursorY = LCDHEIGHT - display.fontHeight*3 - 3;
-				if((frameCount/16)%2)
-				  display.println(("\25 \20"));
-				else
-				  display.println(("\25\20 "));
-				//B button
-				display.cursorX = LCDWIDTH - display.fontWidth*3 - 1;
-				display.cursorY++;
-				if(sound.globalVolume)
-					display.println(("\26\23\24"));
-				else
-					display.println(("\26\23x"));
-				//C button
-				display.cursorX = LCDWIDTH - display.fontWidth*3 - 1;
-				display.cursorY++;
-				//display.println(F("\27SD"));
-
-				//toggle volume when B is pressed
-				if(buttons.pressed(BTN_B)){
-					sound.setVolume(sound.getVolume() + 1);
-					sound.playTick();
-				}
-				//leave the menu
-				if(buttons.pressed(BTN_A) || ((frameCount>=startMenuTimer)&&(startMenuTimer != 255))){
-					startMenuTimer = 255; //don't automatically skip the title screen next time it's displayed
-					sound.stopPattern(0);
-					sound.playOK();
-					break;
-				}
-				//flash the loader
-				//if(buttons.pressed(BTN_C))
-					// ToDo changeGame();
-			}
-		}
-		battery.show = true;
-	}
-}
-
-bool Core::update(bool useDirectMode) {
-#if POK_STREAMING_MUSIC
-        sound.updateStream();
-    #endif
-
-	if ((((nextFrameMillis - getTime())) > timePerFrame) && frameEndMicros) { //if time to render a new frame is reached and the frame end has ran once
-		nextFrameMillis = getTime() + timePerFrame;
-		frameCount++;
-
-		frameEndMicros = 0;
-		backlight.update();
-		buttons.update();
-		battery.update();
-
-		return true;
-
-	} else {
-		if (!frameEndMicros) { //runs once at the end of the frame
-			#if POK_ENABLE_SOUND > 0
-			sound.updateTrack();
-			sound.updatePattern();
-			sound.updateNote();
-			#endif
-			updatePopup();
-			displayBattery();
-
-			if(!useDirectMode)
-				display.update(); //send the buffer to the screen
-
-            frameEndMicros = 1; //jonne
-
-		}
-		return false;
-	}
-}
-
-void Core::displayBattery(){
-#if (ENABLE_BATTERY > 0)
-	//display.setColor(BLACK, WHITE);
-	uint8_t ox,oy;
-	ox=display.cursorX;
-	oy=display.cursorY;
-	display.cursorX = LCDWIDTH-display.fontWidth+1;
-	display.cursorY = 0;
-	switch(battery.level){
-	case 0://battery critic, power down
-		sound.stopPattern();
-		backlight.set(0);
-		display.clear();
-		display.fontSize = 1;
-		display.print(("LOW BATTERY\n"));
-		display.print(battery.voltage);
-		display.print(("mV\n\nPLEASE\nTURN OFF"));
-		display.update();
-		break;
-	case 1: //empty battery
-		if((frameCount % 16) < 8) display.print('\7'); //blinking battery
-		else display.print('x');
-		break;
-	case 2://low battery
-	case 3://full battery
-	case 4://full battery
-		if(battery.show){
-			display.print(char(5+battery.level));
-		}
-		break;
-	default:
-		if(battery.show){
-			display.print('/');
-		}
-		break;
-	}
-display.cursorX = ox;
-display.cursorY = oy;
-#endif
-}
-
-char* Core::filemenu(char *ext) {
-    display.persistence = false;
-    uint16_t oldpal0=display.palette[0];
-    uint16_t oldpal1=display.palette[1];
-    uint16_t oldpal2=display.palette[2];
-    display.palette[2]=COLOR_GREEN;
-    display.palette[1]=COLOR_WHITE;
-    display.palette[0]=COLOR_BLACK;
-    uint8_t oldbg=display.bgcolor;
-    uint8_t oldfg=display.color;
-    display.color=1;
-    display.bgcolor=0;
-
-    int8_t activeItem = 0;
-	int16_t currentY = 100;
-	int16_t targetY = 0, rowh = display.fontHeight + 2;
-	boolean exit = false;
-
-	char* txt;
-
-
-	while (isRunning()) {
-		if (update()) {
-            getFirstFile(ext);
-			if (buttons.pressed(BTN_A) || buttons.pressed(BTN_B) || buttons.pressed(BTN_C)) {
-				exit = true; //time to exit menu !
-				targetY = - display.fontHeight * 10 - 2; //send the menu out of the screen
-				if (buttons.pressed(BTN_A)) {
-					//answer = activeItem;
-					sound.playOK();
-				} else {
-					sound.playCancel();
-				}
-			}
-			if (exit == false) {
-				if (buttons.repeat(BTN_DOWN,4)) {
-					activeItem++;
-					sound.playTick();
-				}
-				if (buttons.repeat(BTN_UP,4)) {
-					activeItem--;
-					sound.playTick();
-				}
-				//don't go out of the menu
-				//if (activeItem == length) activeItem = 0;
-				//if (activeItem < 0) activeItem = length - 1;
-                if (currentY>targetY) currentY-=16;
-                if (currentY<targetY) currentY=targetY;
-				//targetY = -rowh * activeItem + (rowh+4); //center the menu on the active item
-			} else { //exit :
-			    if (currentY>targetY) currentY-=16;
-                if (currentY<targetY) currentY=targetY;
-				if ((currentY - targetY) <= 1)
-				{
-				    display.bgcolor=oldbg;
-				    display.color=oldfg;
-				    display.palette[0] = oldpal0;
-				    display.palette[1] = oldpal1;
-				    display.palette[2] = oldpal2;
-				    return selectedfile;
-				}
-
-			}
-			//draw a fancy menu
-			//currentY = 0;//(currentY + targetY) / 2 + 5;
-			display.cursorX = 0;
-			display.cursorY = currentY;
-			display.textWrap = false;
-			uint16_t fc,bc;
-			fc = display.color;
-            bc = display.bgcolor;
-            //getFirstFile(ext);
-			for (int i = 0; i<20; i++) {
-				display.invisiblecolor=255;
-				display.cursorY = currentY + rowh * i;
-				if (i==3) display.color=1;
-				if (i == activeItem){
-					display.cursorX = 3;
-
-                    //display.fillRoundRect(0, currentY + display.fontHeight * activeItem - 2, LCDWIDTH, (display.fontHeight+3), 3);
-                    display.color=2;
-                    display.fillRect(0, currentY + rowh * activeItem - 2, LCDWIDTH, (rowh));
-                    display.setColor(0,2);
-				} else display.setColor(1,0);
-				//display.println((char*)*(const unsigned int*)(items+i));
-				//display.println((int)i);
-                txt = getNextFile(ext);
-                if (txt) {
-                        display.println(txt);
-                        if (i == activeItem) {
-                            strcpy(selectedfile,txt);
-                        }
-                } else i--;
-                display.setColor(1,0);
-			} // draw menu loop
-		} // update
-	}
-	return 0;
-}
-
-char* Core::filemenu() {
-    return filemenu("");
-}
-
-int8_t Core::menu(const char* const* items, uint8_t length) {
-#if (ENABLE_GUI > 0)
-	display.persistence = false;
-	int8_t activeItem = 0;
-	int16_t currentY = display.height;
-	int16_t targetY = 0, rowh = display.fontHeight + 2;
-	boolean exit = false;
-	int8_t answer = -1;
-	while (isRunning()) {
-		if (update()) {
-			if (buttons.pressed(BTN_A) || buttons.pressed(BTN_B) || buttons.pressed(BTN_C)) {
-				exit = true; //time to exit menu !
-				targetY = - display.fontHeight * length - 2; //send the menu out of the screen
-				if (buttons.pressed(BTN_A)) {
-					answer = activeItem;
-					sound.playOK();
-				} else {
-					sound.playCancel();
-				}
-			}
-			if (exit == false) {
-				if (buttons.repeat(BTN_DOWN,4)) {
-					activeItem++;
-					sound.playTick();
-				}
-				if (buttons.repeat(BTN_UP,4)) {
-					activeItem--;
-					sound.playTick();
-				}
-				//don't go out of the menu
-				if (activeItem == length) activeItem = 0;
-				if (activeItem < 0) activeItem = length - 1;
-
-				targetY = -rowh * activeItem + (rowh+4); //center the menu on the active item
-			} else { //exit :
-				if ((currentY - targetY) <= 1)
-				return (answer);
-			}
-			//draw a fancy menu
-			currentY = (currentY + targetY) / 2;
-			display.cursorX = 0;
-			display.cursorY = currentY;
-			display.textWrap = false;
-			uint16_t fc,bc;
-			fc = display.color;
-            bc = display.bgcolor;
-			for (byte i = 0; i < length; i++) {
-				display.cursorY = currentY + rowh * i;
-				if (i == activeItem){
-					display.cursorX = 3;
-
-                    //display.fillRoundRect(0, currentY + display.fontHeight * activeItem - 2, LCDWIDTH, (display.fontHeight+3), 3);
-                    display.fillRect(0, currentY + rowh * activeItem - 2, LCDWIDTH, (rowh));
-                    display.setColor(bc,fc);
-				} else display.setColor(fc,bc);
-
-				display.println((char*)*(const unsigned int*)(items+i));
-				display.setColor(fc,bc);
-			}
-
-		}
-	}
-#else
-	return 0;
-#endif
-	return 0;
-}
-
-void Core::keyboard(char* text, uint8_t length) {
-#if (ENABLE_GUI > 0)
-	display.persistence = false;
-	//memset(text, 0, length); //clear the text
-	text[length-1] = '\0';
-	//active character in the typing area
-	int8_t activeChar = 0;
-	//selected char on the keyboard
-	int8_t activeX = 0;
-	int8_t activeY = 2;
-	//position of the keyboard on the screen
-	int8_t currentX = LCDWIDTH;
-	int8_t currentY = LCDHEIGHT;
-	int8_t targetX = 0;
-	int8_t targetY = 0;
-
-	while (1) {
-		if (update()) {
-			//move the character selector
-			if (buttons.repeat(BTN_DOWN, 4)) {
-				activeY++;
-				sound.playTick();
-			}
-			if (buttons.repeat(BTN_UP, 4)) {
-				activeY--;
-				sound.playTick();
-			}
-			if (buttons.repeat(BTN_RIGHT, 4)) {
-				activeX++;
-				sound.playTick();
-			}
-			if (buttons.repeat(BTN_LEFT, 4)) {
-				activeX--;
-				sound.playTick();
-			}
-			//don't go out of the keyboard
-			if (activeX == KEYBOARD_W) activeX = 0;
-			if (activeX < 0) activeX = KEYBOARD_W - 1;
-			if (activeY == KEYBOARD_H) activeY = 0;
-			if (activeY < 0) activeY = KEYBOARD_H - 1;
-			//set the keyboard position on screen
-			targetX = -(display.fontWidth+1) * activeX + LCDWIDTH / 2 - 3;
-			targetY = -(display.fontHeight+1) * activeY + LCDHEIGHT / 2 - 4 - display.fontHeight;
-			//smooth the keyboard displacement
-			currentX = (targetX + currentX) / 2;
-			currentY = (targetY + currentY) / 2;
-			//type character
-			if (buttons.pressed(BTN_A)) {
-				if (activeChar < (length-1)) {
-					byte thisChar = activeX + KEYBOARD_W * activeY;
-					if((thisChar == 0)||(thisChar == 10)||(thisChar == 13)) //avoid line feed and carriage return
-					continue;
-					text[activeChar] = thisChar;
-					text[activeChar+1] = '\0';
-				}
-				activeChar++;
-				sound.playOK();
-				if (activeChar > length)
-				activeChar = length;
-			}
-			//erase character
-			if (buttons.pressed(BTN_B)) {
-				activeChar--;
-				sound.playCancel();
-				if (activeChar >= 0)
-				text[activeChar] = 0;
-				else
-				activeChar = 0;
-			}
-			//leave menu
-			if (buttons.pressed(BTN_C)) {
-				sound.playOK();
-				while (1) {
-					if (update()) {
-						//display.setCursor(0,0);
-						display.println(("You entered\n"));
-						display.print(text);
-						display.println(("\n\n\n\x15:okay \x16:edit"));
-						if(buttons.pressed(BTN_A)){
-							sound.playOK();
-							return;
-						}
-						if(buttons.pressed(BTN_B)){
-							sound.playCancel();
-							break;
-						}
-					}
-				}
-			}
-			//draw the keyboard
-			for (int8_t y = 0; y < KEYBOARD_H; y++) {
-				for (int8_t x = 0; x < KEYBOARD_W; x++) {
-					display.drawChar(currentX + x * (display.fontWidth+1), currentY + y * (display.fontHeight+1), x + y * KEYBOARD_W, 1);
-				}
-			}
-			//draw instruction
-			display.cursorX = currentX-display.fontWidth*6-2;
-			display.cursorY = currentY+1*(display.fontHeight+1);
-			display.print(("\25type"));
-
-			display.cursorX = currentX-display.fontWidth*6-2;
-			display.cursorY = currentY+2*(display.fontHeight+1);
-			display.print(("\26back"));
-
-			display.cursorX = currentX-display.fontWidth*6-2;
-			display.cursorY = currentY+3*(display.fontHeight+1);
-			display.print(("\27save"));
-
-			//erase some pixels around the selected character
-			display.setColor(WHITE);
-			display.drawFastHLine(currentX + activeX * (display.fontWidth+1) - 1, currentY + activeY * (display.fontHeight+1) - 2, 7);
-			//draw the selection rectangle
-			display.setColor(BLACK);
-			display.drawRoundRect(currentX + activeX * (display.fontWidth+1) - 2, currentY + activeY * (display.fontHeight+1) - 3, (display.fontWidth+2)+(display.fontWidth-1)%2, (display.fontHeight+5), 3);
-			//draw keyboard outline
-			//display.drawRoundRect(currentX - 6, currentY - 6, KEYBOARD_W * (display.fontWidth+1) + 12, KEYBOARD_H * (display.fontHeight+1) + 12, 8, BLACK);
-			//text field
-			display.drawFastHLine(0, LCDHEIGHT-display.fontHeight-2, LCDWIDTH);
-			display.setColor(WHITE);
-			display.fillRect(0, LCDHEIGHT-display.fontHeight-1, LCDWIDTH, display.fontHeight+1);
-			//typed text
-			display.cursorX = 0;
-			display.cursorY = LCDHEIGHT-display.fontHeight;
-			display.setColor(BLACK);
-			display.print(text);
-			//blinking cursor
-			if (((frameCount % 8) < 4) && (activeChar < (length-1)))
-			display.drawChar(display.fontWidth * activeChar, LCDHEIGHT-display.fontHeight, '_',1);
-		}
-	}
-#endif
-}
-
-void Core::popup(const char* text, uint8_t duration){
-#if (ENABLE_GUI > 0)
-	popupText = text;
-	popupTimeLeft = duration+12;
-#endif
-}
-
-void Core::updatePopup(){
-#if (ENABLE_GUI > 0)
-	if (popupTimeLeft){
-		uint8_t yOffset = 0;
-		if(popupTimeLeft<12){
-			yOffset = 12-popupTimeLeft;
-		}
-		display.fontSize = 1;
-		display.setColor(WHITE);
-		display.fillRoundRect(0,LCDHEIGHT-display.fontHeight+yOffset-3,84,display.fontHeight+3,3);
-		display.setColor(BLACK);
-		display.drawRoundRect(0,LCDHEIGHT-display.fontHeight+yOffset-3,84,display.fontHeight+3,3);
-		display.cursorX = 4;
-		display.cursorY = LCDHEIGHT-display.fontHeight+yOffset-1;
-		display.print(popupText);
-		popupTimeLeft--;
-	}
-#endif
-}
-
-void Core::setFrameRate(uint8_t fps) {
-	timePerFrame = 1000 / fps;
-	sound.prescaler = fps / 20;
-	sound.prescaler = __avrmax(1, sound.prescaler);
-}
-
-void Core::pickRandomSeed(){
-        initRandom();
-}
-
-bool Core::collidePointRect(int16_t x1, int16_t y1 ,int16_t x2 ,int16_t y2, int16_t w, int16_t h){
-	if((x1>=x2)&&(x1<x2+w))
-	if((y1>=y2)&&(y1<y2+h))
-	return true;
-	return false;
-}
-
-bool Core::collideRectRect(int16_t x1, int16_t y1, int16_t w1, int16_t h1 ,int16_t x2 ,int16_t y2, int16_t w2, int16_t h2){
-  return !( x2     >=  x1+w1  ||
-            x2+w2  <=  x1     ||
-            y2     >=  y1+h1  ||
-            y2+h2  <=  y1     );
-}
-
-bool Core::collideBitmapBitmap(int16_t x1, int16_t y1, const uint8_t* b1, int16_t x2, int16_t y2, const uint8_t* b2){
-  int16_t w1 = pgm_read_byte(b1);
-  int16_t h1 = pgm_read_byte(b1 + 1);
-  int16_t w2 = pgm_read_byte(b2);
-  int16_t h2 = pgm_read_byte(b2 + 1);
-
-  if(collideRectRect(x1, y1, w1, h1, x2, y2, w2, h2) == false){
-    return false;
-  }
-
-  int16_t xmin = (x1>=x2)? 0 : x2-x1;
-  int16_t ymin = (y1>=y2)? 0 : y2-y1;
-  int16_t xmax = (x1+w1>=x2+w2)? x2+w2-x1 : w1;
-  int16_t ymax = (y1+h1>=y2+h2)? y2+h2-y1 : h1;
-  for(uint8_t y = ymin; y < ymax; y++){
-    for(uint8_t x = xmin; x < xmax; x++){
-      if(display.getBitmapPixel(b1, x, y) && display.getBitmapPixel(b2, x1+x-x2, y1+y-y2)){
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-
-//** EOF **//
-
-
-
-
-
-
-
-
-
--- a/POKITTO_CORE/PokittoCore.h	Fri Dec 29 02:55:34 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,263 +0,0 @@
-/**************************************************************************/
-/*!
-    @file     PokittoCore.h
-    @author   Jonne Valola
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2016, Jonne Valola
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-#ifndef POKITTOCORE_H
-#define POKITTOCORE_H
-
-#include <stdint.h>
-#include <math.h>
-#ifndef POK_SIM
-    #include "pwmout_api.h"
-    #include "HWButtons.h"
-#else
-    #include "PokittoSimulator.h"
-#endif
-#if POK_USE_CONSOLE > 0
-    #include "PokittoConsole.h"
-#endif // POK_USE_CONSOLE
-#if POK_ENABLE_SD > 0
-    #include "PokittoDisk.h"
-#endif
-
-#include "PokittoFonts.h"
-#include "PokittoPalettes.h"
-#include "PokittoDisplay.h"
-#include "PokittoButtons.h"
-#include "PokittoBattery.h"
-#include "PokittoBacklight.h"
-#include "PokittoSound.h"
-#include "PokittoFakeavr.h"
-
-#define PALETTE_SIZE 16
-#define PI 3.141592741f
-
-// For GB compatibility
-#if PROJ_GAMEBUINO > 0
-extern void setup();
-extern void loop();
-#endif // PROJ_GAMEBUINO
-
-extern uint32_t* ptimer; // re-directed tick counter
-
-namespace Pokitto {
-
-/** Core class.
- *  The Core class is a class consisting of static data and methods.
- *  It handles the lowlevel hardware functions of the Pokitto.
- *  It is declared as static to prevent several instances running at same time.
- * Example:
- * @code
- * // A simple "Hello World!" program with Pokitto
- *
- * #include "Pokitto.h"
- *
- * Pokitto::Core myApp;
- *
- * int main() {
- *     myApp.begin(); // This starts up the console (the display, buttons etc.)
- *     while(myApp.isRunning()) {
- *         if(myApp.Update()) {
- *             myApp.display.print("Hello World!");
- *         }
- *     }
- * }
- * @endcode
- */
-
-class Core
-{
-public:
-  /** Create a Core runtime instance
-  */
-  Core();
-
-  /** Backlight component of the Core runtime */
-  static Backlight backlight;
-  /** Buttons component of the Core runtime */
-  static Buttons buttons;
-  /** Battery component of the Core runtime */
-  static Battery battery;
-  /** Sound component of the Core runtime */
-  static Sound sound;
-  /** Display component of the Core runtime */
-  static Display display;
-
-  // EXCECUTION CONTROL
-public:
-  /** Initialize runtime (use this one) */
-  static void begin();
-  /** Initialize runtime (deprecated, avoid) */
-  static void init();
-  /** Initialize runtime with options (deprecated, avoid) */
-  static void init(uint8_t);
-  /** Return run state (1 = running, 0 = shutting down) */
-  static bool isRunning();
-  /** Stop running */
-  static void quit();
-private:
-  /** run_state is true as long as program is running */
-  static bool run_state;
-
-public:
-  // INITIALIZATION
-  /** Initialize display */
-  static void initDisplay();
-  /** Initialize random generator */
-  static void initRandom();
-  /** Initialize GPIO */
-  static void initGPIO();
-  /** Initialize LCD */
-  static void initLCD();
-  /** Initialize Audio */
-  static void initAudio();
-
-
-  // DISPLAY
-public:
-  /** Initialize backlight */
-  static void initBacklight();
-
-private:
-  /** Backlight PWM pointer */
-  #ifndef POK_SIM
-  static pwmout_t backlightpwm;
-  #endif
-
-  // TIMEKEEPING
-public:
-  /** Initialize runtime clock */
-  static void initClock();
-  /** Get value of time elapsed during program in milliseconds */
-  static uint32_t getTime();
-  /** Wait for n milliseconds */
-  static void wait(uint16_t);
-private:
-  /** Time of next refresh */
-  static uint32_t refreshtime;
-
-  // DIRECT TO SCREEN
-public:
-  /** Display Pokitto logo */
-  static void showLogo();
-  static void showWarning();
-  static void setVolLimit();
-
-// BUTTON INPUT HANDLING
-private:
-  static uint8_t heldStates[];
-public:
-  static void initButtons();
-  static void pollButtons();
-  static uint8_t leftBtn();
-  static uint8_t rightBtn();
-  static uint8_t upBtn();
-  static uint8_t downBtn();
-  static uint8_t aBtn();
-  static uint8_t bBtn();
-  static uint8_t cBtn();
-  static uint8_t leftHeld();
-  static uint8_t rightHeld();
-  static uint8_t upHeld();
-  static uint8_t downHeld();
-  static uint8_t aHeld();
-  static uint8_t bHeld();
-  static uint8_t cHeld();
-
-  static uint8_t leftReleased();
-  static uint8_t rightReleased();
-  static uint8_t upReleased();
-  static uint8_t downReleased();
-  static uint8_t aReleased();
-  static uint8_t bReleased();
-  static uint8_t cReleased();
-
-  // AUDIO RELATED
-  static uint8_t ampIsOn();
-  static void ampEnable(uint8_t);
-  static uint8_t soundbyte;
-
-  // GB RELATED
-public:
-    static void readSettings();
-    static void titleScreen(const char* name, const uint8_t *logo);
-	static void titleScreen(const char* name);
-	static void titleScreen(const uint8_t* logo);
-    static void titleScreen();
-    static bool update(bool useDirectMode=false);
-    static uint32_t frameCount;
-    static int8_t menu(const char* const* items, uint8_t length);
-    static char* filemenu(char*);
-    static char* filemenu();
-    static void keyboard(char* text, uint8_t length);
-    static void popup(const char* text, uint8_t duration);
-    static void setFrameRate(uint8_t fps);
-	static void pickRandomSeed();
-
-	static uint8_t getCpuLoad();
-    static uint16_t getFreeRam();
-
-    static bool collidePointRect(int16_t x1, int16_t y1 ,int16_t x2 ,int16_t y2, int16_t w, int16_t h);
-	static bool collideRectRect(int16_t x1, int16_t y1, int16_t w1, int16_t h1 ,int16_t x2 ,int16_t y2, int16_t w2, int16_t h2);
-    static bool collideBitmapBitmap(int16_t x1, int16_t y1, const uint8_t* b1, int16_t x2, int16_t y2, const uint8_t* b2);
-
-private:
-    static uint8_t timePerFrame;
-    static uint32_t nextFrameMillis;
-    static void updatePopup();
-    static const char* popupText;
-    static uint8_t popupTimeLeft;
-    static void displayBattery();
-    static uint16_t frameDurationMicros;
-    static uint32_t frameStartMicros, frameEndMicros;
-    static uint8_t startMenuTimer;
-    static int updateLoader(uint32_t,uint32_t);
-public:
-    static uint8_t volbar_visible;
-    static void drawvolbar(int,int,int, bool);
-    static void askLoader();
-    static void jumpToLoader();
-};
-
-// this is the instance used by the system
-extern Core core;
-
-
-}
-
-#endif // POKITTOCORE_H
-
-
-
--- a/POKITTO_CORE/PokittoDisplay.cpp	Fri Dec 29 02:55:34 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2152 +0,0 @@
-/**************************************************************************/
-/*!
-    @file     PokittoDisplay.cpp
-    @author   Jonne Valola
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2016, Jonne Valola
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-
-/* THE SEGMENT BELOW PERTAINS TO CIRCLE DRAWING FUNCTIONS ONLY
-*
-This is the core graphics library for all our displays, providing a common
-set of graphics primitives (points, lines, circles, etc.).  It needs to be
-paired with a hardware-specific library for each display device we carry
-(to handle the lower-level functions).
-Adafruit invests time and resources providing this open source code, please
-support Adafruit & open-source hardware by purchasing products from Adafruit!
-Copyright (c) 2013 Adafruit Industries.  All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-- Redistributions of source code must retain the above copyright notice,
-  this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "PokittoDisplay.h"
-#include "Pokitto_settings.h"
-#include "GBcompatibility.h"
-#include "PokittoCore.h"
-#include "PokittoSound.h"
-#include <stdio.h>
-#include <string.h>
-
-#ifndef POK_SIM
-#include "HWLCD.h"
-#else
-#include "SimLCD.h"
-#endif
-
-Pokitto::Core core;
-Pokitto::Sound sound;
-
-using namespace Pokitto;
-
-
-
-uint8_t* Display::m_scrbuf;
-uint8_t* Display::m_tileset;
-uint8_t* Display::m_tilebuf;
-uint8_t* Display::m_tilecolorbuf;
-uint8_t Display::m_mode, Display::m_colordepth;
-uint8_t Display::fontSize=1;
-int16_t Display::cursorX,Display::cursorY;
-uint16_t Display::m_w,Display::m_h;
-uint8_t Display::fontWidth, Display::fontHeight;
-bool Display::textWrap=true;
-
-uint8_t Display::persistence = 0;
-uint16_t Display::color = 1;
-uint16_t Display::bgcolor = 0;
-uint16_t Display::invisiblecolor = 17;
-uint16_t Display::directcolor=0xFFFF;
-uint16_t Display::directbgcolor=0x0;
-
-uint16_t* Display::paletteptr;
-uint16_t Display::palette[PALETTE_SIZE];
-const unsigned char* Display::font;
-int8_t Display::adjustCharStep = 1;
-int8_t Display::adjustLineStep = 1;
-bool Display::fixedWidthFont = false;
-
-/** drawing canvas **/
-//uint8_t* Display::canvas; // points to the active buffer. if null, draw direct to screen
-
-/** screenbuffer **/
-uint8_t Display::bpp = POK_COLORDEPTH;
-#ifndef POK_TILEDMODE
-#if (POK_SCREENMODE == MODE_HI_MONOCHROME)
-    uint8_t Display::width = POK_LCD_W;
-    uint8_t Display::height = POK_LCD_H;
-    uint8_t Display::screenbuffer[((POK_LCD_H+1)*POK_LCD_W)*POK_COLORDEPTH/8]; // maximum resolution
-#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
-#elif (POK_SCREENMODE == MODE_FAST_16COLOR)
-    uint8_t Display::width = POK_LCD_W/2;
-    uint8_t Display::height = POK_LCD_H/2;
-    uint8_t Display::screenbuffer[(((POK_LCD_H/2)+1)*POK_LCD_W/2)*POK_COLORDEPTH/8]; // half resolution
-#elif (POK_SCREENMODE == MODE_HI_16COLOR)
-    uint8_t Display::width = POK_LCD_W;
-    uint8_t Display::height = POK_LCD_H;
-    uint8_t Display::screenbuffer[POK_LCD_H*POK_LCD_W/2]; // 4 bits per pixel
-#elif (POK_SCREENMODE == MODE_LAMENES)
-    uint8_t Display::width = 128;
-    uint8_t Display::height = 120;
-    uint8_t Display::screenbuffer[((121)*128)*POK_COLORDEPTH/8]; // half resolution
-#elif (POK_SCREENMODE == MODE_GAMEBOY)
-    uint8_t Display::width = 160;
-    uint8_t Display::height = 144;
-    uint8_t Display::screenbuffer[160*144/4];
-#else
-    uint8_t Display::width = 84;
-    uint8_t Display::height = 48;
-    uint8_t Display::screenbuffer[128*64]; // not needed because Gamebuino and Arduboy have their own buffer
-#endif
-#else //Tiledmode
-#if (POK_SCREENMODE == MODE_TILED_1BIT)
-    uint8_t Display::width = POK_LCD_W;
-    uint8_t Display::height = POK_LCD_H;
-    uint8_t Display::screenbuffer[0];
-#else
-    uint8_t Display::width = POK_LCD_W;
-    uint8_t Display::height = POK_LCD_H;
-    uint8_t Display::screenbuffer[0];
-#endif
-#endif //tiledmode
-
-// RLE decoding
-#define RLE_ESC_EOL 0
-#define RLE_ESC_EOB 1
-#define RLE_ESC_OFFSET 2
-
-Display::Display() {
-    m_scrbuf = screenbuffer;
-    setDefaultPalette();
-    m_mode = 1; // direct printing on by default
-    m_w = POK_LCD_W;
-    m_h = POK_LCD_H;
-    setFont(DEFAULT_FONT);
-    invisiblecolor=17;
-    bgcolor=0;
-    if (POK_COLORDEPTH) m_colordepth = POK_COLORDEPTH;
-    else m_colordepth = 4;
-    #if POK_GAMEBUINO_SUPPORT
-    setColorDepth(1);
-    #endif // POK_GAMEBUINO_SUPPORT
-}
-
-uint16_t Display::getWidth() {
-    return width;
-}
-
-uint8_t Display::getNumberOfColors() {
-    return 1<<POK_COLORDEPTH;
-}
-
-uint16_t Display::getHeight() {
-    return height;
-}
-
-uint8_t Display::getColorDepth() {
-    return m_colordepth;
-}
-
-void Display::setColorDepth(uint8_t v) {
-    if (v > POK_COLORDEPTH) v=POK_COLORDEPTH;
-    m_colordepth = v;
-}
-
-void Display::clearLCD() {
-    lcdFillSurface(0);
-    setCursor(0,0); // old basic computer style
-}
-
-void Display::fillLCD(uint16_t c) {
-    lcdFillSurface(c);
-}
-
-void Display::directPixel(int16_t x, int16_t y, uint16_t color) {
-    lcdPixel(x,y,color);
-}
-
-void Display::directTile(int16_t x, int16_t y, int16_t x2, int16_t y2, uint16_t* gfx) {
-    lcdTile(x,y,x2,y2,gfx);
-}
-
-void Display::directRectangle(int16_t x, int16_t y,int16_t x2, int16_t y2, uint16_t color) {
-    lcdRectangle(x,y,x2,y2,color);
-}
-
-void Display::begin() {
-    lcdInit();
-}
-
-void Display::setCursor(int16_t x,int16_t y) {
-    cursorX = x;
-    cursorY = y;
-}
-
-void Display::update() {
-
-#if POK_SCREENMODE == MODE_GAMEBOY
-    lcdRefreshModeGBC(m_scrbuf, paletteptr);
-#endif
-
-#if POK_SCREENMODE == MODE_HI_4COLOR
-    lcdRefreshMode1(m_scrbuf, paletteptr);
-#endif
-
-#if POK_SCREENMODE == MODE_HI_16COLOR
-    lcdRefreshMode3(m_scrbuf, paletteptr);
-#endif
-
-#if POK_SCREENMODE == MODE_FAST_16COLOR
-    lcdRefreshMode2(m_scrbuf, paletteptr);
-#endif
-
-#if POK_SCREENMODE == MODE_GAMEBUINO_16COLOR
-    lcdRefreshGB(m_scrbuf, paletteptr);
-#endif
-
-#if POK_SCREENMODE == MODE_ARDUBOY_16COLOR
-    lcdRefreshAB(m_scrbuf, paletteptr);
-#endif
-
-#if POK_SCREENMODE == MODE_TILED_1BIT
-    lcdRefreshT1(m_tilebuf, m_tilecolorbuf, m_tileset, paletteptr);
-#endif
-
-if (!persistence) clear();
-
-/** draw volume bar if visible **/
-#if POK_SHOW_VOLUME > 0
-if (core.volbar_visible) {
-        core.drawvolbar(4,20,sound.getVolume(),true);
-        core.volbar_visible--;
-}
-#endif // POK_SHOW_VOLUME
-
-}
-
-void Display::directBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t depth, uint8_t scale) {
-    uint8_t w = *bitmap;
-	uint8_t h = *(bitmap + 1);
-	bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
-    int16_t i, j;
-    int8_t byteNum, bitNum, byteWidth = (w + 7) >> 3;
-
-    if (depth == 1) {
-        for (i = 0; i < w; i++) {
-            byteNum = i / 8;
-            bitNum = i % 8;
-            for (j = 0; j < h; j++) {
-                if (*(bitmap + j * byteWidth + byteNum) & (0x80 >> bitNum)) { //0x80 = B10000000
-                    if (scale==1) directPixel(x + i, y + j,directcolor);
-                    else {
-                        directPixel(x + i + i, y + j + j,directcolor);
-                        directPixel(x + 1 + i + i, y + j + j,directcolor);
-                        directPixel(x + i + i, y + j + j + 1,directcolor);
-                        directPixel(x + i + i + 1 , y + j + j + 1,directcolor);
-                    }
-                }
-            }
-        }
-    } else if (depth == 4) {
-        for (j = 0; j < h; j+=1) {
-            for (i = 0; i < w; i+=2) {
-                uint16_t col = paletteptr[*bitmap>>4]; //higher nibble
-                if (scale==2) {
-                        directPixel(x + (i<<1), y + (j<<1),col);
-                        directPixel(x + (i<<1) + 1, y + (j<<1),col);
-                        directPixel(x + (i<<1) + 1, y + (j<<1) + 1,col);
-                        directPixel(x + (i<<1), y + (j<<1) + 1,col);
-                } else directPixel(x + i, y + j,col);
-                col = paletteptr[*bitmap&0xF]; // lower nibble
-                if (scale==2) {
-                        directPixel(x + (i<<1) + 2, y + (j<<1),col);
-                        directPixel(x + (i<<1) + 1 + 2, y + (j<<1),col);
-                        directPixel(x + (i<<1) + 1 + 2, y + (j<<1) + 1,col);
-                        directPixel(x + (i<<1) + 2 , y + (j<<1) + 1,col);
-                } else directPixel(x + i + 1, y + j,col);
-                bitmap++;
-            }
-        }
-    }
-
-}
-
-int Display::directChar(int16_t x, int16_t y, uint16_t index){
-    const uint8_t* bitmap = font;
-    uint8_t w = *bitmap;
-	uint8_t h = *(bitmap + 1);
-	uint8_t hbytes=0, xtra=1;
-	if (h==8 || h==16) xtra=0; //don't add if exactly on byte limit
-	hbytes=(h>>3)+xtra; //GLCD fonts are arranged w+1 times h/8 bytes
-	//bitmap = bitmap + 3 + index * h * ((w>>3)+xtra); //add an offset to the pointer (fonts !)
-	bitmap = bitmap + 4 + index * (w * hbytes + 1); //add an offset to the pointer (fonts !)
-	//int8_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
-    int8_t i, j, numBytes;
-    numBytes = *bitmap++; //first byte of char is the width in bytes
-    // 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
-
-	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++) {
-                if (bitcolumn&0x1) {
-                    if (fontSize==2) {
-                        directPixel(x + (i<<1)  , y + (j<<1),directcolor);
-                        directPixel(x + (i<<1)+1, y + (j<<1),directcolor);
-                        directPixel(x + (i<<1)  , y + (j<<1)+1,directcolor);
-                        directPixel(x + (i<<1)+1, y + (j<<1)+1,directcolor);
-                    } else directPixel(x + i, y + j,directcolor);
-                } else if (directbgcolor != invisiblecolor) {
-                    if (fontSize==2) {
-                        directPixel(x + (i<<1)  , y + (j<<1),directbgcolor);
-                        directPixel(x + (i<<1)+1, y + (j<<1),directbgcolor);
-                        directPixel(x + (i<<1)  , y + (j<<1)+1,directbgcolor);
-                        directPixel(x + (i<<1)+1, y + (j<<1)+1,directbgcolor);
-                    } else directPixel(x + i, y + j,directbgcolor);
-                }
-                bitcolumn>>=1;
-            }
-    }
-    return (numBytes+adjustCharStep)*fontSize; // for character stepping
-}
-
-int Display::bufferChar(int16_t x, int16_t y, uint16_t index){
-    const uint8_t* bitmap = font;
-    uint8_t w = *bitmap;
-	uint8_t h = *(bitmap + 1);
-	uint8_t hbytes=0, xtra=1;
-	if (h==8 || h==16) xtra=0; //don't add if exactly on byte limit
-	hbytes=(h>>3)+xtra; //GLCD fonts are arranged w+1 times h/8 bytes
-	//bitmap = bitmap + 3 + index * h * ((w>>3)+xtra); //add an offset to the pointer (fonts !)
-	bitmap = bitmap + 4 + index * (w * hbytes + 1); //add an offset to the pointer (fonts !)
-	//int8_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
-    int8_t i, j, numBytes;
-    numBytes = *bitmap++; //first byte of char is the width in bytes
-    // 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
-
-	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 (bitcolumn&0x1) {
-                    drawPixel(x + i, y + j,color);
-                } else drawPixel(x + i, y + j,bgcolor);
-                bitcolumn>>=1;
-                #endif // PROJ_ARDUBOY
-
-            }
-    }
-
-    return numBytes+adjustCharStep; // for character stepping
-}
-
-void Display::clear() {
-
-    uint8_t c=0;
-    c = bgcolor & (PALETTE_SIZE-1) ; //don't let palette go out of bounds
-    if (bpp==1 && bgcolor) c=0xFF; // bgcolor !=0, set all pixels
-    else if (bpp==2) {
-        c = bgcolor & 0x3;
-        c = c | (c << 2);
-        c = c | (c << 4);
-    } else {
-        c = (c & 0x0F) | (c << 4);
-    }
-    uint16_t j = sizeof(screenbuffer);
-    memset((void*)m_scrbuf,c,j);
-
-    setCursor(0,0);
-
-}
-
-void Display::scroll(int16_t pixelrows) {
-    uint16_t index = 0, index2,oc;
-    if (pixelrows==0) return;
-    if (pixelrows >= height) pixelrows=height-1;
-    if (bpp == 4) index2 = pixelrows*width/2;
-    else if (bpp == 2) index2 = pixelrows*width/4;
-    else return;
-    oc = color;
-    color = bgcolor;
-    if (pixelrows>0) {
-    for (uint16_t y=0;y<height-pixelrows;y++) {
-            for (uint16_t x=0;x<(width/8)*bpp;x++) screenbuffer[index++]=screenbuffer[index2++];
-    }
-    fillRect(0,cursorY,width,height);
-    } else {
-    for (uint16_t y=pixelrows;y<height;y++) {
-            for (uint16_t x=0;x<(width*bpp)/8;x++) screenbuffer[index2++]=screenbuffer[index2];
-    }
-    fillRect(0,0,width,pixelrows);
-    }
-    color=oc;
-}
-
-void Display::fillScreen(uint16_t c) {
-    c = c & (PALETTE_SIZE-1) ; //don't let palette go out of bounds
-    if (bpp==1 && c) c=0xFF; // set all pixels
-    else if (bpp==2) {
-        c = bgcolor & 0x3;
-        c = c | (c << 2);
-        c = c | (c << 4);
-    } else {
-        c = (c & 0x0F) | (c << 4);
-    }
-    memset((void*)m_scrbuf,c,sizeof(screenbuffer));
-}
-
-void Display::setDefaultPalette() {
-    #if PICOPALETTE
-        loadRGBPalette(palettePico);
-    #else
-        loadRGBPalette(POK_DEFAULT_PALETTE);
-    #endif //PICOPALETTE
-}
-
-void Display::setColor(uint8_t c) {
-    color = c & ((1<<POK_COLORDEPTH)-1); // cut out colors that go above palette limit
-}
-
-void Display::setColor(uint8_t c,uint8_t bgc){
-    color = c & ((1<<POK_COLORDEPTH)-1); // cut out colors that go above palette limit
-    bgcolor = bgc & ((1<<POK_COLORDEPTH)-1); // cut out colors that go above palette limit
-}
-
-void Display::setInvisibleColor(uint16_t c){
-    invisiblecolor = c; // invisible color can have values beyond 255 for identification purposes
-}
-
-uint8_t Display::getColor() {
-    return color;
-}
-
-uint8_t Display::getBgColor() {
-    return bgcolor;
-}
-
-uint16_t Display::getInvisibleColor() {
-    return invisiblecolor;
-}
-
-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);
-    #if POK_GAMEBUINO_SUPPORT >0
-
-	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
-
-    #else
-    #if POK_COLORDEPTH == 1
-        if (col) {m_scrbuf[(y >> 3) * width + x] |= (0x80 >> (y & 7)); return;}
-        m_scrbuf[(y >> 3) * width + x] &= ~(0x80 >> (y & 7));
-    #elif POK_COLORDEPTH == 2
-        if (col) {
-                col &= 3;
-        }
-        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)|(col); // bits 0-1
-        else if (column==2) pixel = (pixel&0xF3)|(col<<2); // bits 2-3
-        else if (column==1) pixel = (pixel&0xCF)|(col<<4); // bits 4-5
-        else pixel = (pixel&0x3F)|(col<<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)|(col);
-    else pixel = (pixel&0x0F) | (col<<4);
-    m_scrbuf[i] = pixel;
-    #endif // POK_COLORDEPTH
-    #endif // POK_GAMEBUINO_SUPPORT
-}
-
-void Display::drawPixel(int16_t x,int16_t y) {
-    if ((uint16_t)x >= width || (uint16_t)y >= height) return;
-
-    #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
-}
-
-uint8_t Display::getPixel(int16_t x,int16_t y) {
-    if ((uint16_t)x >= width || (uint16_t)y >= height) return 0;
-    #if POK_GAMEBUINO_SUPPORT
-    uint8_t color=0; //jonne
-	for (uint8_t cbit=0; cbit<POK_COLORDEPTH;cbit++) {
-    	color |= (m_scrbuf[x + (y / 8) * LCDWIDTH+POK_BITFRAME*cbit] >> (y % 8)) & 0x1 ; //jonne - added +504*cbit
-	}
-	return color;
-    #else
-    /** not gamebuino */
-    #if POK_COLORDEPTH == 1
-        return (m_scrbuf[(y >> 3) * width + x] & (0x80 >> (y & 7))) ? 1:0;
-    #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==0) return pixel & 0x03; // bits 0-1
-        else if (column==1) return (pixel & 0x0C)>>2; // bits 2-3
-        else if (column==2) return (pixel & 0x30)>>4; // bits 4-5
-        else return pixel>>6;; // bits 6-7
-    #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) return pixel & 0x0F;
-    else return pixel>>4;
-    #endif // POK_COLORDEPTH
-    #endif // POK_GAMEBUINO_SUPPORT
-}
-
-void Display::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
-    if ((uint16_t)x0 >= width || (uint16_t)y0 >= height || (uint16_t)x1 >= width || (uint16_t)y1 >= height ) {
-        if (clipLine (&x0,&y0,&x1,&y1)==0) return; // line out of bounds
-    }
-	if (x0 == x1)
-		drawColumn(x0,y0,y1);
-	else if (y0 == y1)
-		drawRow(x0,x1,y0);
-	else {
-		int e;
-		signed int dx,dy,j, temp;
-		signed char s1,s2, xchange;
-		signed int x,y;
-
-		x = x0;
-		y = y0;
-
-		//take absolute value
-		if (x1 < x0) {
-			dx = x0 - x1;
-			s1 = -1;
-		}
-		else if (x1 == x0) {
-			dx = 0;
-			s1 = 0;
-		}
-		else {
-			dx = x1 - x0;
-			s1 = 1;
-		}
-
-		if (y1 < y0) {
-			dy = y0 - y1;
-			s2 = -1;
-		}
-		else if (y1 == y0) {
-			dy = 0;
-			s2 = 0;
-		}
-		else {
-			dy = y1 - y0;
-			s2 = 1;
-		}
-
-		xchange = 0;
-
-		if (dy>dx) {
-			temp = dx;
-			dx = dy;
-			dy = temp;
-			xchange = 1;
-		}
-
-		e = ((int)dy<<1) - dx;
-
-		for (j=0; j<=dx; j++) {
-			drawPixel(x,y);
-
-			if (e>=0) {
-				if (xchange==1) x = x + s1;
-				else y = y + s2;
-				e = e - ((int)dx<<1);
-			}
-			if (xchange==1)
-				y = y + s2;
-			else
-				x = x + s1;
-			e = e + ((int)dy<<1);
-		}
-	}
-}
-
-uint8_t Display::clipLine(int16_t *x0, int16_t *y0, int16_t *x1, int16_t *y1){
-    // Check X bounds
-	if (*x1<*x0) {
-        //std::swap (*x1,*x0); // swap so that we dont have to check x1 also
-        swapWT(int16_t*,x1,x0);
-        //std::swap (*y1,*y0); // y needs to be swaaped also
-        swapWT(int16_t*,y1,y0);
-	}
-
-	if (*x0>=width) return 0; // whole line is out of bounds
-
-	// Clip against X0 = 0
-	if (*x0 < 0) {
-        if ( *x1 < 0) return 0; // nothing visible
-        int16_t dx = (*x1 - *x0);
-        int16_t dy = ((*y1 - *y0) << 8); // 8.8 fixed point calculation trick
-        int16_t m = dy/dx;
-        *y0 = *y0 + ((m*-*x0)>>8); // get y0 at boundary
-        *x0 = 0;
-	}
-
-	// Clip against x1 = 83
-	if (*x1 >= width) {
-        int16_t dx = (*x1 - *x0);
-        int16_t dy = ((*y1 - *y0) << 8); // 8.8 fixed point calculation trick
-        int16_t m = dy/dx;
-        //*y1 = *y1 + ((m*(*x1-XMAX))>>8); // get y0 at boundary
-        *y1 = *y1 + ((m*(width-1-*x1))>>8); // get y0 at boundary
-        *x1 = width-1;
-	}
-
-    // Check Y bounds
-	if (*y1<*y0) {
-        //std::swap (*x1,*x0); // swap so that we dont have to check x1 also
-        swapWT(int16_t*,x1,x0);
-        //std::swap (*y1,*y0); // y needs to be swaaped also
-        swapWT(int16_t*,y1,y0);
-	}
-
-	if (*y0>=height) return 0; // whole line is out of bounds
-
-    if (*y0 < 0) {
-        if ( *y1 < 0) return 0; // nothing visible
-        int16_t dx = (*x1 - *x0) << 8;
-        int16_t dy = (*y1 - *y0); // 8.8 fixed point calculation trick
-        int16_t m = dx/dy;
-        *x0 = *x0 + ((m*-*y0)>>8); // get x0 at boundary
-        *y0 = 0;
-	}
-
-    // Clip against y1 = 47
-	if (*y1 >= height) {
-        int16_t dx = (*x1 - *x0) << 8;
-        int16_t dy = (*y1 - *y0); // 8.8 fixed point calculation trick
-        int16_t m = dx/dy;
-        *x1 = *x1 + ((m*(height-1-*y1))>>8); // get y0 at boundary
-        //*x1 = *x1 + ((m*(*y1-YMAX))>>8); // get y0 at boundary
-        *y1 = height-1;
-	}
-	return 1; // clipped succesfully
-}
-
-void Display::map1BitColumn(int16_t x, int16_t sy, int16_t ey, const uint8_t* bitmap, uint16_t column){
-    if ((uint16_t)sy>=height && (uint16_t)ey>=height) return; //completely out of bounds
-    if ((uint16_t)x>=width) return; //completely out of bounds
-    if (sy>ey) {
-            int y=sy;
-            sy=ey;
-            ey=y; // swap around so that x0 is less than x1
-    }
-    uint16_t bmw,bmh;
-    float texelstep, texelindex;
-    bmw = *(bitmap);
-    bmh = *(bitmap+1);
-    if (column>bmw-1) column=bmw-1;
-    bitmap += 2;
-    bitmap += column;
-    texelstep = (float)bmh/((float)ey-(float)sy);
-    texelindex = 0;
-    for (int y=sy; y <= ey; y++, texelindex += texelstep) {
-        uint8_t texel;
-        uint8_t currbyte, bit;
-        currbyte = texelindex / 8;
-        bit = 7-((uint16_t) texelindex & 0x7);
-        texel=*(bitmap+currbyte*bmw);
-        if (texel & (1<<bit)) drawPixel(x,y);
-        else if (bgcolor != invisiblecolor) drawPixel(x,y,bgcolor);
-    }
-};
-
-void Display::drawColumn(int16_t x, int16_t sy, int16_t ey){
-    if ((uint16_t)sy>=height && (uint16_t)ey>=height) return; //completely out of bounds
-    if ((uint16_t)x>=width) return; //completely out of bounds
-    if (sy>ey) {
-            int y=sy;
-            sy=ey;
-            ey=y; // swap around so that x0 is less than x1
-    }
-    for (int y=sy; y <= ey; y++) {
-        drawPixel(x,y);
-    }
-}
-
-void Display::drawRow(int16_t x0, int16_t x1, int16_t y){
-    if ((uint16_t)x0>=width && (uint16_t)x1>=width) return; //completely out of bounds
-    if ((uint16_t)y>=height) return; //completely out of bounds
-
-    if (x0>x1) {
-            int x=x0;
-            x0=x1;
-            x1=x; // swap around so that x0 is less than x1
-    }
-    for (int x=x0; x <= x1; x++) {
-        drawPixel(x,y);
-    }
-}
-
-void Display::drawFastVLine(int16_t x, int16_t y, int16_t h){
-    if (h<0) {y += h; h = -h;}
-    drawColumn(x,y,y+h);
-}
-
-void Display::drawFastHLine(int16_t x, int16_t y, int16_t w){
-    if (w<0) {x += w; w = -w;}
-    drawRow(x,x+w-1,y);
-}
-
-void Display::drawRectangle(int16_t x0, int16_t y0, int16_t w, int16_t h) {
-    drawColumn(x0,y0,y0+h);
-    drawColumn(x0+w,y0,y0+h);
-    drawRow(x0,x0+w,y0);
-    drawRow(x0,x0+w,y0+h);
-}
-
-void Display::fillRectangle(int16_t x0,int16_t y0, int16_t w, int16_t h){
-    int16_t x,y,x1,y1;
-    x1=x0+w;y1=y0+h;
-    if ((x0<0 && x1<0) || (x0>=width && x1 >=width)) return; //completely out of bounds
-    if ((y0<0 && y1<0) || (y0>=height && y1 >=height)) return; //completely out of bounds
-    if (x0>x1) {x=x1;x1=x0;}
-    else x=x0;
-    if (y0>y1) {y=y1;y1=y0;}
-    else y=y0;
-    if (x<0) x=0;
-    if (y<0) y=0;
-    for (;x<x1;x++) drawColumn(x,y,y1);
-}
-
-void Display::fillRect(int16_t x, int16_t y, int16_t w, int16_t h) {
-    fillRectangle(x,y,w,h);
-}
-
-void Display::drawRect(int16_t x, int16_t y, int16_t w, int16_t h) {
-    drawRectangle(x,y,w,h);
-}
-
-void Display::drawCircle(int16_t x0, int16_t y0, int16_t r) {
-    int16_t f = 1 - r;
-    int16_t ddF_x = 1;
-    int16_t ddF_y = -2 * r;
-    int16_t x = 0;
-    int16_t y = r;
-
-    drawPixel(x0, y0 + r);
-    drawPixel(x0, y0 - r);
-    drawPixel(x0 + r, y0);
-    drawPixel(x0 - r, y0);
-
-    while (x < y) {
-        if (f >= 0) {
-
-            y--;
-            ddF_y += 2;
-            f += ddF_y;
-        }
-        x++;
-        ddF_x += 2;
-        f += ddF_x;
-
-        drawPixel(x0 + x, y0 + y);
-        drawPixel(x0 - x, y0 + y);
-        drawPixel(x0 + x, y0 - y);
-        drawPixel(x0 - x, y0 - y);
-        drawPixel(x0 + y, y0 + x);
-        drawPixel(x0 - y, y0 + x);
-        drawPixel(x0 + y, y0 - x);
-        drawPixel(x0 - y, y0 - x);
-
-    }
-}
-
-void Display::drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint16_t cornername) {
-    int16_t f = 1 - r;
-    int16_t ddF_x = 1;
-    int16_t ddF_y = -2 * r;
-    int16_t x = 0;
-    int16_t y = r;
-
-    while (x < y) {
-        if (f >= 0) {
-            y--;
-            ddF_y += 2;
-            f += ddF_y;
-        }
-        x++;
-        ddF_x += 2;
-        f += ddF_x;
-        if (cornername & 0x4) {
-            drawPixel(x0 + x, y0 + y);
-            drawPixel(x0 + y, y0 + x);
-        }
-        if (cornername & 0x2) {
-            drawPixel(x0 + x, y0 - y);
-            drawPixel(x0 + y, y0 - x);
-        }
-        if (cornername & 0x8) {
-            drawPixel(x0 - y, y0 + x);
-            drawPixel(x0 - x, y0 + y);
-        }
-        if (cornername & 0x1) {
-
-            drawPixel(x0 - y, y0 - x);
-            drawPixel(x0 - x, y0 - y);
-        }
-    }
-}
-
-void Display::fillCircle(int16_t x0, int16_t y0, int16_t r) {
-    drawFastVLine(x0, y0 - r, 2 * r );
-    fillCircleHelper(x0, y0, r, 3, 0);
-}
-
-void Display::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint16_t cornername, int16_t delta) {
-    int16_t f = 1 - r;
-    int16_t ddF_x = 1;
-    int16_t ddF_y = -2 * r;
-    int16_t x = 0;
-    int16_t y = r;
-
-    while (x < y) {
-        if (f >= 0) {
-            y--;
-            ddF_y += 2;
-            f += ddF_y;
-        }
-        x++;
-        ddF_x += 2;
-        f += ddF_x;
-
-        if (cornername & 0x1) {
-            drawFastVLine(x0 + x, y0 - y, 2 * y + 1 + delta-1); //added -1 here, jonne
-            drawFastVLine(x0 + y, y0 - x, 2 * x + 1 + delta-1); //added -1 here, jonne
-        }
-        if (cornername & 0x2) {
-
-            drawFastVLine(x0 - x, y0 - y, 2 * y + 1 + delta-1); //added -1 here, jonne
-            drawFastVLine(x0 - y, y0 - x, 2 * x + 1 + delta-1); //added -1 here, jonne
-        }
-    }
-}
-
-void Display::drawRoundRect(int16_t x, int16_t y, int16_t w,int16_t h, int16_t r) {
-    if (r<2) {drawRectangle(x,y,w,h);return;}
-    // smarter version
-    drawFastHLine(x + r, y, w - 2 * r); // Top
-    drawFastHLine(x + r, y + h - 1, w - 2 * r); // Bottom
-    drawFastVLine(x, y + r, h - 2 * r); // Left
-    drawFastVLine(x + w - 1, y + r, h - 2 * r); // Right
-    // draw four corners
-    drawCircleHelper(x + r, y + r, r, 1);
-    drawCircleHelper(x + w - r - 1, y + r, r, 2);
-    drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4);
-    drawCircleHelper(x + r, y + h - r - 1, r, 8);
-}
-
-void Display::fillRoundRect(int16_t x, int16_t y, int16_t w,int16_t h, int16_t r) {
-    if (r<2) {fillRectangle(x,y,w,h);return;}
-    fillRectangle(x + r, y, w - 2 * r, h-1);
-    // draw four corners
-    fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1);
-    fillCircleHelper(x + r, y + r, r, 2, h - 2 * r - 1);
-}
-
-void Display::drawTriangle(int16_t x0, int16_t y0,
-        int16_t x1, int16_t y1,
-        int16_t x2, int16_t y2) {
-    drawLine(x0, y0, x1, y1);
-    drawLine(x1, y1, x2, y2);
-    drawLine(x2, y2, x0, y0);
-}
-
-void Display::fillTriangle(int16_t x0, int16_t y0,
-        int16_t x1, int16_t y1,
-        int16_t x2, int16_t y2) {
-    int16_t a, b, y, last;
-
-    // Sort coordinates by Y order (y2 >= y1 >= y0)
-    if (y0 > y1) {
-        swapWT(int16_t,y0, y1);
-        swapWT(int16_t,x0, x1);
-    }
-    if (y1 > y2) {
-        swapWT(int16_t,y2, y1);
-        swapWT(int16_t,x2, x1);
-    }
-    if (y0 > y1) {
-        swapWT(int16_t,y0, y1);
-        swapWT(int16_t,x0, x1);
-    }
-
-    if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing
-        a = b = x0;
-        if (x1 < a) a = x1;
-        else if (x1 > b) b = x1;
-        if (x2 < a) a = x2;
-        else if (x2 > b) b = x2;
-        drawFastHLine(a, y0, b - a + 1);
-        return;
-    }
-
-    int16_t
-    dx01 = x1 - x0,
-            dy01 = y1 - y0,
-            dx02 = x2 - x0,
-            dy02 = y2 - y0,
-            dx12 = x2 - x1,
-            dy12 = y2 - y1,
-            sa = 0,
-            sb = 0;
-
-    // For upper part of triangle, find scanline crossings for segments
-    // 0-1 and 0-2.  If y1=y2 (flat-bottomed triangle), the scanline y1
-    // is included here (and second loop will be skipped, avoiding a /0
-    // error there), otherwise scanline y1 is skipped here and handled
-    // in the second loop...which also avoids a /0 error here if y0=y1
-    // (flat-topped triangle).
-    if (y1 == y2) last = y1; // Include y1 scanline
-    else last = y1 - 1; // Skip it
-
-    for (y = y0; y <= last; y++) {
-        a = x0 + sa / dy01;
-        b = x0 + sb / dy02;
-        sa += dx01;
-        sb += dx02;
-        /* longhand:
-        a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
-        b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
-         */
-        if (a > b) swapWT(int16_t,a, b);
-        drawFastHLine(a, y, b - a + 1);
-    }
-
-    // For lower part of triangle, find scanline crossings for segments
-    // 0-2 and 1-2.  This loop is skipped if y1=y2.
-    sa = dx12 * (y - y1);
-    sb = dx02 * (y - y0);
-    for (; y <= y2; y++) {
-        a = x1 + sa / dy12;
-        b = x0 + sb / dy02;
-        sa += dx12;
-        sb += dx02;
-
-        if (a > b) swapWT(int16_t,a, b);
-        drawFastHLine(a, y, b - a + 1);
-    }
-}
-
-void Display::setFont(const unsigned char * f) {
-	font = f;
-	fontWidth = *(font)+1;
-	fontHeight = *(font + 1)+1;
-}
-
-void Display::drawMonoBitmap(int16_t x, int16_t y, const uint8_t* bitmap, uint8_t index) {
-    uint8_t w = *bitmap;
-	uint8_t h = *(bitmap + 1);
-	uint8_t xtra=0;
-	if (w&0x7) xtra=1;
-	bitmap = bitmap + 3 + index * h * ((w>>3)+xtra); //add an offset to the pointer (fonts !)
-    #if POK_GAMEBUINO_SUPPORT > 0
-    int8_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 + i, y + j);
-            }
-        }
-    }
-    #else
-    /** not gamebuino */
-    int8_t scrx,scry;
-    uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
-    int8_t bitptr;
-    for (scry = y; scry < y+h; scry+=1) {
-            if ((x&1)==0) { /** EVEN pixel starting line**/
-                for (scrx = x, bitptr=7; scrx < w+x; scrx+=2) {
-                    uint8_t targetpixel = *scrptr;
-                    if (*bitmap & (1<<bitptr)) targetpixel = (targetpixel & 0xF) | color<<4; // upper nibble
-                    else if (bgcolor != invisiblecolor) targetpixel = (targetpixel & 0xF) | bgcolor<<4; // upper nibble
-                    bitptr--;
-                    if (*bitmap & (1<<bitptr)) targetpixel = (targetpixel & 0xF0) | color; // lower nibble
-                    else if (bgcolor != invisiblecolor) targetpixel = (targetpixel & 0xF0) | bgcolor; // lower nibble
-                    bitptr--;
-                    if (bitptr<0) { bitptr = 7; bitmap++; }
-                    *scrptr = targetpixel;
-                    scrptr++;
-                }
-            } else { /** ODD pixel starting line **/
-                for (scrx = x, bitptr=7; scrx < w+x; scrx+=2) {
-                    uint8_t targetpixel = *scrptr;
-                    // store higher nibble of source pixel in lower nibble of target
-                    if (*bitmap & (1<<bitptr)) targetpixel = (targetpixel & 0xF0) | color; // lower nibble
-                    else if (bgcolor != invisiblecolor) targetpixel = (targetpixel & 0xF0) | bgcolor; // lower nibble
-                    *scrptr = targetpixel; // store
-                    bitptr--;scrptr++;targetpixel = *scrptr;
-                    // store lower nibble of source pixel in higher nibble of target
-                    if (*bitmap & (1<<bitptr)) targetpixel = (targetpixel & 0xF) | color<<4; // higher nibble
-                    else if (bgcolor != invisiblecolor) targetpixel = (targetpixel & 0xF) | bgcolor<<4; // higher nibble
-                    *scrptr = targetpixel; // store
-                    bitptr--; // do not increment scrptr here !
-                }
-            }
-            if (bitptr!=7) bitmap++; // force skip to next line
-            // increment the y jump in the scrptr
-            scrptr = scrptr + ((width - w)>>1);
-    }
-    #endif // POK_GAMEBUINO_SUPPORT
-}
-
-
-void Display::drawBitmap(int16_t x, int16_t y, const uint8_t* bitmap, uint8_t frame)
-{
-    int16_t w = *bitmap;
-	int16_t h = *(bitmap + 1);
-	uint8_t framew = *(bitmap+2);
-    bitmap = bitmap + 3; //add an offset to the pointer to start after the width and height
-    /** visibility check */
-    if (y<-h || y>height) return; //invisible
-    if (x<-framew || 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 + i, y + j);
-            }
-        }
-    }
-
-    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);
-            }
-        }
-    }
-
-    return;
-    }
-    /** 4bpp fast version */
-	int16_t scrx,scry,xclip,xjump,scrxjump;
-    xclip=xjump=scrxjump=0;
-    bitmap += (framew*frame)>>1;
-    /** y clipping */
-    if (y<0) { h+=y; bitmap -= y*(w>>1); y=0;}
-    else if (y+h>height) { h -=(y-height);}
-    /** x clipping */
-    xjump = (w-framew)>>1;
-    if (x<0) { xclip=(x&1)<<1; framew+=x; xjump = ((-x)>>1); bitmap += xjump; x=0;}
-    else if (x+framew>width) {
-            xclip = (x&1)<<1;
-            scrxjump = x&1;
-            xjump=((x+framew-width)>>1)+scrxjump;
-            framew = width-x;}
-
-    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) {
-            if (scry>=height) return;
-            if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
-                for (scrx = x; scrx < framew+x-xclip; scrx+=2) {
-                    uint8_t sourcepixel = *bitmap;
-                    if (xclip) {
-                            sourcepixel <<=4;
-                            sourcepixel |= ((*(bitmap+1))>>4);
-                    }
-                    uint8_t targetpixel = *scrptr;
-                    if ((sourcepixel>>4) != invisiblecolor ) targetpixel = (targetpixel&0x0F) | (sourcepixel & 0xF0);
-                    if ((sourcepixel&0x0F) != invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel & 0x0F);
-                    *scrptr = targetpixel;
-                    bitmap++;
-                    scrptr++;
-                }
-                if (xclip){
-                    if (framew&1) {
-                        /**last pixel is odd pixel due to clipping & odd width*/
-                        uint8_t sourcepixel = *bitmap;
-                        if ((sourcepixel&0x0F) != invisiblecolor) {
-                            sourcepixel <<=4;
-                            uint8_t targetpixel = *scrptr;// & 0x0F;
-                            targetpixel |= sourcepixel;
-                            *scrptr = targetpixel;
-                        }
-                        //scrptr++;
-                    }
-                    bitmap++;
-                    scrptr++;
-                }
-                bitmap += xjump; // needed if x<0 clipping occurs
-            } else { /** ODD pixel starting line **/
-                for (scrx = x; scrx < framew+x-xclip; scrx+=2) {
-                    uint8_t sourcepixel = *bitmap;
-                    uint8_t targetpixel = *scrptr;
-                    // store higher nibble of source pixel in lower nibble of target
-                    if((sourcepixel>>4)!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel >> 4 );
-                    *scrptr = targetpixel;
-                    scrptr++;
-                    targetpixel = *scrptr;
-                    // store lower nibble of source pixel in higher nibble of target
-                    if((sourcepixel&0x0F)!=invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel << 4);
-                    *scrptr = targetpixel;
-                    bitmap++;
-                }
-                bitmap+=xjump;
-            }
-            // increment the y jump in the scrptr
-            scrptr = scrptr + ((width - framew)>>1)+scrxjump;
-    }
-}
-
-
-void Display::drawBitmap(int16_t x, int16_t y, 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 + i, y + j);
-            }
-        }
-    }
-
-    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);
-            }
-        }
-    }
-
-    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 */
-    if (x<0) { xclip=(x&1)<<1; w+=x; xjump = ((-x)>>1); bitmap += xjump; x=0;}
-    else if (x+w>width) {
-            xclip = (x&1)<<1;
-            scrxjump = x&1;
-            xjump=((x+w-width)>>1)+scrxjump;
-            w = width-x;}
-
-    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) {
-            if (scry>=height) return;
-            if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
-                for (scrx = x; scrx < w+x-xclip; scrx+=2) {
-                    uint8_t sourcepixel = *bitmap;
-                    if (xclip) {
-                            sourcepixel <<=4;
-                            sourcepixel |= ((*(bitmap+1))>>4);
-                    }
-                    uint8_t targetpixel = *scrptr;
-                    if ((sourcepixel>>4) != invisiblecolor ) targetpixel = (targetpixel&0x0F) | (sourcepixel & 0xF0);
-                    if ((sourcepixel&0x0F) != invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel & 0x0F);
-                    *scrptr = targetpixel;
-                    bitmap++;
-                    scrptr++;
-                }
-                if (xclip){
-                    if (w&1) {
-                        /**last pixel is odd pixel due to clipping & odd width*/
-                        uint8_t sourcepixel = *bitmap;
-                        if ((sourcepixel&0x0F) != invisiblecolor) {
-                            sourcepixel <<=4;
-                            uint8_t targetpixel = *scrptr;// & 0x0F;
-                            targetpixel |= sourcepixel;
-                            *scrptr = targetpixel;
-                        }
-                        //scrptr++;
-                    }
-                    bitmap++;
-                    scrptr++;
-                }
-                bitmap += xjump; // needed if x<0 clipping occurs
-            } else { /** ODD pixel starting line **/
-                for (scrx = x; scrx < w+x-xclip; scrx+=2) {
-                    uint8_t sourcepixel = *bitmap;
-                    uint8_t targetpixel = *scrptr;
-                    // store higher nibble of source pixel in lower nibble of target
-                    if((sourcepixel>>4)!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel >> 4 );
-                    *scrptr = targetpixel;
-                    scrptr++;
-                    targetpixel = *scrptr;
-                    // store lower nibble of source pixel in higher nibble of target
-                    if((sourcepixel&0x0F)!=invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel << 4);
-                    *scrptr = targetpixel;
-                    bitmap++;
-                }
-                bitmap+=xjump;
-            }
-            // increment the y jump in the scrptr
-            scrptr = scrptr + ((width - w)>>1)+scrxjump;
-    }
-}
-
-void Display::drawRleBitmap(int16_t x, int16_t y, const uint8_t* rlebitmap)
-{
-    // ONLY can copy 4-bit bitmap to 4-bit screen mode for time being
-    #if (POK_SCREENMODE != MODE_FAST_16COLOR)
-    return;
-    #endif
-
-    int16_t w = *rlebitmap;
-	int16_t h = *(rlebitmap + 1);
-    rlebitmap = rlebitmap + 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
-
-    // Clipping is not supported
-    if ((x < 0) || (x+w > width) || (y < 0) || (y+h > height)) return;
-
-    // Currently only support RLE bitmaps in 16 color mode.
-    if (m_colordepth != 4)  //
-        return;
-
-    // Go through each line.
-    uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
-    bool is_endofbitmap = false;
-    for (int16_t scry = y; scry < y+h && !is_endofbitmap;) {
-
-        // Process one line. Go through each pixel run and escape command in RLE data.
-        for (int16_t scrx = x;;) {
-            uint8_t rle_count = *rlebitmap++;
-
-            if (rle_count == 0) {
-
-               /** Escape or absolute mode */
-
-                uint8_t rle_escape_or_runsize = *rlebitmap++;
-                if ( rle_escape_or_runsize == RLE_ESC_EOL) {
-                    // End of line.
-                    break;
-                }
-                else if ( rle_escape_or_runsize == RLE_ESC_EOB) {
-                    // End of bitmap.
-                    is_endofbitmap = true;
-                    break;
-                }
-                else if ( rle_escape_or_runsize == RLE_ESC_OFFSET) {
-                    // Move position in target.
-                    // TODO: not tested yet.
-                    uint8_t xoffset = *rlebitmap++;
-                    uint8_t yoffset = *rlebitmap++;
-                    scrptr += (xoffset>1);
-                    scrx += xoffset;
-                    scrptr += yoffset*width;
-                    scry += yoffset;
-                 }
-                else {
-
-                    /** Absolute mode. Copy pixels from the source bitmap to the target screen. */
-
-                    int16_t runsize = rle_escape_or_runsize;
-                    uint8_t targetpixel = *scrptr;  // initial value
-                    uint8_t sourcepixel = *rlebitmap;  // initial value
-                    for( int16_t runx = 0; runx < runsize; ) {
-                        if (scrx&0x1)  { // screen pixel is in the low nibble
-                            if (runx&0x1) { // bitmap pixel is in the low nibble
-                                if ((sourcepixel&0x0F) != invisiblecolor)
-                                    targetpixel = (targetpixel&0xF0) | (sourcepixel&0x0F); // Copy low to low nibble.
-                                rlebitmap++;
-                            }
-                            else // bitmap pixel is in the high nibble
-                                if ((sourcepixel>>4) != invisiblecolor)
-                                    targetpixel = (targetpixel&0xF0) | (sourcepixel>>4); // Copy high to low nibble.
-
-                            // Copy the byte to the target.
-                            *scrptr = targetpixel;
-                            scrptr++;
-                        }
-                        else  { // screen pixel is in the high nibble
-                            targetpixel = *scrptr;
-                            sourcepixel = *rlebitmap;
-                            if (runx&0x1) { // bitmap pixel is sourcepixel = *rlebitmapin the low nibble
-                                if ((sourcepixel&0x0F) != invisiblecolor )
-                                    targetpixel = (targetpixel&0x0F) | ((sourcepixel<<4)&0xF0); // Copy low to high nibble.
-                                rlebitmap++;  // read the new source byte
-                            }
-                            else // bitmap pixel is in the high nibble
-                                if ((sourcepixel>>4) != invisiblecolor )
-                                    targetpixel = (targetpixel&0x0F) | (sourcepixel&0xF0); // Copy high to high nibble.
-                        }
-                        runx++;
-                        scrx++;
-                    }  // end for
-
-                     // If this is odd target index, copy the byte to the target.
-                    if (scrx&0x1) {
-                        *scrptr = targetpixel;
-                        scrptr++;
-                    }
-
-                    // In absolute mode the source size is always padded to the word boundary.
-                    if (runsize%4) {
-                        int16_t padpixcount = 4 - (runsize%4);
-                        rlebitmap += padpixcount>>1;  // skip n padding bytes
-                    }
-                }
-            }
-            else {
-
-                /** Encoded mode. Duplicate one pixel pair to the all required pixels on the target screen */
-
-                int16_t runsize = rle_count;
-                uint8_t clonepixelpair = *rlebitmap++;
-                uint8_t targetpixel = *scrptr;  // initial value
-                for( int16_t runx = 0;  runx < runsize; ) {
-                    if (scrx&0x1)  { // screen pixel is in the low nibble
-                        if (runx&0x1) { // bitmap pixel is in the low nibble
-                            if ((clonepixelpair&0x0F) != invisiblecolor)
-                                targetpixel = (targetpixel&0xF0) | (clonepixelpair&0x0F); // Copy low to low nibble.
-                        }
-                        else // bitmap pixel is in the high nibble
-                            if ((clonepixelpair>>4) != invisiblecolor)
-                                targetpixel = (targetpixel&0xF0) | (clonepixelpair>>4); // Copy high to low nibble.
-
-                        // Copy the byte to the target.
-                        *scrptr = targetpixel;
-                        scrptr++;
-                    }
-                    else  { // screen pixel is in the high nibble
-                        targetpixel = *scrptr;
-                        if (runx&0x1) {// bitmap pixel is in the low nibble
-                            if ((clonepixelpair&0x0F) != invisiblecolor )
-                                targetpixel = (targetpixel&0x0F) | ((clonepixelpair<<4)&0xF0); // Copy low to high nibble.
-                        }
-                        else // bitmap pixel is in the high nibble
-                            if ((clonepixelpair>>4) != invisiblecolor )
-                                targetpixel = (targetpixel&0x0F) | (clonepixelpair&0xF0); // Copy high to high nibble.
-                    }
-                    runx++;
-                    scrx++;
-
-                }  // end for
-
-                // If this is odd target index, copy the byte to the target.
-                if (scrx&0x1) {
-                    *scrptr = targetpixel;
-                    scrptr++;
-                 }
-            } // end if
-        }  // end while
-
-        // Increment the target screen pointer and index.
-        scrptr = scrptr + ((width - w)>>1);
-        scry++;
-    } // end for scry
-}
-
-void Display::drawBitmapXFlipped(int16_t x, int16_t y, 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);
-            }
-        }
-    }
-
-    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);
-            }
-        }
-    }
-
-    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) {
-            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) {
-            xclip = (x&1)<<1;
-            scrxjump = x&1;
-            xjump=((x+w-width)>>1)+scrxjump;
-            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) {
-            if (scry>=height) return;
-            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) {
-                    uint8_t sourcepixel = *(bitmap);
-                    if (xclip) {
-                            sourcepixel <<=4;
-                            sourcepixel |= ((*(bitmap-1))>>4);//inverted!
-                    }
-                    uint8_t targetpixel = *scrptr;
-                    // NIBBLES ARE INVERTED BECAUSE PICTURE IS FLIPPED !!!
-                    if ((sourcepixel>>4) != invisiblecolor ) targetpixel = (targetpixel&0xF0) | (sourcepixel>>4);
-                    if ((sourcepixel&0x0F) != invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel<<4);
-                    *scrptr = targetpixel;
-                    bitmap--;
-                    scrptr++;
-                }
-                bitmap += w; // w*2 >> 1 because inverted and because 2 pixels per byte!!
-                if (xclip){
-                    if (w&1) {
-                        /**last pixel is odd pixel due to clipping & odd width*/
-                        uint8_t sourcepixel = *bitmap;
-                        if ((sourcepixel&0x0F) != invisiblecolor) {
-                            sourcepixel <<=4;
-                            uint8_t targetpixel = *scrptr;// & 0x0F;
-                            targetpixel |= sourcepixel;
-                            *scrptr = targetpixel;
-                        }
-                        //scrptr++;
-                    }
-                    bitmap++;
-                    scrptr++;
-                }
-                bitmap += xjump; // needed if x<0 clipping occurs
-            } 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
-                    if((sourcepixel&0x0F)!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel & 0x0F );
-                    *scrptr = targetpixel;
-                    scrptr++;
-                    targetpixel = *scrptr;
-                    // inverted ! store higher nibble of source pixel in higher nibble of target
-                    if((sourcepixel>>4)!=invisiblecolor) targetpixel = (targetpixel & 0x0F) | (sourcepixel & 0xF0);
-                    *scrptr = targetpixel;
-                    bitmap--;
-                }
-                bitmap += w; // w*2 >> 1 because inverted and because 2 pixels per byte!!
-                bitmap+=xjump;
-            }
-            // increment the y jump in the scrptr
-            scrptr = scrptr + ((width - w)>>1)+scrxjump;
-    }
-}
-
-void Display::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t rotation, uint8_t flip) {
-#if PROJ_GAMEBUINO == 0
-    if (!flip) drawBitmap(x,y,bitmap);
-    else drawBitmapXFlipped(x,y,bitmap);
-#else
-	if((rotation == NOROT) && (flip == NOFLIP)){
-		drawBitmap(x,y,bitmap); //use the faster algorithm
-		return;
-	}
-	uint8_t w = bitmap[0];
-	uint8_t h = bitmap[1];
-	bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
-    int8_t i, j, //coordinates in the raw bitmap
-            k, l, //coordinates in the rotated/flipped bitmap
-            byteNum, bitNum, byteWidth = (w + 7) >> 3;
-
-    rotation %= 4;
-
-    for (i = 0; i < w; i++) {
-        byteNum = i / 8;
-        bitNum = i % 8;
-        for (j = 0; j < h; j++) {
-            if (bitmap[j * byteWidth + byteNum] & (B10000000 >> bitNum)) {
-                switch (rotation) {
-                    case NOROT: //no rotation
-                        k = i;
-                        l = j;
-                        break;
-                    case ROTCCW: //90� counter-clockwise
-                        k = j;
-                        l = w - i - 1;
-                        break;
-                    case ROT180: //180�
-                        k = w - i - 1;
-                        l = h - j - 1;
-                        break;
-                    case ROTCW: //90� clockwise
-                        k = h - j - 1;
-                        l = i;
-                        break;
-                }
-                if (flip) {
-                    flip %= 4;
-                    if (flip & B00000001) { //horizontal flip
-                        k = w - k;
-                    }
-                    if (flip & B00000010) { //vertical flip
-                        l = h - l;
-                    }
-                }
-                k += x; //place the bitmap on the screen
-                l += y;
-                drawPixel(k, l);
-            }
-        }
-    }
-#endif //PROJ_GAMEBUINO
-
-}
-
-uint8_t* Display::getBuffer() {
-    return m_scrbuf;
-}
-
-uint8_t Display::getBitmapPixel(const uint8_t* bitmap, uint16_t x, uint16_t y) {
-    uint16_t w = *bitmap;
-    uint8_t sourcebyte = bitmap[2+(y * ((w+7)>>3))+ (x>>3)];
-    return sourcebyte & (0x80>>(x&7));
-}
-
-int Display::print_char(uint8_t x, uint8_t y, unsigned char c) {
-	c -= font[2];
-	if (m_mode) return directChar(x,y,c);
-	return bufferChar(x,y,c);
-}
-
-void Display::drawChar(int8_t x, int8_t y, unsigned char c, uint8_t size) {
-	print_char(x,y,c);
-	return;
-}
-
-
-bool Display::isDirectPrintingEnabled() {
-    return m_mode;
-}
-
-void Display::enableDirectPrinting(uint8_t m) {
-    if (m) {
-            m_mode=true;
-            m_w = POK_LCD_W;
-            m_h = POK_LCD_H;
-    } else {
-            m_mode=false;
-            m_w = getWidth();
-            m_h = getHeight();
-    }
-}
-
-void Display::write(uint8_t c) {
-	int charstep=0;
-	if(font[3]) {
-        // only caps in this font
-        if (c>=97) c-=32;
-	}
-	switch(c) {
-		case '\0':			//null
-			break;
-		case '\n':			//line feed
-			cursorX = 0;
-			inc_txtline();
-			break;
-		case 8:				//backspace
-			cursorX -= font[0];
-			charstep=print_char(cursorX,cursorY,' ');
-			break;
-		case 13:			//carriage return
-			cursorX = 0;
-			break;
-		case 14:			//form feed new page(clear screen)
-			//clear_screen();
-			break;
-		default:
-			if (cursorX >= (m_w - font[0])) {
-				cursorX = 0;
-				if (textWrap) inc_txtline();
-				else return; // stop outputting text
-				charstep=print_char(cursorX,cursorY,c);
-			}
-			else
-				charstep=print_char(cursorX,cursorY,c);
-			if (c==' ' && adjustCharStep) charstep=(charstep>>1)+1;
-			cursorX += charstep;
-	}
-}
-
-void Display::inc_txtline() {
-	if (cursorY > m_h - 2*font[1]) //= (height - (font[1]+1)))
-		#if SCROLL_TEXT > 0
-		scroll(font[1] + adjustLineStep);
-		#else
-		cursorY = 0;
-		#endif
-	else
-		cursorY += font[1] + adjustLineStep;
-}
-
-/* default implementation: may be overridden */
-void Display::write(const char *str)
-{
-  while (*str)
-    write(*str++);
-}
-
-/* default implementation: may be overridden */
-void Display::write(const uint8_t *buffer, uint8_t size)
-{
-  while (size--)
-    write(*buffer++);
-}
-
-void Display::print(const char str[])
-{
-  write(str);
-}
-
-void Display::print(char c, int base)
-{
-  print((long) c, base);
-}
-
-void Display::print(unsigned char b, int base)
-{
-  print((unsigned long) b, base);
-}
-
-void Display::print(int n, int base)
-{
-  print((long) n, base);
-}
-
-void Display::print(unsigned int n, int base)
-{
-  print((unsigned long) n, base);
-}
-
-void Display::print(long n, int base)
-{
-  if (base == 0) {
-    write(n);
-  } else if (base == 10) {
-    if (n < 0) {
-      print('-');
-      n = -n;
-    }
-    printNumber(n, 10);
-  } else {
-    printNumber(n, base);
-  }
-}
-
-void Display::print(unsigned long n, int base)
-{
-  if (base == 0) write(n);
-  else printNumber(n, base);
-}
-
-void Display::print(double n, int digits)
-{
-  printFloat(n, digits);
-}
-
-void Display::println(void)
-{
-  print('\r');
-  print('\n');
-}
-
-void Display::println(const char c[])
-{
-  print(c);
-  println();
-}
-
-void Display::println(char c, int base)
-{
-  print(c, base);
-  println();
-}
-
-void Display::println(unsigned char b, int base)
-{
-  print(b, base);
-  println();
-}
-
-void Display::println(int n, int base)
-{
-  print(n, base);
-  println();
-}
-
-void Display::println(unsigned int n, int base)
-{
-  print(n, base);
-  println();
-}
-
-void Display::println(long n, int base)
-{
-  print(n, base);
-  println();
-}
-
-void Display::println(unsigned long n, int base)
-{
-  print(n, base);
-  println();
-}
-
-void Display::println(double n, int digits)
-{
-  print(n, digits);
-  println();
-}
-
-void Display::set_cursor(uint8_t x, uint8_t y) {
-	cursorX = x;
-	cursorY = y;
-}
-
-void Display::print(uint8_t x, uint8_t y, const char str[]) {
-	cursorX = x;
-	cursorY = y;
-	write(str);
-
-}
-void Display::print(uint8_t x, uint8_t y, char c, int base) {
-	cursorX = x;
-	cursorY = y;
-	print((long) c, base);
-}
-void Display::print(uint8_t x, uint8_t y, unsigned char b, int base) {
-	cursorX = x;
-	cursorY = y;
-	print((unsigned long) b, base);
-}
-void Display::print(uint8_t x, uint8_t y, int n, int base) {
-	cursorX = x;
-	cursorY = y;
-	print((long) n, base);
-}
-void Display::print(uint8_t x, uint8_t y, unsigned int n, int base) {
-	cursorX = x;
-	cursorY = y;
-	print((unsigned long) n, base);
-}
-void Display::print(uint8_t x, uint8_t y, long n, int base) {
-	cursorX = x;
-	cursorY = y;
-	print(n,base);
-}
-void Display::print(uint8_t x, uint8_t y, unsigned long n, int base) {
-	cursorX = x;
-	cursorY = y;
-	print(n,base);
-}
-void Display::print(uint8_t x, uint8_t y, double n, int digits) {
-	cursorX = x;
-	cursorY = y;
-	print(n,digits);
-}
-
-void Display::println(uint8_t x, uint8_t y, const char c[])
-{
-	cursorX = x;
-	cursorY = y;
-	print(c);
-	println();
-}
-
-void Display::println(uint8_t x, uint8_t y, char c, int base)
-{
-	cursorX = x;
-	cursorY = y;
-	print(c, base);
-	println();
-}
-
-void Display::println(uint8_t x, uint8_t y, unsigned char b, int base)
-{
-	cursorX = x;
-	cursorY = y;
-	print(b, base);
-	println();
-}
-
-void Display::println(uint8_t x, uint8_t y, int n, int base)
-{
-	cursorX = x;
-	cursorY = y;
-	print(n, base);
-	println();
-}
-
-void Display::println(uint8_t x, uint8_t y, unsigned int n, int base)
-{
-	cursorX = x;
-	cursorY = y;
-	print(n, base);
-	println();
-}
-
-void Display::println(uint8_t x, uint8_t y, long n, int base)
-{
-	cursorX = x;
-	cursorY = y;
-	print(n, base);
-	println();
-}
-
-void Display::println(uint8_t x, uint8_t y, unsigned long n, int base)
-{
-	cursorX = x;
-	cursorY = y;
-	print(n, base);
-	println();
-}
-
-void Display::println(uint8_t x, uint8_t y, double n, int digits)
-{
-	cursorX = x;
-	cursorY = y;
-	print(n, digits);
-	println();
-}
-
-void Display::printNumber(unsigned long n, uint8_t base)
-{
-  unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
-  unsigned long i = 0;
-
-  if (n == 0) {
-    print('0');
-    return;
-  }
-
-  while (n > 0) {
-    buf[i++] = n % base;
-    n /= base;
-  }
-
-  for (; i > 0; i--)
-    print((char) (buf[i - 1] < 10 ?
-      '0' + buf[i - 1] :
-      'A' + buf[i - 1] - 10));
-}
-
-void Display::printFloat(double number, uint8_t digits)
-{
-  // Handle negative numbers
-  if (number < 0.0)
-  {
-     print('-');
-     number = -number;
-  }
-
-  // Round correctly so that print(1.999, 2) prints as "2.00"
-  double rounding = 0.5;
-  for (uint8_t i=0; i<digits; ++i)
-    rounding /= 10.0;
-
-  number += rounding;
-
-  // Extract the integer part of the number and print it
-  unsigned long int_part = (unsigned long)number;
-  double remainder = number - (double)int_part;
-  print(int_part);
-
-  // Print the decimal point, but only if there are digits beyond
-  if (digits > 0)
-    print(".");
-
-  // Extract digits from the remainder one at a time
-  while (digits-- > 0)
-  {
-    remainder *= 10.0;
-    int toPrint = int(remainder);
-    print(toPrint);
-    remainder -= toPrint;
-  }
-}
-
-void Display::draw4BitColumn(int16_t x, int16_t y, uint8_t h, uint8_t* bitmap)
-{
-    int8_t scry;
-    uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
-
-    /** ONLY 4-bit mode for time being **/
-
-            if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
-                for (scry = y; scry < h+y; scry++) {
-                    uint8_t sourcepixel = *bitmap;
-                    uint8_t targetpixel = *scrptr;
-                    targetpixel = (targetpixel&0x0F) | (sourcepixel << 4);
-                    *scrptr = targetpixel;
-                    bitmap++;
-                    scrptr+=55;
-                }
-            } else { /** ODD pixel starting line **/
-                for (scry = y; scry < h+y; scry++) {
-                    uint8_t sourcepixel = *bitmap;
-                    uint8_t targetpixel = *scrptr;
-                    // store source pixel in lower nibble of target
-                    targetpixel = (targetpixel & 0xF0) | (sourcepixel);
-                    *scrptr = targetpixel;
-                    scrptr+=55;
-                    bitmap++;
-                }
-            }
-}
-
-void Display::lcdRefresh(unsigned char* scr) {
-
-#if POK_SCREENMODE == MODE_GAMEBOY
-    lcdRefreshModeGBC(scr, paletteptr);
-#endif
-
-#if POK_SCREENMODE == MODE_HI_4COLOR
-    lcdRefreshMode1(scr, paletteptr);
-#endif
-
-#if POK_SCREENMODE == MODE_FAST_16COLOR
-    lcdRefreshMode2(scr, paletteptr);
-#endif
-
-#if POK_SCREENMODE == MODE_GAMEBUINO_16COLOR
-    lcdRefreshGB(scr, paletteptr);
-#endif
-
-#if POK_SCREENMODE == MODE_ARDUBOY_16COLOR
-    lcdRefreshAB(scr, paletteptr);
-#endif
-
-}
-
-void Display::setFrameBufferTo(uint8_t* sb) {
-    m_scrbuf = sb;
-};
-
-void Display::setTileBufferTo(uint8_t* tb) {
-    m_tilebuf = tb;
-};
-
-void Display::loadTileset(const uint8_t* ts) {
-    m_tileset = (uint8_t*) ts;
-};
-
-void Display::setTile(uint16_t i, uint8_t t) {
-    if (!m_tilebuf) return;
-    m_tilebuf[i]=t;
-};
-
-
-/** Eof */
-
-
-
-
--- a/POKITTO_CORE/PokittoDisplay.h	Fri Dec 29 02:55:34 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,410 +0,0 @@
-/**************************************************************************/
-/*!
-    @file     PokittoDisplay.h
-    @author   Jonne Valola
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2016, Jonne Valola
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-
-
-/* THE SEGMENT BELOW PERTAINS TO CIRCLE DRAWING FUNCTIONS ONLY
-*
-This is the core graphics library for all our displays, providing a common
-set of graphics primitives (points, lines, circles, etc.).  It needs to be
-paired with a hardware-specific library for each display device we carry
-(to handle the lower-level functions).
-Adafruit invests time and resources providing this open source code, please
-support Adafruit & open-source hardware by purchasing products from Adafruit!
-Copyright (c) 2013 Adafruit Industries.  All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-- Redistributions of source code must retain the above copyright notice,
-  this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef POKITTODISPLAY_H
-#define POKITTODISPLAY_H
-
-#include <stdint.h>
-#include "Pokitto_settings.h"
-#include "PokittoGlobs.h"
-#include "PokittoFonts.h"
-#include "PokittoPalettes.h"
-
-// Basic Color definitions
-#define	COLOR_BLACK                         (uint16_t)(0x0000)
-#define	COLOR_BLUE                          (uint16_t)(0x001F)
-#define	COLOR_RED                           (uint16_t)(0xF800)
-#define	COLOR_GREEN                         (uint16_t)(0x07E0)
-#define COLOR_CYAN                          (uint16_t)(0x07FF)
-#define COLOR_MAGENTA                       (uint16_t)(0xF81F)
-#define COLOR_YELLOW                        (uint16_t)(0xFFE0)
-#define COLOR_WHITE                         (uint16_t)(0xFFFF)
-
-// Grayscale Values
-#define COLOR_GRAY_15                       (uint16_t)(0x0861)    //  15  15  15
-#define COLOR_GRAY_30                       (uint16_t)(0x18E3)    //  30  30  30
-#define COLOR_GRAY_50                       (uint16_t)(0x3186)    //  50  50  50
-#define COLOR_GRAY_80                       (uint16_t)(0x528A)    //  80  80  80
-#define COLOR_GRAY_128                      (uint16_t)(0x8410)    // 128 128 128
-#define COLOR_GRAY_200                      (uint16_t)(0xCE59)    // 200 200 200
-#define COLOR_GRAY_225                      (uint16_t)(0xE71C)    // 225 225 225
-
-/** The tables below are palettes, that resemble the Pico 8 palette*/
-
-enum defcolors {
-    C_BLACK,
-    C_DARKBLUE,
-    C_PURPLE,
-    C_DARKGREEN,
-
-    C_BROWN,
-    C_DARKBROWN,
-    C_LIGHTGRAY,
-    C_WHITE,
-
-    C_RED,
-    C_ORANGE,
-    C_YELLOW,
-    C_GREEN,
-
-    C_BLUE,
-    C_DARKGRAY,
-    C_PINK,
-    C_PEACH
-};
-
-const uint16_t def565palette[16] = {
-    //kind of like pico8 palette
-    0,0x194a,0x792a,0x42a,
-    0xaa86,0x5aa9,0xc618,0xff9d,
-    0xf809,0xfd00,0xff84,0x72a,
-    0x2d7f,0x83b3,0xfbb5,0xfe75
-};
-
-#define PALETTE_SIZE 16
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-namespace Pokitto {
-
-class Display {
-public:
-    Display();
-
-    // PROPERTIES
-private:
-    static uint8_t* canvas;
-    static uint8_t bpp;
-    static uint8_t m_colordepth;
-public:
-    static uint8_t width;
-    static uint8_t height;
-    static uint8_t screenbuffer[];
-
-    // PROPERTIES
-    static void setColorDepth(uint8_t);
-    static uint8_t getColorDepth();
-    static uint8_t getBitsPerPixel();
-    static uint16_t getWidth();
-    static uint16_t getHeight();
-    static uint8_t getNumberOfColors();
-
-    // IMPORTANT PUBLIC STATE MEMBERS
-    /** Selected font */
-    static const unsigned char * font;
-    /** Set if screen is cleared between updates or not*/
-    static uint8_t persistence;
-    /** Selected drawing color */
-    static uint16_t color;
-    /** Selected background color */
-    static uint16_t bgcolor;
-    /** Selected invisible color */
-    static uint16_t invisiblecolor;
-    /** Direct unbuffered color */
-    static uint16_t directcolor;
-    /** Direct unbuffered background color */
-    static uint16_t directbgcolor;
-    /** set color with a command */
-    static void setColor(uint8_t);
-    /** set color and bgcolor with a command */
-    static void setColor(uint8_t,uint8_t);
-    /** set invisiblecolor with a command */
-    static void setInvisibleColor(uint16_t);
-    /** get color */
-    static uint8_t getColor();
-    /** get background color */
-    static uint8_t getBgColor();
-    /** get invisible color */
-    static uint16_t getInvisibleColor();
-
-
-    /** Initialize display */
-    static void begin();
-    /** Clear display buffer */
-    static void clear();
-    /** Scroll by x lines */
-    static void scroll(int16_t);
-    /** Fill display buffer */
-    static void fillScreen(uint16_t);
-    /** Send display buffer to display hardware */
-    static void update();
-    /** Forced update of LCD display memory with a given pixel buffer */
-    static void lcdRefresh(unsigned char*);
-    /** Clear LCD hardware memory */
-    static void clearLCD();
-    /** Fill LCD hardware memory */
-    static void fillLCD(uint16_t);
-    /** Show Pokitto logo at startup*/
-    static void showLogo();
-    /** Point to another screenbuffer instead of the default one */
-    static void setFrameBufferTo(uint8_t*);
-
-    // COLORS AND PALETTE
-public:
-    /** set default palette */
-    static void setDefaultPalette();
-    /** master palette */
-    static uint16_t palette[PALETTE_SIZE];
-    /** runtime palette pointer */
-    static uint16_t *paletteptr;
-    /** convert RGB to 565 color value */
-    static uint16_t RGBto565(uint8_t,uint8_t,uint8_t);
-    /** linear interpolation between colors */
-    static uint16_t interpolateColor(uint16_t, uint16_t, uint8_t);
-    /** load an R,G,B triplet palette */
-    static void loadRGBPalette(const unsigned char*);
-    /** load a ready-made 565 palette */
-    static void load565Palette(const uint16_t*);
-    /** rotate palette by step */
-    static void rotatePalette(int8_t);
-    /** tween between two palettes **/
-    static void tweenPalette(uint16_t*, const uint16_t*, const uint16_t*, uint8_t);
-
-    // DIRECT DRAWING (NO BUFFERING)
-    /** Direct pixel (not through display buffer) */
-    static void directPixel(int16_t,int16_t,uint16_t);
-    /** Direct tile 16bit (not through display buffer) */
-	static void directTile(int16_t x, int16_t y, int16_t x2, int16_t y2, uint16_t* gfx);
-    /** Direct rectangle (not through display buffer) */
-    static void directRectangle(int16_t, int16_t,int16_t, int16_t, uint16_t);
-    /** Set the cursor for printing to a certain screen position */
-    static void setCursor(int16_t,int16_t);
-    /** direct bitmap to screen (no buffering) */
-    static void directBitmap(int16_t,int16_t,const uint8_t*, uint8_t,uint8_t);
-
-
-    // DRAWING METHODS
-    /** Draw pixel at various bit depths */
-    static void drawPixel(int16_t,int16_t);
-    /** Draw pixel with specific color index at various bit depths */
-    static void drawPixel(int16_t x,int16_t y, uint8_t col);
-    /** Get pixel at various bit depths */
-    static uint8_t getPixel(int16_t,int16_t);
-    /** Draw line **/
-    static void drawLine(int16_t,int16_t,int16_t,int16_t);
-    /** Clip line with screen boundaries, returns 0 if whole line is out of bounds */
-    static uint8_t clipLine(int16_t*, int16_t*, int16_t*, int16_t*);
-    /** Draw a column real fast */
-    static void drawColumn(int16_t, int16_t, int16_t);
-    /** Map a 1-bit column real fast */
-    static void map1BitColumn(int16_t, int16_t, int16_t, const uint8_t*, uint16_t);
-    /** Draw a row real fast */
-    static void drawRow(int16_t, int16_t, int16_t);
-    /** Legacy drawColumn name, for compatibility - macros are not OK because of scope problems */
-    static void drawFastVLine(int16_t, int16_t, int16_t);
-    /** Legacy drawRow name, for compatibility - macros are not OK because of scope problems */
-    static void drawFastHLine(int16_t, int16_t, int16_t);
-    /** Draw rectangle (edges only) */
-    static void drawRectangle(int16_t,int16_t,int16_t,int16_t);
-    /** Fill rectangle */
-    static void fillRectangle(int16_t,int16_t,int16_t,int16_t);
-    /** GB compatibility fillRect */
-    static void fillRect(int16_t x, int16_t y, int16_t w, int16_t h);
-    /** GB compatibility drawRect */
-    static void drawRect(int16_t x, int16_t y, int16_t w, int16_t h);
-
-    // Functions lifted from Adafruit GFX library (see PokittoDisplay.h for license //
-    /** Draw circle */
-    static void drawCircle(int16_t x0, int16_t y0, int16_t r);
-    /** Draw circle helper */
-	static void drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint16_t cornername);
-	/** Fill circle */
-	static void fillCircle(int16_t x0, int16_t y0, int16_t r);
-	/** Fill circle helper*/
-	static void fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint16_t cornername, int16_t delta);
-	/** draw triangle */
-	static void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
-	/** Fill triangle*/
-	static void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
-	/** Draw rounded rectangle */
-	static void drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius);
-	/** Fill rounded rectangle */
-	static void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius);
-
-    // BITMAPS !
-    /** Draw monochromatic bitmap. Used in font rendering */
-    static void drawMonoBitmap(int16_t x, int16_t y, const uint8_t* bitmap, uint8_t index);
-    /** Draw bitmap */
-    static void drawBitmap(int16_t x, int16_t y, const uint8_t* bitmap);
-    /** Draw RLE bitmap */
-    static void drawRleBitmap(int16_t x, int16_t y, const uint8_t* bitmap);
-    /** Draw animated bitmap frame */
-    static void drawBitmap(int16_t x, int16_t y, const uint8_t* bitmap, uint8_t frame);
-    /** Draw bitmap flipped on x-axis*/
-    static void drawBitmapXFlipped(int16_t x, int16_t y, const uint8_t* bitmap);
-    /** Draw bitmap with options */
-    static void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t rotation, uint8_t flip);
-    /** Get pointer to the screen buffer - GB compatibility */
-    static uint8_t* getBuffer();
-    /** Get pixel in a monochromatic bitmap - GB compatibility */
-    static uint8_t getBitmapPixel(const uint8_t*, uint16_t, uint16_t);
-    /** Optimized functions for drawing bit columns - used in raytracing */
-    static void draw4BitColumn(int16_t x, int16_t y, uint8_t h, uint8_t* bitmap);
-
-    // PRINTING
-    /** direct character to screen (no buffering) */
-    static int directChar(int16_t, int16_t, uint16_t);
-    /** character to screenbuffer */
-    static int bufferChar(int16_t, int16_t, uint16_t);
-    /** set the active font */
-    static void setFont(const unsigned char * f);
-    /** font dimensions */
-    static uint8_t fontWidth, fontHeight;
-    /** text wrapping */
-    static bool textWrap;
-    /** GB compatibility drawChar */
-    static void drawChar(int8_t x, int8_t y, unsigned char c, uint8_t size);
-
-    static void enableDirectPrinting(uint8_t m);
-    static bool isDirectPrintingEnabled();
-    static int print_char(uint8_t x, uint8_t y, unsigned char c);
-    static void set_cursor(uint8_t, uint8_t);
-    static void write(uint8_t);
-    static void write(const char *str);
-    static void write(const uint8_t *buffer, uint8_t size);
-    static void print(const char[]);
-    static void print(char, int base = 0);
-    static void print(unsigned char, int base = 0);
-    static void print(int, int base = 10);
-    static void print(unsigned int, int base = 10);
-    static void print(long, int base = 10);
-    static void print(unsigned long, int base = 10);
-    static void print(double, int base = 2);
-    static void print(uint8_t, uint8_t, const char[]);
-    static void print(uint8_t, uint8_t, char, int = 0);
-    static void print(uint8_t, uint8_t, unsigned char, int = 0);
-    static void print(uint8_t, uint8_t, int, int = 10);
-    static void print(uint8_t, uint8_t, unsigned int, int = 10);
-    static void print(uint8_t, uint8_t, long, int = 10);
-    static void print(uint8_t, uint8_t, unsigned long, int = 10);
-    static void print(uint8_t, uint8_t, double, int = 2);
-    static void println(uint8_t, uint8_t, const char[]);
-    static void println(uint8_t, uint8_t, char, int = 0);
-    static void println(uint8_t, uint8_t, unsigned char, int = 0);
-    static void println(uint8_t, uint8_t, int, int = 10);
-    static void println(uint8_t, uint8_t, unsigned int, int = 10);
-    static void println(uint8_t, uint8_t, long, int = 10);
-    static void println(uint8_t, uint8_t, unsigned long, int = 10);
-    static void println(uint8_t, uint8_t, double, int = 2);
-    static void println(uint8_t, uint8_t);
-    static void println(const char[]);
-    static void println(char, int = 0);
-    static void println(unsigned char, int = 0);
-    static void println(int, int = 10);
-    static void println(unsigned int, int = 10);
-    static void println(long, int = 10 );
-    static void println(unsigned long, int = 10);
-    static void println(double, int = 2);
-    static void println(void);
-
-    static int16_t cursorX,cursorY;
-    static uint8_t fontSize;
-    static int8_t adjustCharStep, adjustLineStep;
-	static bool fixedWidthFont;
-
-    static void inc_txtline();
-    static void printNumber(unsigned long, uint8_t);
-    static void printFloat(double, uint8_t);
-
-    /** Tiled mode functions **/
-
-    static void loadTileset(const uint8_t*);
-
-    static void setTileBufferTo(uint8_t*);
-    static void clearTileBuffer();
-    static void shiftTileBuffer(int8_t,int8_t);
-
-    static void setTile(uint16_t,uint8_t);
-    static uint8_t getTile(uint16_t);
-    static uint8_t getTile(uint8_t,uint8_t);
-
-
-
-private:
-    static uint8_t m_mode;
-    static uint16_t m_w,m_h; // store these for faster access when switching printing modes
-    /** Pointer to screen buffer */
-    static uint8_t* m_scrbuf;
-    /** Pointer to tileset */
-    static uint8_t* m_tileset;
-    /** Pointer to tilebuffer */
-    static uint8_t* m_tilebuf;
-    /** Pointer to tilecolorbuffer */
-    static uint8_t* m_tilecolorbuf;
-
-};
-
-}
-
-#endif // POKITTODISPLAY_H
-
-
-
-
-
--- a/POKITTO_CORE/PokittoSound.cpp	Fri Dec 29 02:55:34 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,914 +0,0 @@
-/**************************************************************************/
-/*!
-    @file     PokittoSound.cpp
-    @author   Jonne Valola
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2016, Jonne Valola
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-/*
- * NOTE:
- * API of the Pokitto Sound library is partially identical to the Gamebuino Sound API.
- * Due to the difference in architecture (ARM Cortex-M0+ in mbed environment vs. 8-bit AVR)
- * large parts are not identical. Most functions were rewritten, with only API remaining.
- * We want to give attribution to the original author's project:
- *
- * License for Gamebuino-identical code:
- *
- * (C) Copyright 2014 Aur�lien Rodot. All rights reserved.
- *
- * This file is part of the Gamebuino Library (http://gamebuino.com)
- *
- * The Gamebuino Library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>
- */
-
-#include "PokittoSound.h"
-#include "Pokitto_settings.h"
-#include "PokittoCore.h"
-#include "Synth.h"
-
-#ifndef POK_SIM
-#include "HWSound.h"
-#else
-#include "SimSound.h"
-#include "PokittoSimulator.h"
-#endif
-
-typedef uint8_t byte;
-
-using namespace Pokitto;
-
-Pokitto::Core c;
-
-uint8_t Sound::prescaler;
-uint16_t Sound::globalVolume;
-uint16_t Sound::volumeMax = VOLUME_HEADPHONE_MAX;
-
-bool Sound::trackIsPlaying[NUM_CHANNELS];
-bool Sound::patternIsPlaying[NUM_CHANNELS];
-uint8_t Sound::outputPitch[NUM_CHANNELS];
-int8_t Sound::outputVolume[NUM_CHANNELS];
-
-uint16_t *Sound::trackData[NUM_CHANNELS];
-uint8_t Sound::trackCursor[NUM_CHANNELS];
-uint16_t **Sound::patternSet[NUM_CHANNELS];
-int8_t Sound::patternPitch[NUM_CHANNELS];
-
-// pattern data
-uint16_t *Sound::patternData[NUM_CHANNELS];
-uint16_t **Sound::instrumentSet[NUM_CHANNELS];
-bool Sound::patternLooping[NUM_CHANNELS];
-uint16_t Sound::patternCursor[NUM_CHANNELS];
-
-// note data
-uint8_t Sound::notePitch[NUM_CHANNELS];
-uint8_t Sound::noteDuration[NUM_CHANNELS];
-int8_t Sound::noteVolume[NUM_CHANNELS];
-bool Sound::notePlaying[NUM_CHANNELS];
-
-// commands data
-int8_t Sound::commandsCounter[NUM_CHANNELS];
-int8_t Sound::volumeSlideStepDuration[NUM_CHANNELS];
-int8_t Sound::volumeSlideStepSize[NUM_CHANNELS];
-uint8_t Sound::arpeggioStepDuration[NUM_CHANNELS];
-int8_t Sound::arpeggioStepSize[NUM_CHANNELS];
-uint8_t Sound::tremoloStepDuration[NUM_CHANNELS];
-int8_t Sound::tremoloStepSize[NUM_CHANNELS];
-
-// instrument data
-uint16_t *Sound::instrumentData[NUM_CHANNELS];
-uint8_t Sound::instrumentLength[NUM_CHANNELS]; //number of steps in the instrument
-uint8_t Sound::instrumentLooping[NUM_CHANNELS]; //how many steps to loop on when the last step of the instrument is reached
-uint16_t Sound::instrumentCursor[NUM_CHANNELS]; //which step is being played
-uint8_t Sound::instrumentNextChange[NUM_CHANNELS]; //how many frames before the next step
-
-//current step data
-int8_t Sound::stepVolume[NUM_CHANNELS];
-uint8_t Sound::stepPitch[NUM_CHANNELS];
-uint8_t Sound::chanVolumes[NUM_CHANNELS];
-
-#if (POK_ENABLE_SOUND < 1)
- #define NUM_CHANNELS 0
-#endif
-
-#if(NUM_CHANNELS > 0)
-    #ifndef POK_SIM
-        uint8_t sbyte;
-    #else
-    uint8_t sbyte;
-    float pwm1;
-    #endif // POK_SIM
-
-//declare these variables globally for faster access
-uint8_t _rand = 1;
-uint8_t _chanCount[NUM_CHANNELS]; //counts until the next change of the waveform
-bool _chanState[NUM_CHANNELS]; //if the waveform is currently high or low
-uint8_t _chanHalfPeriod[NUM_CHANNELS]; //duration of half the period of the waveform
-uint8_t _chanOutputVolume[NUM_CHANNELS]; //amplitude of the outputted waveform
-uint8_t _chanOutput[NUM_CHANNELS]; //current value of the outputted waveform
-bool _chanNoise[NUM_CHANNELS]; //if a random value should be added to the waveform to generate noise
-
-#if POK_GBSOUND > 0
-const uint16_t squareWaveInstrument[]  = {0x0101, 0x03F7};
-const uint16_t noiseInstrument[]  = {0x0101, 0x03FF};
-const uint16_t* const defaultInstruments[]  = {squareWaveInstrument,noiseInstrument};
-
-const uint16_t playOKPattern[]  = {0x0005,0x138,0x168,0x0000};
-const uint16_t playCancelPattern[]  = {0x0005,0x168,0x138,0x0000};
-const uint16_t playTickP[]  = {0x0045,0x168,0x0000};
-#endif
-#if(EXTENDED_NOTE_RANGE > 0)
-//extended note range
-#define NUM_PITCH 59
-const uint8_t _halfPeriods[NUM_PITCH] = {246,232,219,207,195,184,174,164,155,146,138,130,123,116,110,104,98,92,87,82,78,73,69,65,62,58,55,52,49,46,44,41,39,37,35,33,31,29,28,26,25,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6};
-#else
-//regular note range
-#define NUM_PITCH 36
-const uint8_t _halfPeriods[NUM_PITCH] = {246,232,219,207,195,184,174,164,155,146,138,130,123,116,110,104,98,92,87,82,78,73,69,65,62,58,55,52,49,46,44,41,39,37,35,33};
-#endif
-
-#endif
-
-void Pokitto::audio_IRQ() {
-    #if POK_STREAMING_MUSIC > 0
-        #if POK_STREAMFREQ_HALVE > 0
-        streamstep = 1-streamstep;
-        #else
-        streamstep=1;
-        #endif
-
-        streamstep &= streamon; //check if stream is on
-		
-        if(streamvol && streamstep) {
-            uint8_t output = (*currentPtr++);
-            sbyte = output;
-        } else {
-            sbyte = 0; // duty cycle
-        }
-
-        if (currentPtr >= endPtr)
-        {
-        currentBuffer++;
-        if (currentBuffer==4) currentBuffer=0;
-        currentPtr = buffers[currentBuffer];
-        endPtr = currentPtr + BUFFER_SIZE;
-        }
-
-    #endif // POK_STREAMING_MUSIC
-    #if (NUM_CHANNELS > 0)
-	Sound::generateOutput();
-    #endif
-}
-
-void Sound::volumeUp() {
-    if (globalVolume>VOLUME_HEADPHONE_MAX) setVolume(getVolume()+VOLUME_STEP*2);
-    else setVolume(getVolume()+VOLUME_STEP);
-}
-
-void Sound::volumeDown() {
-    if (globalVolume>VOLUME_HEADPHONE_MAX) setVolume(getVolume()-VOLUME_STEP*4);
-    else setVolume(getVolume()-VOLUME_STEP);
-}
-
-
-void Sound::setMaxVol(int16_t v) {
-    if (v < 0) v = 0; //prevent nasty wraparound
-    if (v > VOLUME_SPEAKER_MAX) {
-            v = VOLUME_SPEAKER_MAX;
-    }
-    volumeMax = v;
-    setVolume(globalVolume);
-}
-
-uint16_t Sound::getMaxVol() {
-    return volumeMax;
-}
-
-void Sound::updateStream() {
-    #if POK_STREAMING_MUSIC
-    if (oldBuffer != currentBuffer) {
-        if (currentBuffer==0) fileReadBytes(&buffers[3][0],BUFFER_SIZE);
-        else if (currentBuffer==1) fileReadBytes(&buffers[0][0],BUFFER_SIZE);
-        else if (currentBuffer==2) fileReadBytes(&buffers[1][0],BUFFER_SIZE);
-        else fileReadBytes(&buffers[2][0],BUFFER_SIZE);
-        oldBuffer = currentBuffer;
-        streamcounter += BUFFER_SIZE;
-    }
-
-    #ifndef POK_SIM
-    if ( streamcounter > fs.fsize - (BUFFER_SIZE)) {
-    #else
-    if ( streamcounter > getFileLength() - (BUFFER_SIZE)) {
-    #endif
-        streamcounter=0;
-        #if POK_STREAM_LOOP > 0
-        fileRewind();
-        #endif
-        #ifndef POK_SIM
-        streamon=0;
-        #endif // POK_SIM
-    }
-    #endif
-}
-
-void Sound::begin() {
-#if POK_ENABLE_SOUND > 0
-soundInit();
-ampEnable(true);
-#endif
-#if (NUM_CHANNELS > 0)
-#if POK_ENABLE_SOUND > 0
-#if POK_GBSOUND > 0
-	prescaler = 1;
-	for(byte i=0; i<NUM_CHANNELS; i++){
-		chanVolumes[i] = VOLUME_CHANNEL_MAX;
-		changeInstrumentSet(defaultInstruments, i); //load default instruments. #0:square wave, #1: noise
-		command(CMD_INSTRUMENT, 0, 0, i); //set the default instrument to square wave
-	}
-#endif // POK_GBSOUND
-#endif //POK_ENABLE_SOUND
-#endif
-}
-
-void Sound::playTrack(const uint16_t* track, uint8_t channel){
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	stopTrack(channel);
-	trackCursor[channel] = 0;
-	trackData[channel] = (uint16_t*)track;
-	trackIsPlaying[channel] = true;
-#endif
-}
-
-void Sound::stopTrack(uint8_t channel){
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	trackIsPlaying[channel] = false;
-	stopPattern(channel);
-#endif
-}
-
-void Sound::stopTrack(){
-#if(NUM_CHANNELS > 0)
-	for(uint8_t i=0; i<NUM_CHANNELS; i++){
-		stopTrack(i);
-	}
-#endif
-}
-
-void Sound::updateTrack(uint8_t channel){
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	if(trackIsPlaying[channel] && !patternIsPlaying[channel]){
-		uint16_t data = pgm_read_word(trackData[channel] + trackCursor[channel]);
-		if(data == 0xFFFF){ //en of the track
-			trackIsPlaying[channel] = false;
-			return;
-		}
-		uint8_t patternID = data & 0xFF;
-		data >>= 8;
-		patternPitch[channel] = data;
-		playPattern((const uint16_t*)pgm_read_word(&(patternSet[channel][patternID])), channel);
-		trackCursor[channel] ++;
-	}
-#endif
-}
-
-void Sound::updateTrack(){
-#if(NUM_CHANNELS > 0)
-	for (uint8_t i=0; i<NUM_CHANNELS; i++){
-		updateTrack(i);
-	}
-#endif
-}
-
-void Sound::changePatternSet(const uint16_t* const* patterns, uint8_t channel){
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	patternSet[channel] = (uint16_t**)patterns;
-#endif
-}
-
-void Sound::playPattern(const uint16_t* pattern, uint8_t channel){
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	stopPattern(channel);
-	patternData[channel] = (uint16_t*)pattern;
-	patternCursor[channel] = 0;
-	patternIsPlaying[channel] = true;
-	noteVolume[channel] = 9;
-	//reinit commands
-	volumeSlideStepDuration[channel] = 0;
-	arpeggioStepDuration[channel] = 0;
-	tremoloStepDuration[channel] = 0;
-#endif
-}
-
-void Sound::updatePattern(){
-#if(NUM_CHANNELS > 0)
-	for (uint8_t i=0; i<NUM_CHANNELS; i++){
-		updatePattern(i);
-	}
-#endif
-}
-
-void Sound::changeInstrumentSet(const uint16_t* const* instruments, uint8_t channel){
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	instrumentSet[channel] = (uint16_t**)instruments;
-#endif
-}
-
-void Sound::updatePattern(uint8_t i){
-#if(NUM_CHANNELS > 0)
-	if(i>=NUM_CHANNELS)
-		return;
-	if(patternIsPlaying[i]){
-		if(noteDuration[i]==0){//if the end of the previous note is reached
-
-			uint16_t data = pgm_read_word(patternCursor[i] + patternData[i]);
-
-			if(data == 0){ //end of the pattern reached
-				if(patternLooping[i] == true){
-					patternCursor[i] = 0;
-					data = pgm_read_word(patternCursor[i] + patternData[i]);
-				}
-				else{
-					patternIsPlaying[i] = false;
-					if(trackIsPlaying[i]){ //if this pattern is part of a track, get the next pattern
-						updateTrack(i);
-						data = pgm_read_word(patternCursor[i] + patternData[i]);
-					} else {
-						stopNote(i);
-						//Serial.print("pattern end\n");
-						return;
-					}
-				}
-			}
-
-			while (data & 0x0001){ //read all commands and instrument changes
-				data >>= 2;
-				//Serial.print("\ncmd\t");
-				uint8_t cmd = data & 0x0F;
-				data >>= 4;
-				uint8_t X = data & 0x1F;
-				data >>= 5;
-				int8_t Y = data - 16;
-				command(cmd,X,Y,i);
-				patternCursor[i]++;
-				data = pgm_read_word(patternCursor[i] + patternData[i]);
-			}
-			data >>= 2;
-
-			uint8_t pitch = data & 0x003F;
-			data >>= 6;
-
-			uint8_t duration = data;
-			if(pitch != 63){
-			}
-
-			playNote(pitch, duration, i);
-
-			patternCursor[i]++;
-		}
-	}
-#endif
-}
-
-void Sound::stopPattern(uint8_t channel){
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	stopNote(channel);
-	patternIsPlaying[channel] = false;
-#endif
-}
-
-void Sound::stopPattern(){
-#if(NUM_CHANNELS > 0)
-	for(uint8_t i=0; i<NUM_CHANNELS; i++){
-		stopPattern(i);
-	}
-#endif
-}
-
-void Sound::command(uint8_t cmd, uint8_t X, int8_t Y, uint8_t i){
-#if(NUM_CHANNELS > 0)
-	if(i>=NUM_CHANNELS)
-		return;
-	switch(cmd){
-	case CMD_VOLUME: //volume
-	    X = constrain((int8_t)X, 0, 10);
-		noteVolume[i] = X;
-		break;
-	case CMD_INSTRUMENT: //instrument
-		instrumentData[i] = (uint16_t*)pgm_read_word(&(instrumentSet[i][X]));
-		instrumentLength[i] = pgm_read_word(&(instrumentData[i][0])) & 0x00FF; //8 LSB
-		instrumentLength[i] *= prescaler;
-		instrumentLooping[i] = min2((pgm_read_word(&(instrumentData[i][0])) >> 8), instrumentLength[i]); //8 MSB - check that the loop is shorter than the instrument length
-		instrumentLooping[i] *= prescaler;
-		break;
-	case CMD_SLIDE: //volume slide
-		volumeSlideStepDuration[i] = X * prescaler;
-		volumeSlideStepSize[i] = Y;
-		break;
-	case CMD_ARPEGGIO:
-		arpeggioStepDuration[i] = X * prescaler;
-		arpeggioStepSize[i] = Y;
-		break;
-	case CMD_TREMOLO:
-		tremoloStepDuration[i] = X * prescaler;
-		tremoloStepSize[i] = Y;
-		break;
-	default:
-		break;
-	}
-#endif
-}
-
-void Sound::playNote(uint8_t pitch, uint8_t duration, uint8_t channel){
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	//set note
-	notePitch[channel] = pitch;
-	noteDuration[channel] = duration * prescaler;
-	//reinit vars
-	instrumentNextChange[channel] = 0;
-	instrumentCursor[channel] = 0;
-	notePlaying[channel] = true;
-	_chanState[channel] = true;
-	commandsCounter[channel] = 0;
-#endif
-}
-
-void Sound::stopNote(uint8_t channel) {
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	notePlaying[channel] = false;
-	//counters
-	noteDuration[channel] = 0;
-	instrumentCursor[channel] = 0;
-	commandsCounter[channel] = 0;
-	//output
-	_chanOutput[channel] = 0;
-	_chanOutputVolume[channel] = 0;
-	_chanState[channel] = false;
-	updateOutput();
-#endif
-}
-
-void Sound::stopNote() {
-#if(NUM_CHANNELS > 0)
-	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) {
-		stopNote(channel);
-	}
-#endif
-}
-
-void Sound::updateNote() {
-#if(NUM_CHANNELS > 0)
-	for (uint8_t i = 0; i < NUM_CHANNELS; i++) {
-		updateNote(i);
-	}
-#endif
-}
-
-void Sound::updateNote(uint8_t i) {
-#if(NUM_CHANNELS > 0)
-	if(i>=NUM_CHANNELS)
-		return;
-	if (notePlaying[i]) {
-
-		if(noteDuration[i] == 0){
-			stopNote(i);
-			//Serial.println("note end");
-			return;
-		} else {
-			noteDuration[i]--;
-		}
-
-		if (instrumentNextChange[i] == 0) {
-
-			//read the step data from the progmem and decode it
-			uint16_t thisStep = pgm_read_word(&(instrumentData[i][1 + instrumentCursor[i]]));
-
-			stepVolume[i] = thisStep & 0x0007;
-			thisStep >>= 3;
-
-			uint8_t stepNoise = thisStep & 0x0001;
-			thisStep >>= 1;
-
-			uint8_t stepDuration = thisStep & 0x003F;
-			thisStep >>= 6;
-
-			stepPitch[i] = thisStep;
-
-			//apply the step settings
-			instrumentNextChange[i] = stepDuration * prescaler;
-
-			_chanNoise[i] = stepNoise;
-
-
-			instrumentCursor[i]++;
-
-			if (instrumentCursor[i] >= instrumentLength[i]) {
-				if (instrumentLooping[i]) {
-					instrumentCursor[i] = instrumentLength[i] - instrumentLooping[i];
-				} else {
-					stopNote(i);
-				}
-			}
-		}
-		instrumentNextChange[i]--;
-
-		commandsCounter[i]++;
-
-		//UPDATE VALUES
-		//pitch
-		outputPitch[i] = notePitch[i] + stepPitch[i] + patternPitch[i];
-		if(arpeggioStepDuration[i]){
-		  outputPitch[i] += commandsCounter[i] / arpeggioStepDuration[i] * arpeggioStepSize[i];
-		}
-		outputPitch[i] = (outputPitch[i] + NUM_PITCH) % NUM_PITCH; //wrap
-		//volume
-		outputVolume[i] = noteVolume[i];
-		if(volumeSlideStepDuration[i]){
-		  outputVolume[i] += commandsCounter[i] / volumeSlideStepDuration[i] * volumeSlideStepSize[i];
-		}
-		if(tremoloStepDuration[i]){
-			outputVolume[i] += ((commandsCounter[i]/tremoloStepDuration[i]) % 2) * tremoloStepSize[i];
-		}
-		outputVolume[i] = constrain(outputVolume[i], 0, 9);
-		if(notePitch[i] == 63){
-			outputVolume[i] = 0;
-		}
-		// jonnehw noInterrupts();
-		_chanHalfPeriod[i] = pgm_read_byte(_halfPeriods + outputPitch[i]);
-		_chanOutput[i] = _chanOutputVolume[i] = outputVolume[i] * (globalVolume>>GLOBVOL_SHIFT) * chanVolumes[i] * stepVolume[i];
-		//Serial.println(outputVolume[i]);
-		// jonnehw interrupts();
-	}
-#endif
-}
-
-void Sound::setChannelHalfPeriod(uint8_t channel, uint8_t halfPeriod) {
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	_chanHalfPeriod[channel] = halfPeriod;
-	_chanState[channel] = false;
-	_chanCount[channel] = 0;
-	updateOutput();
-#endif
-}
-
-
-void Sound::generateOutput() {
-#if(NUM_CHANNELS > 0)
-	bool outputChanged = false;
-	//no for loop here, for the performance sake (this function runs 15 000 times per second...)
-	//CHANNEL 0
-	if (_chanOutputVolume[0]) {
-		_chanCount[0]++;
-		if (_chanCount[0] >= _chanHalfPeriod[0]) {
-			outputChanged = true;
-			_chanState[0] = !_chanState[0];
-			_chanCount[0] = 0;
-			if (_chanNoise[0]) {
-				_rand = 67 * _rand + 71;
-				_chanOutput[0] = _rand % _chanOutputVolume[0];
-			}
-		}
-	}
-
-
-	//CHANNEL 1
-	#if (NUM_CHANNELS > 1)
-	if (_chanOutputVolume[1]) {
-		_chanCount[1]++;
-		if (_chanCount[1] >= _chanHalfPeriod[1]) {
-			outputChanged = true;
-			_chanState[1] = !_chanState[1];
-			_chanCount[1] = 0;
-			if (_chanNoise[1]) {
-				_rand = 67 * _rand + 71;
-				_chanOutput[1] = _rand % _chanOutputVolume[1];
-			}
-		}
-	}
-	#endif
-
-	//CHANNEL 2
-	#if (NUM_CHANNELS > 2)
-	if (_chanOutputVolume[2]) {
-		_chanCount[2]++;
-		if (_chanCount[2] >= _chanHalfPeriod[2]) {
-			outputChanged = true;
-			_chanState[2] = !_chanState[2];
-			_chanCount[2] = 0;
-			if (_chanNoise[2]) {
-				_rand = 67 * _rand + 71;
-				_chanOutput[2] = _rand % _chanOutputVolume[2];
-			}
-		}
-	}
-	#endif
-
-	//CHANNEL 3
-	#if (NUM_CHANNELS > 3)
-	if (_chanOutputVolume[3]) {
-		_chanCount[3]++;
-		if (_chanCount[3] >= _chanHalfPeriod[3]) {
-			outputChanged = true;
-			_chanState[3] = !_chanState[3];
-			_chanCount[3] = 0;
-			if (_chanNoise[3]) {
-				_rand = 67 * _rand + 71;
-				_chanOutput[3] = _rand % _chanOutputVolume[3];
-			}
-		}
-	}
-	#endif
-
-    #if POK_STREAMING_MUSIC
-        if (streamstep) {
-            outputChanged=true;
-        }
-    #endif
-
-	if (outputChanged) {
-		updateOutput();
-	}
-#endif
-}
-
-void Sound::updateOutput() {
-#if(NUM_CHANNELS > 0)
-	uint8_t output = 0;
-
-	//CHANNEL 0
-	if (_chanState[0]) {
-		output += _chanOutput[0];
-	}
-
-	//CHANNEL 1
-	#if (NUM_CHANNELS > 1)
-	if (_chanState[1]) {
-		output += _chanOutput[1];
-	}
-	#endif
-
-	//CHANNEL 2
-	#if (NUM_CHANNELS > 2)
-	if (_chanState[2]) {
-		output += _chanOutput[2];
-	}
-	#endif
-
-	//CHANNEL 3
-	#if (NUM_CHANNELS > 3)
-	if (_chanState[3]) {
-		output += _chanOutput[3];
-	}
-	#endif
-
-    #ifndef POK_SIM
-    #if POK_ENABLE_SOUND
-    /** HARDWARE **/
-
-        #if POK_STREAMING_MUSIC
-            if (streamstep) {
-                pwmout_write(&audiopwm,(float)sbyte/(float)255);
-            }
-        #endif
-            dac_write((uint8_t)output); //direct hardware mixing baby !
-    soundbyte = output;
-    #endif //POK_ENABLE_SOUND
-    #else
-    /** SIMULATOR **/
-        #if POK_STREAMING_MUSIC
-            if (streamstep) {
-                uint16_t o = output + sbyte;
-                output = o/2;
-            }
-        #endif
-        soundbyte = output;
-    #endif // POK_SIM
-#endif
-}
-
-void Sound::setPatternLooping(bool loop, uint8_t channel) {
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	patternLooping[channel] = loop;
-#endif
-}
-
-void Sound::playOK(){
-    #if POK_GBSOUND
-#if(NUM_CHANNELS > 0)
-	playPattern(playOKPattern,0);
-#endif
-#endif // POK_GBSOUND
-}
-
-void Sound::playCancel(){
-#if POK_GBSOUND
-#if(NUM_CHANNELS > 0)
-	playPattern(playCancelPattern,0);
-#endif
-#endif
-}
-
-void Sound::playTick(){
-#if POK_GBSOUND
-#if(NUM_CHANNELS > 0)
-	playPattern(playTickP,0);
-#endif
-#endif // POK_GBSOUND
-}
-
-void Sound::setVolume(int16_t volume) {
-//#if NUM_CHANNELS > 0
-	if (volume<0) volume = 0;
-	if (volume>volumeMax) volume = volumeMax;
-	globalVolume = volume; // % (volumeMax+1);
-	#ifndef POK_SIM
-	volume = (volume / 2)-10;
-	if (volume<0) volume = 0;
-	#if POK_ENABLE_SOUND > 0
-	setHWvolume(volume);
-	#endif
-	#endif
-	#if POK_SHOW_VOLUME > 0
-	c.volbar_visible = VOLUMEBAR_TIMEOUT;
-	#endif
-//#endif
-}
-
-uint16_t Sound::getVolume() {
-//#if NUM_CHANNELS > 0
-	return globalVolume;
-//#else
-//	return 0;
-//#endif
-}
-
-void Sound::setVolume(int8_t volume, uint8_t channel) {
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return;
-	volume = (volume > VOLUME_CHANNEL_MAX) ? VOLUME_CHANNEL_MAX : volume;
-	volume = (volume < 0) ? 0 : volume;
-	chanVolumes[channel] = volume;
-#endif
-}
-
-uint8_t Sound::getVolume(uint8_t channel) {
-#if(NUM_CHANNELS > 0)
-	if(channel>=NUM_CHANNELS)
-		return 255;
-	return (chanVolumes[channel]);
-#else
-	return 0;
-#endif
-}
-
-void Sound::playTone(uint8_t os, int frq, uint8_t amp, uint8_t wav,uint8_t arpmode)
-{
-    if (wav>5) wav=0;
-    if (arpmode>MAX_ARPMODE) arpmode=MAX_ARPMODE;
-    if (os==1) setOSC(&osc1,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0);
-    else if (os==2) setOSC(&osc2,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0);
-    else if (os==3) setOSC(&osc3,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0);
-}
-
-void Sound::playTone(uint8_t os, uint16_t frq, uint8_t volume, uint32_t duration)
-{
-    if (os==1) setOSC(&osc1,1,WSAW,frq,volume,duration);
-    else if (os==2) setOSC(&osc2,1,WTRI,frq,volume,duration);
-    else if (os==3) setOSC(&osc3,1,WTRI,frq,volume,duration);
-}
-
-uint8_t Sound::ampIsOn()
-{
-    #ifdef POK_SIM
-    return core.ampIsOn();
-    #else
-    #if POK_ENABLE_SOUND > 0
-    return Pokitto::ampIsOn();
-    #endif
-    #endif // POK_SIM
-    return 0;
-}
-
-void Sound::ampEnable(uint8_t v) {
-    #ifdef POK_SIM
-    core.ampEnable(v);
-    #else
-    #if POK_ENABLE_SOUND > 0
-    Pokitto::ampEnable(v);
-    #endif
-    #endif // POK_SIM
-
-}
-
-int Sound::playMusicStream(char* filename)
-{
-    return playMusicStream(filename,0);
-}
-
-int Sound::playMusicStream()
-{
-    #if POK_STREAMING_MUSIC >0
-    if (currentPtr) {
-            pokPlayStream();
-            return 1;
-    } else return 0; //no stream
-    #endif // POK_STREAMING_MUSIC
-}
-
-void Sound::pauseMusicStream() {
-    #if POK_ENABLE_SOUND > 0
-    pokPauseStream();
-    #endif
-}
-
-int Sound::playMusicStream(char* filename, uint8_t options)
-{
-    #if POK_STREAMING_MUSIC
-        uint8_t result;
-        result = pokInitSD();
-        if (!isThisFileOpen(filename)) {
-            fileClose(); // close any open files
-            result = fileOpen(filename,FILE_MODE_OVERWRITE | FILE_MODE_BINARY);
-        }
-
-        if (result) {
-                currentPtr = 0; // mark that no stream is available
-                return 0; // opening music file failed
-        }
-
-        fileReadBytes(&buffers[0][0],BUFFER_SIZE);
-        fileReadBytes(&buffers[1][0],BUFFER_SIZE);
-        fileReadBytes(&buffers[2][0],BUFFER_SIZE);
-        fileReadBytes(&buffers[3][0],BUFFER_SIZE);
-        currentBuffer = 0;
-        currentPtr = buffers[currentBuffer];
-        endPtr = currentPtr + BUFFER_SIZE;
-
-        //streaming = STR_PLAYING|options;
-
-        if (!options) pokPlayStream(); // activate stream
-    #endif //POK_STREAMING_MUSIC
-    return 1; // opening music file succeeded
-}
-
--- a/POKITTO_HW/HWButtons.cpp	Fri Dec 29 02:55:34 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/**************************************************************************/
-/*!
-    @file     HWButtons.cpp
-    @author   Jonne Valola
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2016, Jonne Valola
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-#include "HWButtons.h"
-#include "PokittoCore.h"
-#include "PokittoSound.h"
-#include "PokittoDisplay.h"
-
-Pokitto::Sound _s;
-Pokitto::Display _bd;
-
-using namespace mbed;
-
-InterruptIn ABtn(POK_BTN_A_PIN);
-InterruptIn BBtn(POK_BTN_B_PIN);
-InterruptIn CBtn(POK_BTN_C_PIN);
-InterruptIn UBtn(POK_BTN_UP_PIN);
-InterruptIn DBtn(POK_BTN_DOWN_PIN);
-InterruptIn LBtn(POK_BTN_LEFT_PIN);
-InterruptIn RBtn(POK_BTN_RIGHT_PIN);
-
-#define BS_IDLE 0
-#define BS_DOWN 1
-#define BS_UP 2
-
-uint8_t Pokitto::heldStates[NUM_BTN];
-
-void APressed() { Pokitto::heldStates[BTN_A] = 1; }
-void AReleased() { Pokitto::heldStates[BTN_A] = 0; }
-void BPressed() { Pokitto::heldStates[BTN_B] = 1; }
-void BReleased() { Pokitto::heldStates[BTN_B] = 0; }
-void CPressed() { Pokitto::heldStates[BTN_C] = 1;}
-void CReleased() { Pokitto::heldStates[BTN_C] = 0; }
-void UPressed() { Pokitto::heldStates[BTN_UP] = 1; }
-void UReleased() { Pokitto::heldStates[BTN_UP] = 0; }
-void DPressed() { Pokitto::heldStates[BTN_DOWN] = 1; }
-void DReleased() { Pokitto::heldStates[BTN_DOWN] = 0; }
-void RPressed() {
-    /* Hardware volume control */
-    if (Pokitto::heldStates[BTN_C]) _s.volumeUp();
-    else Pokitto::heldStates[BTN_RIGHT] = 1;
-    }
-void RReleased() { Pokitto::heldStates[BTN_RIGHT] = 0; }
-void LPressed() {
-    /* Hardware volume control */
-    if (Pokitto::heldStates[BTN_C]) _s.volumeDown();
-    else Pokitto::heldStates[BTN_LEFT] = 1;
-    }
-void LReleased() { Pokitto::heldStates[BTN_LEFT] = 0; }
-
-void Pokitto::initButtons() {  
-  ABtn.fall(&AReleased);
-  ABtn.rise(&APressed);
-  BBtn.fall(&BReleased);
-  BBtn.rise(&BPressed);
-  CBtn.fall(&CReleased);
-  CBtn.rise(&CPressed);
-  UBtn.fall(&UReleased);
-  UBtn.rise(&UPressed);
-  DBtn.fall(&DReleased);
-  DBtn.rise(&DPressed);
-  LBtn.fall(&LReleased);
-  LBtn.rise(&LPressed);
-  RBtn.fall(&RReleased);
-  RBtn.rise(&RPressed);
-}
-
-uint8_t Pokitto::Core::aBtn() {
-    return Pokitto::heldStates[BTN_A];
-}
-
-uint8_t Pokitto::Core::bBtn() {
-    return Pokitto::heldStates[BTN_B];
-}
-
-uint8_t Pokitto::Core::cBtn() {
-    return Pokitto::heldStates[BTN_C];
-}
-
-uint8_t Pokitto::Core::upBtn() {
-    return Pokitto::heldStates[BTN_UP];
-}
-uint8_t Pokitto::Core::downBtn() {
-    return Pokitto::heldStates[BTN_DOWN];
-}
-
-uint8_t Pokitto::Core::leftBtn() {
-    return Pokitto::heldStates[BTN_LEFT];
-}
-uint8_t Pokitto::Core::rightBtn() {
-    return Pokitto::heldStates[BTN_RIGHT];
-}
-
--- a/POKITTO_HW/HWLCD.cpp	Fri Dec 29 02:55:34 2017 +0000
+++ b/POKITTO_HW/HWLCD.cpp	Fri Dec 29 05:17:10 2017 +0000
@@ -37,6 +37,11 @@
 #include "HWLCD.h" //HWLCD.h" #include "HWLCD.h"
 #include "Pokitto_settings.h"
 
+#ifndef DISABLEAVRMIN
+#define max(a,b) ((a)>(b)?(a):(b))
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif // DISABLEAVRMIN
+
 #define AB_JUMP 1024 // jump one 1-bit Arduboy screen forward to get next color bit
 #define GB_JUMP 504 // jump one 1-bit Gamebuino screen forward to get next color bit
 
@@ -327,6 +332,7 @@
     }
 }
 
+
 void Pokitto::setWindow(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
 	write_command(0x37); write_data(x1);
 	write_command(0x36); write_data(x2);
@@ -449,7 +455,11 @@
 uint16_t scanline[4][176]; // read 4 half-nibbles = 4 pixels at a time
 uint8_t *d, yoffset=0;
 
+#ifdef PROJ_USE_FPS_COUNTER
+xptr = 8;
+#else
 xptr = 0;
+#endif
 setDRAMptr(xptr,yoffset);
 
 
@@ -474,51 +484,367 @@
 
     d+=220/4; // jump to read byte directly below in screenbuffer
     }
-    s=0;
-    /** draw scanlines **/
-    for (s=0;s<176;) {
-        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
-    }
-    for (s=0;s<176;) {
-        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
-    }
-    for (s=0;s<176;) {
-        setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
-    }
-    for (s=0;s<176;) {
-        setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
-        setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+
+#ifdef PROJ_USE_FPS_COUNTER
+    if (x>=8 ) {
+#else
+    {
+
+#endif
+
+        /** draw scanlines **/
+        for (s=0;s<176;) {
+            setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+        }
+        for (s=0;s<176;) {
+            setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+        }
+        for (s=0;s<176;) {
+            setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+        }
+        for (s=0;s<176;) {
+            setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+            setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+        }
     }
   }
 }
 
+// Copy sprite pixels to the scanline
+#define SPRITE_2BPP_INNER_LOOP(n)\
+\
+    /* If the sprite is enabled and contained in this vertical scanline, copy 4 pixels. */\
+    if (sprScanlineAddr[(n)] &&\
+        y >= sprites[(n)].y && y < sprites[(n)].y + sprites[(n)].h ) {\
+\
+        int16_t sprx = sprites[(n)].x;\
+        uint16_t s_data16b = 0;  /* sprite data, 2 bytes */\
+\
+        /* Get pixel block, 4 or 8 pixels horizontally. Use the predefined bitshift mode. */\
+        /* Note:it is cheapest to compare to 0 first. */\
+        if (sprScanlineBitshiftMode[(n)] == BITSHIFT_MODE_MIDDLE_BYTE) {\
+            s_data16b = *(sprScanlineAddr[(n)]);\
+            uint16_t leftByte = *(sprScanlineAddr[(n)]-1);\
+            s_data16b = (leftByte << 8) | s_data16b;\
+        }\
+        else if (sprScanlineBitshiftMode[(n)] == BITSHIFT_MODE_FIRST_BYTE) {\
+            s_data16b = *(sprScanlineAddr[(n)]);\
+        }\
+        else { /* BITSHIFT_MODE_LAST_BYTE */\
+            uint16_t leftByte = *(sprScanlineAddr[(n)]-1);\
+            s_data16b = (leftByte << 8) | s_data16b;\
+        }\
+\
+        /* Shift sprite pixels according to sprite x. After shifting we have only 4 pixels. */\
+        uint8_t shiftRight = (sprx&0x3) << 1;\
+        s_data16b = (s_data16b >> shiftRight);\
+\
+        /* Get individual pixels */\
+        uint8_t s_t4 = s_data16b & 0x03; s_data16b >>= 2; /* lowest half-nibble */\
+        uint8_t s_t3 = s_data16b & 0x03; s_data16b >>= 2; /* second lowest half-nibble */\
+        uint8_t s_t2 = s_data16b & 0x03; s_data16b >>= 2; /* second highest half-nibble */\
+        uint8_t s_t1 = s_data16b & 0x03;                  /* highest half-nibble */\
+\
+        /* Store pixels as 16-bit colors from the palette */\
+        if (s_t4 != transparentColor) p4 = sprites[(n)].palette[s_t4];\
+        if (s_t3 != transparentColor) p3 = sprites[(n)].palette[s_t3];\
+        if (s_t2 != transparentColor) p2 = sprites[(n)].palette[s_t2];\
+        if (s_t1 != transparentColor) p = sprites[(n)].palette[s_t1];\
+\
+        /* Advance scanline address */\
+        sprScanlineAddr[(n)] += (sprites[(n)].w >> 2);\
+    }
+
+// Loop unrolling macros
+#define UNROLLED_LOOP_1() SPRITE_2BPP_INNER_LOOP(0)
+#define UNROLLED_LOOP_2() UNROLLED_LOOP_1() SPRITE_2BPP_INNER_LOOP(1)
+#define UNROLLED_LOOP_3() UNROLLED_LOOP_2() SPRITE_2BPP_INNER_LOOP(2)
+#define UNROLLED_LOOP_4() UNROLLED_LOOP_3() SPRITE_2BPP_INNER_LOOP(3)
+#define UNROLLED_LOOP_5() UNROLLED_LOOP_4() SPRITE_2BPP_INNER_LOOP(4)
+#define UNROLLED_LOOP_6() UNROLLED_LOOP_5() SPRITE_2BPP_INNER_LOOP(5)
+#define UNROLLED_LOOP_7() UNROLLED_LOOP_6() SPRITE_2BPP_INNER_LOOP(6)
+#define UNROLLED_LOOP_8() UNROLLED_LOOP_7() SPRITE_2BPP_INNER_LOOP(7)
+#define UNROLLED_LOOP_9() UNROLLED_LOOP_8() SPRITE_2BPP_INNER_LOOP(8)
+#define UNROLLED_LOOP_10() UNROLLED_LOOP_9() SPRITE_2BPP_INNER_LOOP(9)
+#define UNROLLED_LOOP_11() UNROLLED_LOOP_10() SPRITE_2BPP_INNER_LOOP(10)
+#define UNROLLED_LOOP_12() UNROLLED_LOOP_11() SPRITE_2BPP_INNER_LOOP(11)
+#define UNROLLED_LOOP_13() UNROLLED_LOOP_12() SPRITE_2BPP_INNER_LOOP(12)
+#define UNROLLED_LOOP_14() UNROLLED_LOOP_13() SPRITE_2BPP_INNER_LOOP(13)
+#define UNROLLED_LOOP_15() UNROLLED_LOOP_14() SPRITE_2BPP_INNER_LOOP(14)
+#define UNROLLED_LOOP_16() UNROLLED_LOOP_15() SPRITE_2BPP_INNER_LOOP(15)
+#define UNROLLED_LOOP_N_(n) UNROLLED_LOOP_##n()
+#define UNROLLED_LOOP_N(n) UNROLLED_LOOP_N_(n)
+
+/**
+Update the screen buffer of 220x176 pixels and sprites to LCD.
+
+If useDirectMode=true only sprites are updated TO LCD and the dirty rect is drawn behind the sprite current and previous
+location.
+If useDirectMode=false both the full screen buffer and sprites are updated to LCD.
+
+Limitations of sprites:
+- Sprite is enabled if sprites.bitmapData is not NULL
+- All enabled sprites must be at the beginning of the sprites array.
+*/
+void Pokitto::lcdRefreshMode1Spr(uint8_t * scrbuf, uint16_t* paletteptr, SpriteInfo* sprites, bool useDirectMode) {
+
+    // In direct mode, return now if there are no sprites
+    if (useDirectMode && (sprites == NULL || sprites[0].bitmapData == NULL))
+        return;
+
+    uint16_t x,y;
+    uint16_t scanline[4][176]; // read 4 half-nibbles (= 4 pixels) at a time
+    const uint8_t transparentColor = 0;  // fixed palette index 0 for transparency
+
+    // Calculate the current amount of sprites
+    // Note: Sprites must be taken into use from index 0 upwards, because the first sprite with bitmapData==NULL is considered as the last sprite
+    uint8_t spriteCount = 0;
+    if (sprites != NULL)
+        for (;sprites[spriteCount].bitmapData != NULL && spriteCount < SPRITE_COUNT; spriteCount++);
+
+    // If drawing the screen buffer, set the start pos to LCD commands only here.
+    #ifdef PROJ_USE_FPS_COUNTER
+    if (!useDirectMode) setDRAMptr(8, 0);
+    #else
+    if (!useDirectMode) setDRAMptr(0, 0);
+    #endif
+
+    // TODO OPTIMIZE: if a sprite is totally out-of-screen, it could be marked here already. Even in this case we might
+    // need to clear the previous sprite location with screen buffer pixels.
+
+    // Go through each vertical group of 4 scanlines.
+    for (x=0; x<220; x+=4) {
+
+        uint8_t *screenBufScanlineAddr = scrbuf + (x>>2);// point to beginning of line in data
+
+        /*Prepare scanline start address for sprites that are visible in this vertical scanline. Sprite width cannot exceed the screen width*/
+        uint8_t *sprScanlineAddr[SPRITE_COUNT];  // Sprite start address for the scanline
+        uint8_t sprScanlineBitshiftMode[SPRITE_COUNT];  // Sprite bitshift mode for the scanline
+        const uint8_t BITSHIFT_MODE_MIDDLE_BYTE = 0;
+        const uint8_t BITSHIFT_MODE_FIRST_BYTE = 1;
+        const uint8_t BITSHIFT_MODE_LAST_BYTE = 2;
+        uint8_t scanlineMinY = 0;  // Min y to draw for the scanline
+        uint8_t scanlineMaxY = 175;  // Max y to draw for the scanline
+
+        // If not drawing the screen buffer, reset min and max to uninitialized values
+        if (useDirectMode ) {
+            scanlineMinY = 255;
+            scanlineMaxY = 0;
+        }
+        if (sprites != NULL) {
+
+            // Check all the sprites for this scanline.
+            for (int sprindex = 0; sprindex < spriteCount; sprindex++) {
+
+                int16_t sprx = sprites[sprindex].x;
+                int16_t spry = sprites[sprindex].y;
+                uint8_t sprw = sprites[sprindex].w;
+                uint8_t sprh = sprites[sprindex].h;
+                int16_t sprOldX = sprites[sprindex].oldx;
+                int16_t sprOldY = sprites[sprindex].oldy;
+
+                // Detect the dirty rect x-span by combining the previous and current sprite position.
+                int16_t sprDirtyXMin = min(sprx, sprOldX);
+                int16_t sprDirtyXMax = max(sprx, sprOldX);
+
+                // Is current x inside the sprite combined dirty rect ?
+                int16_t sprDirtyXMaxEnd = sprDirtyXMax + sprw - 1 + 4; // Add 4 pixels to dirty rect width (needed?)
+                if (sprDirtyXMin <= x+3 && x <= sprDirtyXMaxEnd) {
+
+                    // If not drawing the whole screen buffer, detect the dirty rect y-span by combining the old and
+                    // current sprite position, and combine all the sprites.
+                    if (useDirectMode) {
+
+                        // Dirty rect
+                        int16_t sprDirtyYMin = min(spry, sprOldY);
+                        sprDirtyYMin = max(sprDirtyYMin, 0);
+                        int16_t sprDirtyYMax = max(spry, sprOldY);
+                        int16_t sprDirtyYMaxEnd = sprDirtyYMax + sprh - 1;
+                        sprDirtyYMaxEnd = min(sprDirtyYMaxEnd, 175);
+
+                        // Get the scanline min and max y values for drawing
+                        if (sprDirtyYMin < scanlineMinY)
+                            scanlineMinY = sprDirtyYMin;
+                        if (sprDirtyYMaxEnd > scanlineMaxY)
+                            scanlineMaxY = sprDirtyYMaxEnd;
+                    }
+
+                    // Check if the sprite should be active for this vertical scanline group.
+                    if (sprx <= x+3 && x < sprx + sprw) { // note: cover group of 4 pixels of the scanline (x+3)
+
+                        // Find the byte number in the sprite data
+                        int16_t byteNum = ((x+3) - sprx)>>2;
+
+                        // Get the start addres of the spite data in this scanline.
+                        sprScanlineAddr[sprindex] = const_cast<uint8_t*>(sprites[sprindex].bitmapData + byteNum);
+
+                        // If the sprite goes over the top, it must be clipped from the top.
+                        if(spry < 0)
+                            sprScanlineAddr[sprindex] += (-spry) * (sprw >> 2);
+
+                        // Select the bitshift mode for the blit algorithm
+                        if (byteNum == 0)
+                            sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_FIRST_BYTE;
+                        else if (byteNum >= (sprw >> 2))
+                            sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_LAST_BYTE;
+                        else
+                            sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_MIDDLE_BYTE;
+                    }
+                    else
+                        sprScanlineAddr[sprindex] = NULL;  // Deactive sprite for this scanline
+                }
+                else
+                    sprScanlineAddr[sprindex] = NULL;  // Deactive sprite for this scanline
+            }
+        }
+
+        // The height must dividable by 8. That is needed because later we copy 8 pixels at a time to the LCD.
+        if (useDirectMode && scanlineMaxY - scanlineMinY + 1 > 0) {
+            uint8_t scanlineH = scanlineMaxY - scanlineMinY + 1;
+            uint8_t addW = 8 - (scanlineH & 0x7);
+
+            // if height is not dividable by 8, make it be.
+            if (addW != 0) {
+                if (scanlineMinY > addW )
+                    scanlineMinY -= addW;
+                else if( scanlineMaxY + addW < 176)
+                    scanlineMaxY += addW;
+                else {
+                    scanlineMinY = 0;
+                    scanlineMaxY = 175;
+                }
+            }
+        }
+
+        // Find colours in this group of 4 scanlines
+        screenBufScanlineAddr += (scanlineMinY * 220/4);
+        for (y=scanlineMinY; y<=scanlineMaxY; y++)
+        {
+            // get the screen buffer data first
+            uint8_t tdata = *screenBufScanlineAddr;
+            uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
+            uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
+            uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
+            uint8_t t = tdata & 0x03;// highest half-nibble
+
+            // Convert to 16-bit colors in palette
+            uint16_t p = paletteptr[t];
+            uint16_t p2 = paletteptr[t2];
+            uint16_t p3 = paletteptr[t3];
+            uint16_t p4 = paletteptr[t4];
+
+            // Add active sprite pixels
+            if (sprites != NULL) {
+
+                // Use loop unrolling for speed optimization
+                UNROLLED_LOOP_N(SPRITE_COUNT)
+            }
+
+            // put the result nibble values in the scanline
+            scanline[0][y] = p;
+            scanline[1][y] = p2;
+            scanline[2][y] = p3;
+            scanline[3][y] = p4;
+
+            screenBufScanlineAddr += 220>>2; // jump to read byte directly below in screenbuffer
+        }
+
+        // Draw scanline to LCD
+#ifdef PROJ_USE_FPS_COUNTER
+        if (x>=8 && scanlineMaxY - scanlineMinY +1 > 0) {
+#else
+        if (scanlineMaxY - scanlineMinY +1 > 0) {
+#endif
+            if (useDirectMode) setDRAMptr(x, scanlineMinY);
+            for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
+                setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
+            }
+
+            if (useDirectMode) setDRAMptr(x+1, scanlineMinY);
+            for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
+                setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
+            }
+
+            if (useDirectMode) setDRAMptr(x+2, scanlineMinY);
+            for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
+                setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
+            }
+
+            if (useDirectMode) setDRAMptr(x+3, scanlineMinY);
+            for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
+                setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+                setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
+            }
+        }
+    }
+
+    // Update old x and y for the sprites
+    if (sprites != NULL) {
+        for (int sprindex = 0; sprindex < spriteCount; sprindex++) {
+            sprites[sprindex].oldx = sprites[sprindex].x;
+            sprites[sprindex].oldy = sprites[sprindex].y;
+        }
+    }
+
+    #ifdef POK_SIM
+    simulator.refreshDisplay();
+    #endif
+}
+
 void Pokitto::lcdRefreshMode2(uint8_t * scrbuf, uint16_t* paletteptr) {
 uint16_t x,y;
 uint16_t scanline[2][88]; // read two nibbles = pixels at a time
@@ -1206,8 +1532,80 @@
     #endif
 }
 
+
+void Pokitto::lcdRefreshMode13(uint8_t * scrbuf, uint16_t* paletteptr, uint8_t offset){
+uint16_t x,y;
+uint16_t scanline[2][110]; // read two nibbles = pixels at a time
+uint8_t *d;
+
+write_command(0x20); write_data(0);
+write_command(0x21); write_data(0);
+write_command(0x22);
+CLR_CS_SET_CD_RD_WR;
+
+for(x=0;x<110;x+=2)
+  {
+    d = scrbuf+x;// point to beginning of line in data
+    uint8_t s=0;
+    for(y=0;y<88;y++)
+    {
+        uint8_t t = *d;
+        uint8_t t1 = *(d+1);
+        scanline[0][s] = paletteptr[(t+offset)&255];
+        scanline[1][s++] = paletteptr[(t1+offset)&255];
+        d+=110; // jump to read byte directly below in screenbuffer
+    }
+    s=0;
+    for (s=0;s<88;) {
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+    }
+    for (s=0;s<88;) {
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+    }
+    for (s=0;s<88;) {
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+    }
+    for (s=0;s<88;) {
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+        setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
+    }
+  }
+
+}
+
+
+
+
 void Pokitto::blitWord(uint16_t c) {
     setup_data_16(c);CLR_WR;SET_WR;
 }
 
 
+
--- a/POKITTO_HW/HWLCD.h	Fri Dec 29 02:55:34 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +0,0 @@
-/**************************************************************************/
-/*!
-    @file     HWLCD.h
-    @author   Jonne Valola
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2016, Jonne Valola
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-#ifndef __HWLCD_H__
-#define __HWLCD_H__
-
-#include "mbed.h"
-#include "gpio_api.h"
-#include "pinmap.h"
-
-#define write_command write_command_16
-#define write_data write_data_16
-
-namespace Pokitto {
-
-
-extern void initBacklight();
-extern void setBacklight(float);
-extern void lcdFillSurface(uint16_t);
-extern void lcdPixel(int16_t x, int16_t y, uint16_t c);
-extern void setWindow(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
-extern void lcdTile(int16_t x0, int16_t y0, int16_t width, int16_t height, uint16_t* gfx);
-extern void lcdRectangle(int16_t x, int16_t y,int16_t x2, int16_t y2, uint16_t color);
-extern void lcdInit();
-extern void lcdSleep();
-extern void lcdWakeUp();
-extern void lcdRefresh(uint8_t *, uint16_t*);
-extern void lcdRefreshAB(uint8_t *, uint16_t*);
-extern void lcdRefreshGB(uint8_t *, uint16_t*);
-extern void lcdRefreshRegionMode1(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t * scrbuf, uint16_t * paletteptr);
-extern void lcdRefreshMode1(uint8_t *, uint16_t*);
-extern void lcdRefreshMode2(uint8_t *, uint16_t*);
-extern void lcdRefreshMode3(uint8_t *, uint16_t*);
-extern void lcdRefreshModeGBC(uint8_t *, uint16_t*);
-/** Update LCD from 1-bit tile mode */
-extern void lcdRefreshT1(uint8_t*, uint8_t*, uint8_t*, uint16_t*);
-extern void lcdClear();
-extern void lcdFill(uint16_t);
-/** Blit one word of data*/
-extern void blitWord(uint16_t);
-
-/**************************************************************************/
-/**                          PINS AND PORTS                              **/
-/**************************************************************************/
-
-#if POK_BOARDREV == 1
-/** 2-layer board version 1.3 **/
- #define LCD_CD_PORT           0
- #define LCD_CD_PIN            2
- #define LCD_WR_PORT           1
- #define LCD_WR_PIN            23
- #define LCD_RD_PORT           1
- #define LCD_RD_PIN            24
- #define LCD_RES_PORT          1
- #define LCD_RES_PIN           28
-#else
-/** 4-layer board version 2.1 **/
- #define LCD_CD_PORT           0
- #define LCD_CD_PIN            2
- #define LCD_WR_PORT           1
- #define LCD_WR_PIN            12
- #define LCD_RD_PORT           1
- #define LCD_RD_PIN            24
- #define LCD_RES_PORT          1
- #define LCD_RES_PIN           0
-#endif
-
-/**************************************************************************/
-/**                          LCD CONTROL MACROS                          **/
-/**************************************************************************/
-
-#define CLR_RESET LPC_GPIO_PORT->CLR[LCD_RES_PORT] = 1 << LCD_RES_PIN; //RST = (0); // Clear pin
-#define SET_RESET LPC_GPIO_PORT->SET[LCD_RES_PORT] = 1 << LCD_RES_PIN; // RST = (1); // Set pin
-
-#define CLR_CD { LPC_GPIO_PORT->CLR[LCD_CD_PORT] = 1 << LCD_CD_PIN; } // RS = (0); // Clear pin
-#define SET_CD { LPC_GPIO_PORT->SET[LCD_CD_PORT] = 1 << LCD_CD_PIN; }// RS = (1); // Set pin
-
-#define CLR_WR { LPC_GPIO_PORT->CLR[LCD_WR_PORT] = 1 << LCD_WR_PIN; __asm("nop");__asm("nop");}//WR = (0); // Clear pin
-#define SET_WR LPC_GPIO_PORT->SET[LCD_WR_PORT] = 1 << LCD_WR_PIN; //WR = (1); // Set pin
-
-#define CLR_RD LPC_GPIO_PORT->CLR[LCD_RD_PORT] = 1 << LCD_RD_PIN; //RD = (0); // Clear pin
-#define SET_RD LPC_GPIO_PORT->SET[LCD_RD_PORT] = 1 << LCD_RD_PIN; //RD = (1); // Set pin
-
-#define SET_CS  //CS tied to ground
-#define CLR_CS
-
-#define CLR_CS_CD_SET_RD_WR {CLR_CD; SET_RD; SET_WR;}
-#define CLR_CS_SET_CD_RD_WR {SET_CD; SET_RD; SET_WR;}
-#define SET_CD_RD_WR {SET_CD; SET_RD; SET_WR;}
-#define SET_WR_CS SET_WR;
-
-#define SET_MASK_P2 LPC_GPIO_PORT->MASK[2] = ~(0x7FFF8); //mask P2_3 ...P2_18
-#define CLR_MASK_P2 LPC_GPIO_PORT->MASK[2] = 0; // all on
-
-
-
-/**************************************************************************/
-/**                          SETUP GPIO & DATA                           **/
-/**************************************************************************/
-
-static void setup_gpio()
-{
-    /** control lines **/
-    LPC_GPIO_PORT->DIR[LCD_CD_PORT] |= (1  << LCD_CD_PIN );
-    LPC_GPIO_PORT->DIR[LCD_WR_PORT] |= (1  << LCD_WR_PIN );
-    LPC_GPIO_PORT->DIR[LCD_RD_PORT] |= (1  << LCD_RD_PIN );
-    LPC_GPIO_PORT->DIR[LCD_RES_PORT] |= (1  << LCD_RES_PIN );
-    /** data lines **/
-    LPC_GPIO_PORT->DIR[2] |= (0xFFFF  << 3);  // P2_3...P2_18 as output
-
-    pin_mode(P2_3,PullNone); // turn off pull-up
-    pin_mode(P2_4,PullNone); // turn off pull-up
-    pin_mode(P2_5,PullNone); // turn off pull-up
-    pin_mode(P2_6,PullNone); // turn off pull-up
-
-    pin_mode(P2_7,PullNone); // turn off pull-up
-    pin_mode(P2_8,PullNone); // turn off pull-up
-    pin_mode(P2_9,PullNone); // turn off pull-up
-    pin_mode(P2_10,PullNone); // turn off pull-up
-
-    pin_mode(P2_11,PullNone); // turn off pull-up
-    pin_mode(P2_12,PullNone); // turn off pull-up
-    pin_mode(P2_13,PullNone); // turn off pull-up
-    pin_mode(P2_14,PullNone); // turn off pull-up
-
-    pin_mode(P2_15,PullNone); // turn off pull-up
-    pin_mode(P2_16,PullNone); // turn off pull-up
-    pin_mode(P2_17,PullNone); // turn off pull-up
-    pin_mode(P2_18,PullNone); // turn off pull-up
-}
-
-
-
-
-#define HI_BYTE(d) (LPC_GPIO->MPIN[1]= (d<<13)) //((d>>8)<<21))
-#define LO_BYTE(d) (LPC_GPIO->MPIN[1]= (d<<21)) //because of mask makes no difference
-
-// Macros to set data bus direction to input/output
-#define LCD_GPIO2DATA_SETINPUT  GPIO_GPIO2DIR &= ~LCD_DATA_MASK
-#define LCD_GPIO2DATA_SETOUTPUT GPIO_GPIO2DIR |= LCD_DATA_MASK
-
-
-// Basic Color definitions
-#define	COLOR_BLACK                         (uint16_t)(0x0000)
-#define	COLOR_BLUE                          (uint16_t)(0x001F)
-#define	COLOR_RED                           (uint16_t)(0xF800)
-#define	COLOR_GREEN                         (uint16_t)(0x07E0)
-#define COLOR_CYAN                          (uint16_t)(0x07FF)
-#define COLOR_MAGENTA                       (uint16_t)(0xF81F)
-#define COLOR_YELLOW                        (uint16_t)(0xFFE0)
-#define COLOR_WHITE                         (uint16_t)(0xFFFF)
-
-// Grayscale Values
-#define COLOR_GRAY_15                       (uint16_t)(0x0861)    //  15  15  15
-#define COLOR_GRAY_30                       (uint16_t)(0x18E3)    //  30  30  30
-#define COLOR_GRAY_50                       (uint16_t)(0x3186)    //  50  50  50
-#define COLOR_GRAY_80                       (uint16_t)(0x528A)    //  80  80  80
-#define COLOR_GRAY_128                      (uint16_t)(0x8410)    // 128 128 128
-#define COLOR_GRAY_200                      (uint16_t)(0xCE59)    // 200 200 200
-#define COLOR_GRAY_225                      (uint16_t)(0xE71C)    // 225 225 225
-
-
-} // namespace pokitto
-#endif // __HWLCD_H_
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/POKITTO_LIBS/ImageFormat/BmpImage.cpp	Fri Dec 29 05:17:10 2017 +0000
@@ -0,0 +1,482 @@
+/**************************************************************************/
+/*!
+    @file     BmpImage.cpp
+    @author   Hannu Viitala. Original BMP decoder code by Jonne Valola.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2016, Jonne Valola
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#if POKITTO_USE_WIN_SIMULATOR
+#include "defines_win_SIM.h"
+#endif
+
+#define PROJ_MBED 1
+
+#if PROJ_LINUX || PROJ_MBED
+#include "defines_linux_SIM.h"
+#endif
+
+#include "Pokitto.h"
+#include "PokittoDisk.h"
+#ifdef POK_SIM
+#include "FileIO.h"
+#endif
+
+#if POK_ENABLE_SD > 0
+
+
+#include "PokittoDisplay.h"
+#include "ImageFormat.h"
+
+Pokitto::Core _game;
+Pokitto::Display pokdisp;
+
+int openImageFileFromSD(char* filepath, uint16_t **palette_out, uint8_t **bitmap_out) {
+
+    // Reset the out pointers.
+    *palette_out = 0;
+    *bitmap_out = 0;
+
+    BITMAPFILEHEADER bf;
+    BITMAPINFO bmi;
+
+    uint32_t bytes_read=0, bmpsize=0;
+
+    /** numcol is the number of colors for output */
+    unsigned int numcol = 0;
+
+    if (POK_COLORDEPTH == 8) numcol=256;
+    else if (POK_COLORDEPTH == 4) numcol=16;
+    else if (POK_COLORDEPTH == 2) numcol=4;
+    else if (POK_COLORDEPTH == 1) numcol=1;
+
+    if (!isThisFileOpen(filepath)) {
+        fileClose(); // close any open files
+        fileOpen(filepath, FILE_MODE_READONLY | FILE_MODE_BINARY);
+    }
+    else
+        return -1;  // Already open, not good.
+
+    if (fileOK() && fileReadBytes((uint8_t*)&bf, sizeof(bf)) == sizeof(bf) ) {
+        bytes_read += sizeof(bf);
+    }
+	else
+	{
+		POK_TRACE("Error reading BMP header\n");
+		fileClose();
+		return(-1);
+	}
+
+    if (fileReadBytes((uint8_t*)&bmi,sizeof(bmi.bmiHeader)) != sizeof(bmi.bmiHeader)) {
+		POK_TRACE("Error reading BMP info\n");
+		fileClose();
+		return(-1);
+	}
+    bytes_read += sizeof(bmi.bmiHeader);
+
+    /** Check image validity */
+
+    if (bf.bfType != 0x4D42) {
+        POK_TRACE("Bitmap file has an unrecognized format (4D42 id missing from beginning).\n");
+        POK_TRACE("BMP2POK accepts .BMP files that have an indexed (1,-bit, 4-bit or 8-bit) color palette.\n");
+        fileClose();
+        return(-1);
+    }
+    if (bmi.bmiHeader.biBitCount != POK_COLORDEPTH ) {
+        POK_TRACE("ERROR!\nThe image color depth should be the same as screen color depth!\n");
+    }
+    if (bmi.bmiHeader.biWidth%32 && bmi.bmiHeader.biBitCount == 1) {
+        POK_TRACE("ERROR!\nPadding of 1-bit (monochrome) images is not yet supported\n");
+        POK_TRACE("1-bit images need to have width that is divisible by 32!\n");
+        POK_TRACE("Adjust size of source image.\n");
+        fileClose();
+        return(-1);
+    }
+	if (bmi.bmiHeader.biWidth%4) {
+        POK_TRACE("Width is not divisible by 4\n");
+        fileClose();
+        return(-1);
+	}
+	if (bmi.bmiHeader.biWidth%8 && bmi.bmiHeader.biBitCount==4) {
+        if (bmi.bmiHeader.biWidth%4) {
+            POK_TRACE("ERROR!\n4-bit source images have to have a width that is divisible by 4\n");
+            fileClose();
+            return(-1);
+        }
+	}
+    if (bmi.bmiHeader.biBitCount != 8 && bmi.bmiHeader.biBitCount != 4 && bmi.bmiHeader.biBitCount != 1)
+    {
+        POK_TRACE("Only 8bpp, 4bpp & 1bpp BMP files are supported\n");
+        fileClose();
+        return(-1);
+    }
+    if (bmi.bmiHeader.biCompression != 0 &&
+        !(bmi.bmiHeader.biCompression == BI_RLE4 && bmi.bmiHeader.biBitCount == 4))
+    {
+        POK_TRACE("Only RLE compression for bitmaps with 4 bpp is supported\n");
+        fileClose();
+        return(-1);
+    }
+
+    /* If the height is negative the bmp image is in the correct way.
+       If the heigh is positive the bmp image is vertically mirrored
+    */
+    int biAbsHeight = bmi.bmiHeader.biHeight;
+    if (bmi.bmiHeader.biHeight < 0 )
+        biAbsHeight = - bmi.bmiHeader.biHeight;
+
+    /** Read and copy palette **/
+
+    int c = bmi.bmiHeader.biClrUsed;
+    if (c==0) c = 1 << bmi.bmiHeader.biBitCount; // from MS BMP specs. 0 means 2^n colors
+    bmi.bmiHeader.biClrUsed = c;
+
+    /* Allocate memory for the output parameter */
+    if (numcol>bmi.bmiHeader.biClrUsed) numcol = bmi.bmiHeader.biClrUsed;
+    *palette_out = (uint16_t*) malloc(numcol*2);
+  	if (*palette_out == NULL)
+	{
+		POK_TRACE("Error allocating temporary palette buffer.\n");
+		free(*palette_out);
+		return(-1);
+	}
+
+    /* seek to the beginning of the color table - because of gimp */
+    fileSeekAbsolute(bf.bfOffBits-c*4); //gfx data star minus color table
+
+    for (unsigned int c=0;c<numcol;c++) {
+
+        RGBQUAD rgbValue;
+        fileReadBytes((uint8_t*)&rgbValue, sizeof(RGBQUAD));
+        bytes_read += sizeof(RGBQUAD);
+
+        unsigned int r,g,b,o;
+        r = rgbValue.rgbRed >> 3; // 5 bit
+        g = rgbValue.rgbGreen >> 2; // 6 bits
+        b = rgbValue.rgbBlue >> 3; // 5 bits
+        o = (r<<11)|(g<<5)|b;
+
+        (*palette_out)[c] = o;
+    }
+
+    /** Read and copy image data **/
+
+    /* Get image data size. If the biSizeImage is given (>0) for RLE image, use that to reduce memory usage. */
+    bmpsize = bmi.bmiHeader.biWidth * biAbsHeight*bmi.bmiHeader.biBitCount/8;
+	if (bmi.bmiHeader.biCompression == BI_RLE4)
+        bmpsize = (bmi.bmiHeader.biSizeImage > 0) ? bmi.bmiHeader.biSizeImage : bmpsize;
+
+    // SEEK to the beginning of the data
+	fileSeekAbsolute(bf.bfOffBits);
+
+   /* Allocate output data buffer */
+    *bitmap_out = (uint8_t *) malloc(bmpsize + 2);  // header takes 2 bytes
+    if (*bitmap_out == NULL)
+    {
+        POK_TRACE("Error allocating temporary data buffer, is image too big?\n");
+        free(*palette_out);
+        return(-1);
+    }
+
+    /* Store image size to the pokitto bitmap header */
+    uint32_t outindex = 0;
+    (*bitmap_out)[outindex++] = bmi.bmiHeader.biWidth;
+    (*bitmap_out)[outindex++] = biAbsHeight;
+
+ 	if (bmi.bmiHeader.biCompression == BI_RLE4) {
+        bool eofReached = false;
+        while (outindex < bmpsize && !eofReached ) {
+            /* Read byte from the file. */
+            unsigned char rleByte;
+            if (fileReadBytes(&rleByte, sizeof(rleByte)) != sizeof(rleByte))
+            {
+                /* End of file reached. Allocate a new bitmap which is of the exact size of the data */
+                eofReached = true;
+
+                /* Allocate output data buffer */
+                uint8_t* old_bitmap = *bitmap_out;
+                *bitmap_out = NULL;
+                *bitmap_out = (uint8_t *) malloc(outindex);  // header takes 2 bytes
+                if (*bitmap_out == NULL)
+                {
+                    POK_TRACE("Error allocating temporary data buffer, is image too big?\n");
+                    free(old_bitmap);
+                    free(*palette_out);
+                    return(-1);
+                }
+
+                /* Copy data */
+                for (int i=0; i<outindex;i++)
+                   (*bitmap_out)[i] = old_bitmap[i];
+
+                /* Free original bitmap */
+                free(old_bitmap);
+            }
+            else {
+                /* Store byte */
+                (*bitmap_out)[outindex++] = rleByte;
+            }
+        } // end while
+	}
+	else {
+        /* Do vertical mirroring only for uncompressed data.
+           Note the compressed RLE data above could not be mirrored.
+        */
+        int widthInBytes = bmi.bmiHeader.biWidth * bmi.bmiHeader.biBitCount/8;
+        int widthInBytesInc, incY, startY, endY;
+        if (bmi.bmiHeader.biHeight > 0 ) {
+            /* Mirror vertically */
+            widthInBytesInc = - widthInBytes;
+            incY = -1;
+            startY = biAbsHeight - 1;
+            endY = -1;
+        }
+        else {
+            /* Do not mirror */
+            widthInBytesInc = widthInBytes;
+            incY = 1;
+            startY = 0;
+            endY = biAbsHeight;
+        }
+
+        /* Copy all bytes to the output bitmap */
+        for ( int y = startY, beginLine=startY*widthInBytes; y != endY; y += incY, beginLine += widthInBytesInc) {
+
+            /* Go to the beginning of the previous or next line */
+            outindex = beginLine;
+
+            for ( int xbyte = 0; xbyte < widthInBytes; xbyte++) {
+
+                /* Read byte from the file. */
+                unsigned char byteOfPixels;
+                if (fileReadBytes(&byteOfPixels, sizeof(byteOfPixels)) != sizeof(byteOfPixels))
+                {
+                    POK_TRACE("Error reading BMP data\n");
+                    fileClose();
+                    free(*bitmap_out);
+                    free(*palette_out);
+                    return(-1);
+                }
+
+                /* Copy a byte from the file to the bitmap */
+                (*bitmap_out)[2 + outindex] = byteOfPixels;
+                outindex++;
+            } // end for
+        } // end for
+	} // end if
+
+	// Done with the file reading.
+	fileClose();
+
+    return 0;
+}
+
+int directDrawImageFileFromSD(int16_t sx, int16_t sy, char* filepath) {
+
+    return(directDrawImageFileFromSD(0, 0, 0/* full width */, 0/* full height */, sx, sy, filepath));
+}
+
+int directDrawImageFileFromSD(uint16_t ix, uint16_t iy, uint16_t iw, uint16_t ih, int16_t sx, int16_t sy, char* filepath) {
+
+    BITMAPFILEHEADER bf;
+    BITMAPINFO bmi;
+
+    uint32_t bytes_read=0;
+
+    if (!isThisFileOpen(filepath)) {
+        fileClose(); // close any open files
+        fileOpen(filepath, FILE_MODE_READONLY | FILE_MODE_BINARY);
+    }
+    else {
+        POK_TRACE("Error! Already open\n");
+        return -1;  // Already open, not good.
+    }
+
+    if (fileOK() && fileReadBytes((uint8_t*)&bf, sizeof(bf)) == sizeof(bf) ) {  //!HV why we have to check fileOK()?
+        bytes_read += sizeof(bf);
+    }
+	else
+	{
+		POK_TRACE("Error reading BMP header\n");
+		fileClose();
+		return(-1);
+	}
+
+    if (fileReadBytes((uint8_t*)&bmi,sizeof(bmi.bmiHeader)) != sizeof(bmi.bmiHeader)) {
+		POK_TRACE("Error reading BMP info\n");
+		fileClose();
+		return(-1);
+	}
+    bytes_read += sizeof(bmi.bmiHeader);
+
+    /** Check image validity */
+
+    if (bf.bfType != 0x4D42) {
+        POK_TRACE("Bitmap file has an unrecognized format (4D42 id missing from beginning).\n");
+        POK_TRACE("BMP2POK accepts .BMP files that have an indexed (1,-bit, 4-bit or 8-bit) color palette.\n");
+        fileClose();
+        return(-1);
+    }
+    if (bmi.bmiHeader.biBitCount != 24 ) {
+        POK_TRACE("ERROR!\nThe image color depth should be the same as screen color depth (%d)!\n");
+		fileClose();
+        return(-1);
+    }
+    if (bmi.bmiHeader.biCompression != 0 )
+    {
+        POK_TRACE("Compression is not supported.\n");
+        fileClose();
+        return(-1);
+    }
+
+    /* If the height is negative the bmp image is in the correct way.
+       If the heigh is positive the bmp image is vertically mirrored
+    */
+    int biAbsHeight = bmi.bmiHeader.biHeight;
+    if (bmi.bmiHeader.biHeight < 0 )
+        biAbsHeight = - bmi.bmiHeader.biHeight;
+
+    /** Zero size parameter means full image size */
+    if(iw==0) iw = bmi.bmiHeader.biWidth; // 0 means full image width
+    if(ih==0) ih = biAbsHeight; // 0 means full image width
+
+    /** Check parameters */
+    if( ix + iw > bmi.bmiHeader.biWidth ) {
+        POK_TRACE("Error! Invalid parameter\n");
+		fileClose();
+        return(-1);
+    }
+    if( iy + ih > biAbsHeight ) {
+        POK_TRACE("Error! Invalid parameter\n");
+ 		fileClose();
+        return(-1);
+    }
+    if( sx > pokdisp.getWidth()-1 || sx<-iw) {
+        POK_TRACE("Error! Invalid parameter\n");
+ 		fileClose();
+        return(-1);
+    }
+    if( sy > pokdisp.getHeight()-1  || sy<-ih) {
+        POK_TRACE("Error! Invalid parameter\n");
+		fileClose();
+        return(-1);
+    }
+
+    /** Zero size parameter means full image size */
+    if(iw==0) iw = bmi.bmiHeader.biWidth; // 0 means full image width
+    if(ih==0) ih = biAbsHeight; // 0 means full image width
+
+    /** Clip image to screen dimensions */
+
+    int16_t clipX1OnScreen = max( 0, sx);
+    int16_t clipX2OnScreen = min( pokdisp.getWidth()-1, sx+iw-1);
+    int16_t clipWidthOnScreen = clipX2OnScreen-clipX1OnScreen+1;
+    int16_t clipY1OnScreen = max( 0, sy);
+    int16_t clipY2OnScreen = min( pokdisp.getHeight()-1, sy+ih-1);
+    int16_t clipHeightOnScreen = clipY2OnScreen-clipY1OnScreen+1;
+
+    uint16_t skipImagePixelsAtLineStart = ix+(clipX1OnScreen-sx);
+    uint16_t skipImagePixelsAtLineStartAsBytes = skipImagePixelsAtLineStart*3; // 3 bytes per pixel
+    uint16_t skipImagePixelsAtLineEndAsBytes = (bmi.bmiHeader.biWidth-(skipImagePixelsAtLineStart+clipWidthOnScreen))*3; // 3 bytes per pixel
+
+    uint16_t skipImageRowsAtImageStart = iy+(clipY1OnScreen-sy);
+    uint16_t skipImageRowsAtImageEnd = biAbsHeight-(skipImageRowsAtImageStart+clipHeightOnScreen);
+
+	/* Vertical loop parameters */
+    int incY, startY, pastEndY;
+    uint32_t skipImageRowsAsBytes = 0;
+    if (bmi.bmiHeader.biHeight > 0 ) {
+        /* Mirror vertically */
+        incY = -1;
+        startY = clipY2OnScreen;
+        pastEndY = clipY1OnScreen-1;
+        skipImageRowsAsBytes = skipImageRowsAtImageEnd*bmi.bmiHeader.biWidth*3; // 3 bytes per pixel
+    }
+    else {
+        /* Do not mirror */
+        incY = 1;
+        startY = clipY1OnScreen ;
+        pastEndY = clipY2OnScreen+1;
+        skipImageRowsAsBytes = skipImageRowsAtImageStart*bmi.bmiHeader.biWidth*3; // 3 bytes per pixel
+    }
+
+    /** Read and copy image data directly to the screen **/
+
+    /* Seek to the beginning of the data */
+	fileSeekAbsolute(bf.bfOffBits);
+
+    /* Seek until the image rect starts */
+    if (skipImageRowsAsBytes>0) fileSeekRelative( skipImageRowsAsBytes );
+
+    /* Copy all bytes to the output bitmap */
+    for ( int y = startY; y != pastEndY; y += incY) {
+
+         /* Seek until the image rect starts */
+        if (skipImagePixelsAtLineStartAsBytes>0) fileSeekRelative( skipImagePixelsAtLineStartAsBytes );
+
+        for ( int x = clipX1OnScreen; x <= clipX2OnScreen; x++) {
+
+            /* Read RGB pixel from the file. For 24 bpp the pixel is stored to 3 bytes*/
+            uint32_t rgb24;
+            if (fileReadBytes((uint8_t*)&rgb24, 3) != 3)
+            {
+                POK_TRACE("Error reading BMP data\n");
+                fileClose();
+                return(-1);
+            }
+
+            /* Copy a pixel from the file directly to the screen */
+//            uint8_t r,g,b;
+//            r = (xrgb >> (3 + 16))  & 0x1f; // 5 bit
+//            g = (xrgb >> (2 + 8))   & 0x3f; // 6 bits
+//            b = (xrgb >> 3)         & 0x1f; // 5 bits
+//            uint16_t targetpixel = (r<<11) | (g<<5) | b;
+
+            uint16_t targetpixel =
+               ((rgb24 >> 8) & 0x0000F800) |  // red (bits 15-11)
+               ((rgb24 >> 5) & 0x000007E0) |  // green (bits 10-5)
+               ((rgb24 >> 3) & 0x0000001F);  // blue (bits 4-0)
+            _game.display.directPixel(x, y, targetpixel);
+        } // end for
+
+        /* Skip pixels at line end */
+        if (skipImagePixelsAtLineEndAsBytes>0) fileSeekRelative( skipImagePixelsAtLineEndAsBytes );
+
+    } // end for
+
+	// Done with the file reading.
+	fileClose();
+
+    return 0;
+}
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/POKITTO_LIBS/ImageFormat/ImageFormat.h	Fri Dec 29 05:17:10 2017 +0000
@@ -0,0 +1,37 @@
+/**************************************************************************/
+/*!
+    @file     ImageFormat.h
+    @author   Hannu Viitala
+
+    @section LICENSE
+
+    Pokitto development stage library
+    Software License Agreement
+
+    Copyright (c) 2015, Jonne Valola ("Author")
+    All rights reserved.
+
+    This library is intended solely for the purpose of Pokitto development.
+
+    Redistribution and use in source and binary forms, with or without
+    modification requires written permission from Author.
+*/
+/**************************************************************************/
+
+#ifndef IMAGE_FORMAT_H
+
+#define POK_TRACE(str) printf("%s (%d): %s", __FILE__, __LINE__,str)
+
+extern int openImageFileFromSD(char*, uint16_t **, uint8_t **);
+extern int directDrawImageFileFromSD(int16_t /*sx*/, int16_t /*sy*/, char* /*filepath*/);
+extern int directDrawImageFileFromSD(uint16_t /*ix*/, uint16_t /*iy*/, uint16_t /*iw*/, uint16_t /*ih*/, int16_t /*sx*/, int16_t /*sy*/, char* /*filepath*/);
+
+#define IMAGE_FORMAT_H
+
+
+#ifndef boolean
+//typedef bool boolean;
+#endif
+
+#endif // IMAGE_FORMAT_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/POKITTO_LIBS/ImageFormat/defines_linux_SIM.h	Fri Dec 29 05:17:10 2017 +0000
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include "helpers.h"
+
+#define _MAX_DRIVE	3
+#define _MAX_DIR	256
+#define _MAX_FNAME	256
+#define _MAX_EXT	256
+
+#include <ctype.h>
+
+char* _strupr( char* s )
+  {
+  char* p = s;
+  while (*p = toupper( *p )) p++;
+  return s;
+  }
+
+typedef struct tagRGBQUAD {
+  uint8_t rgbBlue;
+  uint8_t rgbGreen;
+  uint8_t rgbRed;
+  uint8_t rgbReserved;
+} RGBQUAD;
+
+typedef struct tagBITMAPFILEHEADER {
+  int16_t  bfType;
+  int32_t  bfSize;
+  int16_t  bfReserved1;
+  int16_t  bfReserved2;
+  int32_t  bfOffBits;
+} __attribute__((packed)) BITMAPFILEHEADER, *PBITMAPFILEHEADER;
+
+#define BI_RLE4 2
+typedef struct tagBITMAPINFOHEADER {
+  int32_t biSize;
+  int32_t  biWidth;
+  int32_t  biHeight;
+  int16_t  biPlanes;
+  int16_t  biBitCount;
+  int32_t biCompression;
+  int32_t biSizeImage;
+  int32_t biXPelsPerMeter;
+  int32_t  biYPelsPerMeter;
+  int32_t biClrUsed;
+  int32_t biClrImportant;
+} __attribute__((packed)) BITMAPINFOHEADER, *PBITMAPINFOHEADER;
+
+typedef struct tagBITMAPINFO {
+  BITMAPINFOHEADER bmiHeader;
+  RGBQUAD          bmiColors[1];
+} __attribute__((packed)) BITMAPINFO, *PBITMAPINFO;
+
+RGBQUAD myColors[257];
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/POKITTO_LIBS/ImageFormat/defines_win_SIM.h	Fri Dec 29 05:17:10 2017 +0000
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "windows.h"
+#include <stdint.h>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/POKITTO_LIBS/ImageFormat/helpers.h	Fri Dec 29 05:17:10 2017 +0000
@@ -0,0 +1,10 @@
+#ifndef HELPERS_H
+#define HELPERS_H
+
+extern void add_underscores(char *);
+extern void print_usage(char *);
+
+
+#endif // HELPERS_H
+
+
--- a/Pokitto_settings.h	Fri Dec 29 02:55:34 2017 +0000
+++ b/Pokitto_settings.h	Fri Dec 29 05:17:10 2017 +0000
@@ -382,5 +382,9 @@
 /** LOADER UPDATE MECHANISM **/
 #define POK_ENABLE_LOADER_UPDATES 1 //1=check for new loader versions on SD and update if new found
 
+#ifndef SPRITE_COUNT
+#define SPRITE_COUNT 4  // The default max sprite count
+#endif
+
 #endif // POKITTO_SETTINGS_H