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

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

PokittoLib

Library for programming Pokitto hardware

How to Use

  1. Import this library to online compiler (see button "import" on the right hand side
  2. DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
  3. Change My_settings.h according to your project
  4. Start coding!
Committer:
Pokitto
Date:
Sat Oct 21 17:22:35 2017 +0000
Revision:
17:10609a82d462
Parent:
13:680e1a8cdd8b
New bootloader system!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pokitto 6:72f87b7c7400 1 /**************************************************************************/
Pokitto 6:72f87b7c7400 2 /*!
Pokitto 6:72f87b7c7400 3 @file PokittoCore.cpp
Pokitto 6:72f87b7c7400 4 @author Jonne Valola
Pokitto 6:72f87b7c7400 5
Pokitto 6:72f87b7c7400 6 @section LICENSE
Pokitto 6:72f87b7c7400 7
Pokitto 6:72f87b7c7400 8 Software License Agreement (BSD License)
Pokitto 6:72f87b7c7400 9
Pokitto 6:72f87b7c7400 10 Copyright (c) 2016, Jonne Valola
Pokitto 6:72f87b7c7400 11 All rights reserved.
Pokitto 6:72f87b7c7400 12
Pokitto 6:72f87b7c7400 13 Redistribution and use in source and binary forms, with or without
Pokitto 6:72f87b7c7400 14 modification, are permitted provided that the following conditions are met:
Pokitto 6:72f87b7c7400 15 1. Redistributions of source code must retain the above copyright
Pokitto 6:72f87b7c7400 16 notice, this list of conditions and the following disclaimer.
Pokitto 6:72f87b7c7400 17 2. Redistributions in binary form must reproduce the above copyright
Pokitto 6:72f87b7c7400 18 notice, this list of conditions and the following disclaimer in the
Pokitto 6:72f87b7c7400 19 documentation and/or other materials provided with the distribution.
Pokitto 6:72f87b7c7400 20 3. Neither the name of the copyright holders nor the
Pokitto 6:72f87b7c7400 21 names of its contributors may be used to endorse or promote products
Pokitto 6:72f87b7c7400 22 derived from this software without specific prior written permission.
Pokitto 6:72f87b7c7400 23
Pokitto 6:72f87b7c7400 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
Pokitto 6:72f87b7c7400 25 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Pokitto 6:72f87b7c7400 26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Pokitto 6:72f87b7c7400 27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
Pokitto 6:72f87b7c7400 28 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Pokitto 6:72f87b7c7400 29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Pokitto 6:72f87b7c7400 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
Pokitto 6:72f87b7c7400 31 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Pokitto 6:72f87b7c7400 32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Pokitto 6:72f87b7c7400 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Pokitto 6:72f87b7c7400 34 */
Pokitto 6:72f87b7c7400 35 /**************************************************************************/
Pokitto 6:72f87b7c7400 36
Pokitto 6:72f87b7c7400 37 #include "PokittoCore.h"
Pokitto 6:72f87b7c7400 38 #include "Pokitto_settings.h"
Pokitto 6:72f87b7c7400 39 #include "PokittoConsole.h"
Pokitto 6:72f87b7c7400 40 #include "PokittoFonts.h"
Pokitto 6:72f87b7c7400 41 #include "PokittoTimer.h"
Pokitto 6:72f87b7c7400 42 #include "PokittoLogos.h"
Pokitto 6:72f87b7c7400 43 #include <stdlib.h>
Pokitto 6:72f87b7c7400 44 #ifndef DISABLEAVRMIN
Pokitto 6:72f87b7c7400 45 #define max(a,b) ((a)>(b)?(a):(b))
Pokitto 6:72f87b7c7400 46 #endif // DISABLEAVRMIN
Pokitto 6:72f87b7c7400 47
Pokitto 6:72f87b7c7400 48 char selectedfile[25];
Pokitto 6:72f87b7c7400 49
Pokitto 6:72f87b7c7400 50 //#define F
Pokitto 6:72f87b7c7400 51 #ifdef __ARMCC_VERSION
Pokitto 6:72f87b7c7400 52 typedef void (*func_t)(void);
Pokitto 6:72f87b7c7400 53 #endif
Pokitto 6:72f87b7c7400 54
Pokitto 6:72f87b7c7400 55 #ifndef POK_SIM
Pokitto 17:10609a82d462 56 #include "iap.h"
Pokitto 6:72f87b7c7400 57 /** start the user application
Pokitto 6:72f87b7c7400 58 * https://community.nxp.com/thread/417695
Pokitto 6:72f87b7c7400 59 *
Pokitto 6:72f87b7c7400 60 */
Pokitto 6:72f87b7c7400 61 void start_application(unsigned long app_link_location){
Pokitto 6:72f87b7c7400 62 //asm(" ldr sp, [r0,#0]");
Pokitto 6:72f87b7c7400 63 //asm(" ldr pc, [r0,#4]");
Pokitto 6:72f87b7c7400 64 //This code is not valid for the Cortex-m0+ instruction set.
Pokitto 6:72f87b7c7400 65 // The equivalent for this (as used by the KL26) is
Pokitto 6:72f87b7c7400 66 __disable_irq();// Start by disabling interrupts, before changing interrupt vectors
Pokitto 6:72f87b7c7400 67
Pokitto 6:72f87b7c7400 68 // delete buttons
Pokitto 6:72f87b7c7400 69 //pokDeleteButtons();
Pokitto 6:72f87b7c7400 70
Pokitto 6:72f87b7c7400 71 // completely kill button interrupts in preparation for reset
Pokitto 6:72f87b7c7400 72 LPC_PINT->IENR = 0;
Pokitto 6:72f87b7c7400 73 LPC_PINT->IENF = 0;
Pokitto 6:72f87b7c7400 74
Pokitto 6:72f87b7c7400 75 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk & ~(SysTick_CTRL_ENABLE_Msk); //disable systick
Pokitto 6:72f87b7c7400 76 LPC_SYSCON->PDRUNCFG |= (1 << 10); /* Power-down USB PHY */
Pokitto 6:72f87b7c7400 77 LPC_SYSCON->PDRUNCFG |= (1 << 8); /* Power-down USB PLL */
Pokitto 6:72f87b7c7400 78
Pokitto 6:72f87b7c7400 79 // reset clock source to IRC
Pokitto 6:72f87b7c7400 80 LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */
Pokitto 6:72f87b7c7400 81 LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */
Pokitto 6:72f87b7c7400 82 while (LPC_SYSCON->MAINCLKUEN & 0x01); /* Wait Until Updated */
Pokitto 6:72f87b7c7400 83 // switch clock selection to IRC
Pokitto 6:72f87b7c7400 84 LPC_SYSCON->MAINCLKSEL = 0; /* Select Clock Source */
Pokitto 6:72f87b7c7400 85 LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */
Pokitto 6:72f87b7c7400 86 LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */
Pokitto 6:72f87b7c7400 87 while (LPC_SYSCON->MAINCLKUEN & 0x01); /* Wait Until Updated */
Pokitto 6:72f87b7c7400 88 //disable PLL clock output
Pokitto 6:72f87b7c7400 89 LPC_SYSCON->SYSPLLCLKUEN = 0;
Pokitto 6:72f87b7c7400 90 while (LPC_SYSCON->SYSPLLCLKUEN & 0x00);
Pokitto 6:72f87b7c7400 91 LPC_SYSCON->SYSPLLCTRL = 0;
Pokitto 6:72f87b7c7400 92
Pokitto 6:72f87b7c7400 93 //kill peripherals
Pokitto 6:72f87b7c7400 94 LPC_SYSCON->MAINCLKSEL = 0;
Pokitto 6:72f87b7c7400 95 LPC_SYSCON->PRESETCTRL = 0; //disable all peripherals
Pokitto 6:72f87b7c7400 96
Pokitto 6:72f87b7c7400 97 //power down PLL
Pokitto 6:72f87b7c7400 98 volatile uint32_t tmp;
Pokitto 6:72f87b7c7400 99 tmp = (LPC_SYSCON->PDRUNCFG & 0x000025FFL);
Pokitto 6:72f87b7c7400 100 tmp |= ((1<<7) & 0x000025FFL);
Pokitto 6:72f87b7c7400 101 LPC_SYSCON->PDRUNCFG = (tmp | 0x0000C800L); /* Power-down SYSPLL */
Pokitto 6:72f87b7c7400 102
Pokitto 6:72f87b7c7400 103 //Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_IRC); //switch to IRC
Pokitto 6:72f87b7c7400 104
Pokitto 6:72f87b7c7400 105 // clear all gpio states
Pokitto 6:72f87b7c7400 106 LPC_GPIO_PORT->PIN[0] = 0;
Pokitto 6:72f87b7c7400 107 LPC_GPIO_PORT->PIN[1] = 0;
Pokitto 6:72f87b7c7400 108 LPC_GPIO_PORT->PIN[2] = 0;
Pokitto 6:72f87b7c7400 109
Pokitto 6:72f87b7c7400 110 SCB->VTOR = app_link_location;//APPL_ADDRESS; /* Change vector table address */
Pokitto 6:72f87b7c7400 111 #ifndef __ARMCC_VERSION
Pokitto 6:72f87b7c7400 112 asm(" mov r0, %[address]"::[address] "r" (app_link_location));
Pokitto 6:72f87b7c7400 113 asm(" ldr r1, [r0,#0]"); // get the stack pointer value from the program's reset vector
Pokitto 6:72f87b7c7400 114 asm(" mov sp, r1"); // copy the value to the stack pointer
Pokitto 6:72f87b7c7400 115 asm(" ldr r0, [r0,#4]"); // get the program counter value from the program's reset vector
Pokitto 6:72f87b7c7400 116 asm(" blx r0"); // jump to the' start address
Pokitto 6:72f87b7c7400 117 #else
Pokitto 6:72f87b7c7400 118 uint32_t *app_loc = (uint32_t*)app_link_location;
Pokitto 6:72f87b7c7400 119 __set_MSP (app_loc[0]);
Pokitto 6:72f87b7c7400 120 ((func_t)(app_loc[1]))();
Pokitto 6:72f87b7c7400 121 #endif
Pokitto 6:72f87b7c7400 122 }
Pokitto 6:72f87b7c7400 123 #endif
Pokitto 6:72f87b7c7400 124
Pokitto 6:72f87b7c7400 125 // returns a random integar between 0 and maxVal
Pokitto 6:72f87b7c7400 126 int random(int maxVal)
Pokitto 6:72f87b7c7400 127 {
Pokitto 6:72f87b7c7400 128 return random( 0, maxVal);
Pokitto 6:72f87b7c7400 129 }
Pokitto 6:72f87b7c7400 130
Pokitto 6:72f87b7c7400 131 // returns a random integar between minVal and maxVal
Pokitto 6:72f87b7c7400 132 int random(int minVal, int maxVal)
Pokitto 6:72f87b7c7400 133 {
Pokitto 6:72f87b7c7400 134 // int rand(void); included by default from newlib
Pokitto 6:72f87b7c7400 135 return rand() % (maxVal-minVal+1) + minVal;
Pokitto 6:72f87b7c7400 136 }
Pokitto 6:72f87b7c7400 137
Pokitto 6:72f87b7c7400 138 using namespace Pokitto;
Pokitto 6:72f87b7c7400 139
Pokitto 6:72f87b7c7400 140 bool Core::run_state; // this definition needed
Pokitto 6:72f87b7c7400 141
Pokitto 6:72f87b7c7400 142 /** Components */
Pokitto 6:72f87b7c7400 143 Backlight Core::backlight;
Pokitto 6:72f87b7c7400 144 Buttons Core::buttons;
Pokitto 6:72f87b7c7400 145 Battery Core::battery;
Pokitto 6:72f87b7c7400 146 #if POK_ENABLE_SOUND > 0
Pokitto 6:72f87b7c7400 147 Sound Core::sound;
Pokitto 6:72f87b7c7400 148 #endif
Pokitto 6:72f87b7c7400 149 Display Core::display;
Pokitto 6:72f87b7c7400 150
Pokitto 6:72f87b7c7400 151 //GB Related
Pokitto 6:72f87b7c7400 152 uint8_t Core::startMenuTimer;
Pokitto 6:72f87b7c7400 153 uint8_t Core::timePerFrame;
Pokitto 6:72f87b7c7400 154 uint32_t Core::nextFrameMillis;
Pokitto 6:72f87b7c7400 155 uint32_t Core::frameCount;
Pokitto 6:72f87b7c7400 156 const char* Core::popupText;
Pokitto 6:72f87b7c7400 157 uint8_t Core::popupTimeLeft;
Pokitto 6:72f87b7c7400 158 uint16_t Core::frameDurationMicros;
Pokitto 6:72f87b7c7400 159 uint32_t Core::frameStartMicros, Core::frameEndMicros;
Pokitto 6:72f87b7c7400 160 uint8_t Core::volbar_visible=0;
Pokitto 6:72f87b7c7400 161
Pokitto 6:72f87b7c7400 162
Pokitto 6:72f87b7c7400 163 Core::Core() {
Pokitto 6:72f87b7c7400 164
Pokitto 6:72f87b7c7400 165 }
Pokitto 6:72f87b7c7400 166
Pokitto 17:10609a82d462 167
Pokitto 17:10609a82d462 168 int Core::updateLoader (uint32_t version, uint32_t jumpaddress) {
Pokitto 17:10609a82d462 169 uint32_t counter=0;
Pokitto 17:10609a82d462 170 uint8_t data[256];
Pokitto 17:10609a82d462 171 /** prepare the flash writing **/
Pokitto 17:10609a82d462 172 float progress=0;
Pokitto 17:10609a82d462 173 int opg=-1;
Pokitto 17:10609a82d462 174 uint32_t fsize=0;
Pokitto 17:10609a82d462 175 fileEnd(); //
Pokitto 17:10609a82d462 176 fsize = fileGetPosition();
Pokitto 17:10609a82d462 177 if (fsize>0x40000-jumpaddress) fsize = 0x40000-jumpaddress; // shouldn't happen!!
Pokitto 17:10609a82d462 178 fileRewind();
Pokitto 17:10609a82d462 179
Pokitto 17:10609a82d462 180 while (1) {
Pokitto 17:10609a82d462 181 if (counter >= fsize) break;
Pokitto 17:10609a82d462 182 opg=progress;
Pokitto 17:10609a82d462 183 if (fileReadBytes(&data[0],0x100)<0x100) {
Pokitto 17:10609a82d462 184 if (fsize-counter>0x100) {
Pokitto 17:10609a82d462 185 display.println("ERROR READING LOA.DER FILE");
Pokitto 17:10609a82d462 186 return 1; // 1 means error
Pokitto 17:10609a82d462 187 }
Pokitto 17:10609a82d462 188 }
Pokitto 17:10609a82d462 189 if (CopyPageToFlash(jumpaddress+counter,data)) {
Pokitto 17:10609a82d462 190 display.println("FLASH WRITE ERROR");
Pokitto 17:10609a82d462 191 return 1;
Pokitto 17:10609a82d462 192 } else {
Pokitto 17:10609a82d462 193 counter += 0x100;
Pokitto 17:10609a82d462 194 display.print(".");
Pokitto 17:10609a82d462 195 }
Pokitto 17:10609a82d462 196 }
Pokitto 17:10609a82d462 197 return 0; //success
Pokitto 17:10609a82d462 198 }
Pokitto 17:10609a82d462 199
Pokitto 6:72f87b7c7400 200 void Core::showWarning() {
Pokitto 6:72f87b7c7400 201 display.enableDirectPrinting(true);
Pokitto 6:72f87b7c7400 202 display.directbgcolor = COLOR_BLACK;
Pokitto 6:72f87b7c7400 203 display.clearLCD();
Pokitto 6:72f87b7c7400 204 display.directcolor = COLOR_RED;
Pokitto 6:72f87b7c7400 205 display.setFont(fntC64UIGfx);
Pokitto 6:72f87b7c7400 206 display.adjustCharStep = 0;
Pokitto 6:72f87b7c7400 207 display.adjustLineStep = 0;
Pokitto 6:72f87b7c7400 208 display.setCursor(10*8,9);
Pokitto 6:72f87b7c7400 209 display.print("WARNING!");
Pokitto 6:72f87b7c7400 210 display.directcolor = COLOR_WHITE;
Pokitto 6:72f87b7c7400 211 display.setCursor(5*8,4*9);
Pokitto 6:72f87b7c7400 212 display.print("LOUD SOUND THROUGH");
Pokitto 6:72f87b7c7400 213 display.setCursor(2*8,5*9);
Pokitto 6:72f87b7c7400 214 display.print("HEADPHONES COULD DAMAGE");
Pokitto 6:72f87b7c7400 215 display.setCursor(7*8,6*9);
Pokitto 6:72f87b7c7400 216 display.print("YOUR HEARING.");
Pokitto 6:72f87b7c7400 217 display.setCursor(5*8,8*9);
Pokitto 6:72f87b7c7400 218 display.print("USE "); display.directcolor = COLOR_GREEN;
Pokitto 6:72f87b7c7400 219 display.print("0-100% VOLUME");
Pokitto 6:72f87b7c7400 220 display.directcolor = COLOR_WHITE;
Pokitto 6:72f87b7c7400 221 display.setCursor(5*8,9*9);
Pokitto 6:72f87b7c7400 222 display.print("FOR LISTENING WITH");
Pokitto 6:72f87b7c7400 223 display.setCursor(8*8,10*9);
Pokitto 6:72f87b7c7400 224 display.print("HEADPHONES");
Pokitto 6:72f87b7c7400 225 display.setCursor(5*8,12*9);
Pokitto 6:72f87b7c7400 226 display.print("USE "); display.directcolor = COLOR_RED;
Pokitto 6:72f87b7c7400 227 display.print("> 100% VOLUME"); display.directcolor = COLOR_GREEN;
Pokitto 6:72f87b7c7400 228 display.directcolor = COLOR_WHITE;
Pokitto 6:72f87b7c7400 229 display.setCursor(1*8,13*9);
Pokitto 6:72f87b7c7400 230 display.print("ONLY FOR LISTENING VIA THE");
Pokitto 6:72f87b7c7400 231 display.setCursor(5*8,14*9);
Pokitto 6:72f87b7c7400 232 display.print("BUILT-IN SPEAKER");
Pokitto 6:72f87b7c7400 233 display.setCursor(5*8,17*9);
Pokitto 6:72f87b7c7400 234 display.print("PRESS ");display.directcolor = COLOR_GREEN;
Pokitto 6:72f87b7c7400 235 display.print("C ");display.directcolor = COLOR_WHITE;
Pokitto 6:72f87b7c7400 236 display.print("TO ACCEPT");
Pokitto 6:72f87b7c7400 237 while (!buttons.cBtn()) {
Pokitto 6:72f87b7c7400 238 wait(100);
Pokitto 6:72f87b7c7400 239 }
Pokitto 6:72f87b7c7400 240 display.clearLCD();
Pokitto 6:72f87b7c7400 241 display.enableDirectPrinting(false);
Pokitto 6:72f87b7c7400 242 }
Pokitto 6:72f87b7c7400 243
Pokitto 6:72f87b7c7400 244 void Core::jumpToLoader() {
Pokitto 17:10609a82d462 245 display.setFont(font5x7);
Pokitto 17:10609a82d462 246 display.adjustCharStep=1;
Pokitto 17:10609a82d462 247 display.adjustLineStep=1;
Pokitto 6:72f87b7c7400 248 display.fontSize=1;
Pokitto 6:72f87b7c7400 249 display.directbgcolor=COLOR_BLACK;
Pokitto 6:72f87b7c7400 250 display.directcolor=COLOR_GREEN;
Pokitto 17:10609a82d462 251 display.clearLCD();
Pokitto 6:72f87b7c7400 252 display.setCursor(0,0);
Pokitto 6:72f87b7c7400 253 display.enableDirectPrinting(true);
Pokitto 6:72f87b7c7400 254 #ifdef POK_SIM
Pokitto 6:72f87b7c7400 255 display.println("LOADER IS NOT AVAILABLE ON THE SIMULATOR. PRESS A TO RETURN.");
Pokitto 6:72f87b7c7400 256 #else
Pokitto 6:72f87b7c7400 257 uint32_t* bootinfo;
Pokitto 17:10609a82d462 258 uint32_t bootversion=0, sdversion=0, sdjump=0;
Pokitto 17:10609a82d462 259 bool flashloader=false, checkforboot=true;
Pokitto 17:10609a82d462 260 //check for loa.der on SD card
Pokitto 17:10609a82d462 261 #if POK_ENABLE_LOADER_UPDATES > 0
Pokitto 17:10609a82d462 262 pokInitSD();
Pokitto 17:10609a82d462 263 if (fileOpen("LOA.DER", FILE_MODE_BINARY)==0) {
Pokitto 17:10609a82d462 264 //LOA.DER found on SD
Pokitto 17:10609a82d462 265 fileEnd(); // go to end
Pokitto 17:10609a82d462 266 fileSeekRelative(-8); //rewind 8 bytes
Pokitto 17:10609a82d462 267 uint32_t* tptr = &sdversion;
Pokitto 17:10609a82d462 268 fileReadBytes((uint8_t*)tptr,4); //read version number of loader on SD card
Pokitto 17:10609a82d462 269 tptr = &sdjump;
Pokitto 17:10609a82d462 270 fileReadBytes((uint8_t*)tptr,4); //read jump address of loader on sd card
Pokitto 17:10609a82d462 271 fileRewind();
Pokitto 17:10609a82d462 272 }
Pokitto 17:10609a82d462 273 #endif
Pokitto 17:10609a82d462 274 //now start searching for bootkey
Pokitto 17:10609a82d462 275 while (checkforboot)
Pokitto 17:10609a82d462 276 {
Pokitto 17:10609a82d462 277 checkforboot=false; flashloader=false;
Pokitto 17:10609a82d462 278 bootinfo = (uint32_t*)0x3FFF4;
Pokitto 17:10609a82d462 279 if (*bootinfo != 0xB007AB1E) bootinfo = (uint32_t*)0x3FF04; //allow couple of alternative locations
Pokitto 17:10609a82d462 280 if (*bootinfo != 0xB007AB1E) bootinfo = (uint32_t*)0x3FE04; //allow couple of alternative locations
Pokitto 17:10609a82d462 281 if (*bootinfo != 0xB007AB1E) bootinfo = (uint32_t*)0x3F004; //for futureproofing
Pokitto 13:680e1a8cdd8b 282 if (*bootinfo != 0xB007AB1E) {
Pokitto 17:10609a82d462 283 // no bootkey found at all
Pokitto 17:10609a82d462 284 display.println("NO LOADER RESIDENT");
Pokitto 17:10609a82d462 285 if (sdversion==0 || sdjump < 0x38000) {
Pokitto 17:10609a82d462 286 //file open of loader failed
Pokitto 17:10609a82d462 287 display.println("NO VALID LOA.DER FOUND ON SD");
Pokitto 17:10609a82d462 288 display.println("");
Pokitto 17:10609a82d462 289 display.println("PUT A GOOD LOA.DER ON SD & REBOOT");
Pokitto 17:10609a82d462 290 } else flashloader=true;
Pokitto 17:10609a82d462 291 } else {
Pokitto 17:10609a82d462 292 //loader was found
Pokitto 17:10609a82d462 293 //check if we should update the loader
Pokitto 17:10609a82d462 294 #if POK_ENABLE_LOADER_UPDATES > 0
Pokitto 17:10609a82d462 295 if (sdversion>(*(bootinfo+1))) flashloader=true;
Pokitto 17:10609a82d462 296 else start_application(*(bootinfo+2)); //never returns
Pokitto 17:10609a82d462 297 #else
Pokitto 17:10609a82d462 298 start_application(*(bootinfo+2)); //never returns
Pokitto 17:10609a82d462 299 #endif
Pokitto 13:680e1a8cdd8b 300 }
Pokitto 17:10609a82d462 301 // update loader if it was requested
Pokitto 17:10609a82d462 302 if(flashloader) {
Pokitto 17:10609a82d462 303 display.println("UPDATE LOADER? (UP=YES, DOWN=CANCEL)");
Pokitto 17:10609a82d462 304 while(1) {
Pokitto 17:10609a82d462 305 if (buttons.upBtn()) {
Pokitto 17:10609a82d462 306 if (updateLoader(sdversion,sdjump)) {
Pokitto 17:10609a82d462 307 display.println("PUT VALID LOA.DER ON SD AND TRY AGAIN");
Pokitto 17:10609a82d462 308 } else {
Pokitto 17:10609a82d462 309 display.println("SUCCESS!!");
Pokitto 17:10609a82d462 310 checkforboot=true; //recheck
Pokitto 17:10609a82d462 311 }
Pokitto 17:10609a82d462 312 break;
Pokitto 17:10609a82d462 313 }
Pokitto 17:10609a82d462 314 if (buttons.downBtn()) return;
Pokitto 17:10609a82d462 315 }
Pokitto 17:10609a82d462 316 } // if flashloader
Pokitto 17:10609a82d462 317 } // while checkforboot
Pokitto 6:72f87b7c7400 318 #endif // POK_SIM
Pokitto 6:72f87b7c7400 319 while (!buttons.aBtn()) {
Pokitto 6:72f87b7c7400 320 buttons.pollButtons();
Pokitto 6:72f87b7c7400 321 if (buttons.aBtn()) {
Pokitto 6:72f87b7c7400 322 while (buttons.aBtn()) {
Pokitto 6:72f87b7c7400 323 buttons.pollButtons();
Pokitto 6:72f87b7c7400 324 }
Pokitto 6:72f87b7c7400 325 return;
Pokitto 6:72f87b7c7400 326 }
Pokitto 6:72f87b7c7400 327 }
Pokitto 6:72f87b7c7400 328 }
Pokitto 6:72f87b7c7400 329
Pokitto 6:72f87b7c7400 330 void Core::askLoader() {
Pokitto 6:72f87b7c7400 331 display.enableDirectPrinting(true);
Pokitto 6:72f87b7c7400 332 display.directbgcolor = COLOR_BLACK;
Pokitto 6:72f87b7c7400 333 display.clearLCD();
Pokitto 6:72f87b7c7400 334 display.directcolor = COLOR_RED;
Pokitto 6:72f87b7c7400 335 display.setFont(fntC64UIGfx);
Pokitto 6:72f87b7c7400 336 display.fontSize=1;
Pokitto 6:72f87b7c7400 337 display.adjustCharStep = 0;
Pokitto 6:72f87b7c7400 338 display.adjustLineStep = 0;
Pokitto 6:72f87b7c7400 339 display.directcolor=COLOR_GREEN;
Pokitto 6:72f87b7c7400 340 display.set_cursor(12*8,6*8);
Pokitto 6:72f87b7c7400 341 display.print("ijkl");
Pokitto 6:72f87b7c7400 342 display.set_cursor(12*8,7*8);
Pokitto 6:72f87b7c7400 343 display.print("mnop");
Pokitto 6:72f87b7c7400 344 display.set_cursor(12*8,8*8);
Pokitto 6:72f87b7c7400 345 display.print("qrst");
Pokitto 6:72f87b7c7400 346 display.set_cursor(12*8,9*8);
Pokitto 6:72f87b7c7400 347 display.print("uvwx");
Pokitto 6:72f87b7c7400 348 display.set_cursor(5*8,12*8);
Pokitto 6:72f87b7c7400 349 display.print("PRESS");
Pokitto 6:72f87b7c7400 350 display.directcolor=COLOR_WHITE;
Pokitto 6:72f87b7c7400 351 display.print(" C ");
Pokitto 6:72f87b7c7400 352 display.directcolor=COLOR_GREEN;
Pokitto 6:72f87b7c7400 353 display.print("FOR LOADER");
Pokitto 6:72f87b7c7400 354 display.directcolor=COLOR_WHITE;
Pokitto 6:72f87b7c7400 355 display.fontSize=2;
Pokitto 6:72f87b7c7400 356 int countd=POK_LOADER_COUNTDOWN; uint16_t c2 = getTime();
Pokitto 6:72f87b7c7400 357 while (countd) {
Pokitto 6:72f87b7c7400 358 buttons.pollButtons();
Pokitto 6:72f87b7c7400 359 display.set_cursor(13*8,15*8);
Pokitto 6:72f87b7c7400 360 display.print(countd);
Pokitto 6:72f87b7c7400 361 if (getTime()>c2+1000) {
Pokitto 6:72f87b7c7400 362 c2=getTime();
Pokitto 6:72f87b7c7400 363 countd--;
Pokitto 6:72f87b7c7400 364 }
Pokitto 6:72f87b7c7400 365 if (cBtn()) {while (cBtn()) buttons.pollButtons();jumpToLoader();countd=0;}
Pokitto 6:72f87b7c7400 366 if (aBtn()) {while (aBtn()) buttons.pollButtons();countd=0;}
Pokitto 6:72f87b7c7400 367 if (bBtn()) {while (bBtn()) buttons.pollButtons();countd=0;}
Pokitto 6:72f87b7c7400 368 }
Pokitto 6:72f87b7c7400 369 display.fontSize=1;
Pokitto 6:72f87b7c7400 370 display.clearLCD();
Pokitto 6:72f87b7c7400 371 display.enableDirectPrinting(false);
Pokitto 6:72f87b7c7400 372 }
Pokitto 6:72f87b7c7400 373
Pokitto 6:72f87b7c7400 374
Pokitto 6:72f87b7c7400 375 void Core::drawvolbar(int x, int y, int level, bool text) {
Pokitto 6:72f87b7c7400 376 uint16_t oldcol = display.directcolor;
Pokitto 6:72f87b7c7400 377 if (text) display.directRectangle(0,0,50,50,COLOR_BLACK);
Pokitto 6:72f87b7c7400 378 display.directcolor = COLOR_GREEN;
Pokitto 6:72f87b7c7400 379 if (text) {
Pokitto 6:72f87b7c7400 380 bool temp = display.isDirectPrintingEnabled();
Pokitto 6:72f87b7c7400 381 display.enableDirectPrinting(true);
Pokitto 6:72f87b7c7400 382 display.print(x-1,y-20,(int)sound.getVolume());
Pokitto 6:72f87b7c7400 383 display.print(" ");
Pokitto 6:72f87b7c7400 384 display.enableDirectPrinting(temp);
Pokitto 6:72f87b7c7400 385 }
Pokitto 6:72f87b7c7400 386 if (level<12) display.directcolor = COLOR_GRAY_80;
Pokitto 6:72f87b7c7400 387 display.directBitmap(x,y,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 388 if (level<24) display.directcolor = COLOR_GRAY_80;
Pokitto 6:72f87b7c7400 389 display.directBitmap(x+8,y,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 390 display.directBitmap(x+8,y-4,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 391 display.directcolor = COLOR_RED;
Pokitto 6:72f87b7c7400 392 if (level<48) display.directcolor = COLOR_GRAY_80;
Pokitto 6:72f87b7c7400 393 display.directBitmap(x+16,y,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 394 display.directBitmap(x+16,y-4,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 395 display.directBitmap(x+16,y-8,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 396
Pokitto 6:72f87b7c7400 397 if (level<96) {
Pokitto 6:72f87b7c7400 398 display.directcolor = COLOR_GRAY_80;
Pokitto 6:72f87b7c7400 399 }
Pokitto 6:72f87b7c7400 400 display.directBitmap(x+24,y,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 401 display.directBitmap(x+24,y-4,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 402 display.directBitmap(x+24,y-8,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 403 display.directBitmap(x+24,y-12,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 404 if (level<160) {
Pokitto 6:72f87b7c7400 405 display.directcolor = COLOR_GRAY_80;
Pokitto 6:72f87b7c7400 406 }
Pokitto 6:72f87b7c7400 407 display.directBitmap(x+32,y,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 408 display.directBitmap(x+32,y-4,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 409 display.directBitmap(x+32,y-8,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 410 display.directBitmap(x+32,y-12,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 411 display.directBitmap(x+32,y-16,Pokitto_volumebar,1,1);
Pokitto 6:72f87b7c7400 412 display.directcolor = oldcol;
Pokitto 6:72f87b7c7400 413 }
Pokitto 6:72f87b7c7400 414
Pokitto 6:72f87b7c7400 415
Pokitto 6:72f87b7c7400 416 #ifdef POK_SIM
Pokitto 6:72f87b7c7400 417 #define VINCMULT 1
Pokitto 6:72f87b7c7400 418 #else
Pokitto 6:72f87b7c7400 419 #define VINCMULT 50
Pokitto 6:72f87b7c7400 420 #endif //POK_SIM
Pokitto 6:72f87b7c7400 421 void Core::setVolLimit() {
Pokitto 6:72f87b7c7400 422 display.enableDirectPrinting(true);
Pokitto 6:72f87b7c7400 423 display.adjustCharStep = 0;
Pokitto 6:72f87b7c7400 424 sound.setMaxVol(VOLUME_HEADPHONE_MAX);
Pokitto 6:72f87b7c7400 425 int dstate=1;
Pokitto 6:72f87b7c7400 426 bool wipe = true;
Pokitto 6:72f87b7c7400 427 float vol = sound.getVolume(); float tvol;
Pokitto 6:72f87b7c7400 428 volbar_visible=0;
Pokitto 6:72f87b7c7400 429 while (core.isRunning() && dstate){
Pokitto 6:72f87b7c7400 430 switch (dstate) {
Pokitto 6:72f87b7c7400 431 case 1:
Pokitto 6:72f87b7c7400 432 //redraw
Pokitto 6:72f87b7c7400 433 if (wipe) {
Pokitto 6:72f87b7c7400 434 display.clearLCD();
Pokitto 6:72f87b7c7400 435 display.directcolor = COLOR_WHITE;
Pokitto 6:72f87b7c7400 436 display.setCursor(4*8,2*8);
Pokitto 6:72f87b7c7400 437 display.print("SELECT VOLUME LIMIT");
Pokitto 6:72f87b7c7400 438 display.setCursor(5*8,17*9);
Pokitto 6:72f87b7c7400 439 display.print("PRESS ");
Pokitto 6:72f87b7c7400 440 display.directcolor = COLOR_GREEN;
Pokitto 6:72f87b7c7400 441 display.print("A");
Pokitto 6:72f87b7c7400 442 display.directcolor = COLOR_WHITE;
Pokitto 6:72f87b7c7400 443 display.print(" TO ACCEPT");
Pokitto 6:72f87b7c7400 444 display.directcolor = COLOR_GREEN;
Pokitto 6:72f87b7c7400 445 // draw frame below first
Pokitto 6:72f87b7c7400 446 display.setCursor(0,11*8);
Pokitto 6:72f87b7c7400 447 display.println(" abbbbbbbbbbbbbbbbbbbbbbbc");
Pokitto 6:72f87b7c7400 448 display.println(" | |");
Pokitto 6:72f87b7c7400 449 display.println(" | |");
Pokitto 6:72f87b7c7400 450 display.println(" | |");
Pokitto 6:72f87b7c7400 451 display.println(" | |");
Pokitto 6:72f87b7c7400 452 display.println(" dbbbbbbbbbbbbbbbbbbbbbbbe");
Pokitto 6:72f87b7c7400 453 } // wipe = true
Pokitto 6:72f87b7c7400 454 display.setCursor(6*8,17*9);
Pokitto 6:72f87b7c7400 455 if (sound.getVolume()-5<=VOLUME_HEADPHONE_MAX) display.directcolor = COLOR_WHITE;
Pokitto 6:72f87b7c7400 456 else display.directcolor = COLOR_RED;
Pokitto 6:72f87b7c7400 457 display.directBitmap(21*8-4,6*8,Pokitto_headphones,1,2);
Pokitto 6:72f87b7c7400 458 display.setCursor(3*8,6*8+6);
Pokitto 6:72f87b7c7400 459 display.print("HEADPHONES");
Pokitto 6:72f87b7c7400 460 display.setCursor(3*8,8*8+2);
Pokitto 6:72f87b7c7400 461 if (sound.getVolume()-8>VOLUME_HEADPHONE_MAX) display.print("TOO LOUD!");
Pokitto 6:72f87b7c7400 462 else display.print("OK ");
Pokitto 6:72f87b7c7400 463 display.directcolor = COLOR_GREEN;
Pokitto 6:72f87b7c7400 464 display.directBitmap(21*8-4,12*8,Pokitto_speaker,1,2);
Pokitto 6:72f87b7c7400 465 display.setCursor(3*8,12*8+6);
Pokitto 6:72f87b7c7400 466 display.print("VOLUME MAX");
Pokitto 6:72f87b7c7400 467 display.setCursor(3*8,14*8+2);
Pokitto 6:72f87b7c7400 468 tvol = (vol/float(VOLUME_HEADPHONE_MAX))*100;
Pokitto 6:72f87b7c7400 469 if (tvol > 100 && tvol < 120) tvol=100;
Pokitto 6:72f87b7c7400 470 if (sound.getVolume()-5>VOLUME_HEADPHONE_MAX) { display.directcolor=COLOR_RED;}
Pokitto 6:72f87b7c7400 471 else display.directcolor=COLOR_GREEN;
Pokitto 6:72f87b7c7400 472 display.print(int(sound.getVolume()));
Pokitto 6:72f87b7c7400 473 //display.print(int(tvol));
Pokitto 6:72f87b7c7400 474 display.print(" ");
Pokitto 6:72f87b7c7400 475 display.directcolor=COLOR_GREEN;
Pokitto 6:72f87b7c7400 476 drawvolbar(14*8,14*8+4+2,sound.getVolume(),false);
Pokitto 6:72f87b7c7400 477 //display.setCursor(1,10);
Pokitto 6:72f87b7c7400 478 //display.print(vol);
Pokitto 6:72f87b7c7400 479 dstate=2; break;
Pokitto 6:72f87b7c7400 480 case 2:
Pokitto 6:72f87b7c7400 481 buttons.pollButtons();
Pokitto 6:72f87b7c7400 482 if (aBtn()) {dstate=0;while(aBtn()){buttons.pollButtons();};break;}
Pokitto 6:72f87b7c7400 483 if (rightBtn()) {
Pokitto 6:72f87b7c7400 484 if (vol >= VOLUME_HEADPHONE_MAX && vol < VOLUME_HEADPHONE_MAX+1 ) vol += 0.00025f*VINCMULT;
Pokitto 6:72f87b7c7400 485 else if (vol >= VOLUME_HEADPHONE_MAX) vol += 0.025f*VINCMULT;
Pokitto 6:72f87b7c7400 486 else vol += 0.05f*VINCMULT;
Pokitto 6:72f87b7c7400 487 if (vol > VOLUME_HEADPHONE_MAX + 20) {
Pokitto 6:72f87b7c7400 488 sound.setMaxVol(VOLUME_SPEAKER_MAX);
Pokitto 6:72f87b7c7400 489 }
Pokitto 6:72f87b7c7400 490 if (vol > VOLUME_SPEAKER_MAX) vol=VOLUME_SPEAKER_MAX;
Pokitto 6:72f87b7c7400 491 sound.setVolume(vol);
Pokitto 6:72f87b7c7400 492 dstate=1; wipe=false;
Pokitto 6:72f87b7c7400 493 break;
Pokitto 6:72f87b7c7400 494 }
Pokitto 6:72f87b7c7400 495 if (leftBtn()) {
Pokitto 6:72f87b7c7400 496 vol -= 0.025f*VINCMULT;
Pokitto 6:72f87b7c7400 497 if (vol <= VOLUME_HEADPHONE_MAX) sound.setMaxVol(VOLUME_HEADPHONE_MAX);
Pokitto 6:72f87b7c7400 498 if (vol < 0) vol=0;
Pokitto 6:72f87b7c7400 499 sound.setVolume(vol);
Pokitto 6:72f87b7c7400 500 dstate=1; wipe=false;
Pokitto 6:72f87b7c7400 501 break;
Pokitto 6:72f87b7c7400 502 }
Pokitto 6:72f87b7c7400 503 break;
Pokitto 6:72f87b7c7400 504 }
Pokitto 6:72f87b7c7400 505 }
Pokitto 6:72f87b7c7400 506 }
Pokitto 6:72f87b7c7400 507
Pokitto 6:72f87b7c7400 508 void Core::begin() {
Pokitto 6:72f87b7c7400 509
Pokitto 6:72f87b7c7400 510 init(); // original functions
Pokitto 6:72f87b7c7400 511 timePerFrame = POK_FRAMEDURATION;
Pokitto 6:72f87b7c7400 512 //nextFrameMillis = 0;
Pokitto 6:72f87b7c7400 513 //frameCount = 0;
Pokitto 6:72f87b7c7400 514 frameEndMicros = 1;
Pokitto 6:72f87b7c7400 515 startMenuTimer = 255;
Pokitto 6:72f87b7c7400 516 //read default settings from flash memory (set using settings.hex)
Pokitto 6:72f87b7c7400 517 readSettings();
Pokitto 6:72f87b7c7400 518 //init everything
Pokitto 6:72f87b7c7400 519 backlight.begin();
Pokitto 6:72f87b7c7400 520 backlight.set(BACKLIGHT_MAX);
Pokitto 6:72f87b7c7400 521 buttons.begin();
Pokitto 6:72f87b7c7400 522 buttons.update();
Pokitto 6:72f87b7c7400 523 battery.begin();
Pokitto 6:72f87b7c7400 524 display.begin();
Pokitto 6:72f87b7c7400 525 #if POK_DISPLAYLOGO
Pokitto 6:72f87b7c7400 526 showLogo();
Pokitto 6:72f87b7c7400 527 #endif // POK_DISPLAYLOGO
Pokitto 17:10609a82d462 528 #ifdef JUSTLOAD
Pokitto 17:10609a82d462 529 jumpToLoader();
Pokitto 17:10609a82d462 530 #endif
Pokitto 6:72f87b7c7400 531 display.enableDirectPrinting(true);
Pokitto 6:72f87b7c7400 532 display.directbgcolor = COLOR_BLACK;
Pokitto 6:72f87b7c7400 533 display.clearLCD();
Pokitto 6:72f87b7c7400 534 display.setFont(fntC64UIGfx);
Pokitto 17:10609a82d462 535 #ifndef DISABLE_LOADER
Pokitto 6:72f87b7c7400 536 askLoader();
Pokitto 17:10609a82d462 537 #endif
Pokitto 6:72f87b7c7400 538 #ifndef DISABLE_SOUND_WARNING
Pokitto 6:72f87b7c7400 539 //showWarning();
Pokitto 6:72f87b7c7400 540 setVolLimit();
Pokitto 6:72f87b7c7400 541 //sound.setVolume(sound.getVolume());//make sure we're at set volume before continue
Pokitto 6:72f87b7c7400 542 sound.volumeUp();
Pokitto 6:72f87b7c7400 543 #endif
Pokitto 6:72f87b7c7400 544 display.enableDirectPrinting(false);
Pokitto 6:72f87b7c7400 545 display.adjustCharStep=1;
Pokitto 6:72f87b7c7400 546 display.adjustLineStep=1;
Pokitto 6:72f87b7c7400 547 display.fontSize=1;
Pokitto 6:72f87b7c7400 548 display.textWrap=true;
Pokitto 6:72f87b7c7400 549 #if POK_GAMEBUINO_SUPPORT > 0
Pokitto 6:72f87b7c7400 550 display.setFont(font5x7);
Pokitto 6:72f87b7c7400 551 #else
Pokitto 6:72f87b7c7400 552 display.setFont(fontC64);
Pokitto 6:72f87b7c7400 553 #endif
Pokitto 6:72f87b7c7400 554 #if POK_ENABLE_SOUND > 0
Pokitto 6:72f87b7c7400 555 sound.begin();
Pokitto 17:10609a82d462 556
Pokitto 6:72f87b7c7400 557 //mute when B is held during start up or if battery is low
Pokitto 6:72f87b7c7400 558 battery.update();
Pokitto 6:72f87b7c7400 559 if(buttons.pressed(BTN_B) || (battery.level == 0)){
Pokitto 6:72f87b7c7400 560 sound.setVolume(0);
Pokitto 6:72f87b7c7400 561 }
Pokitto 6:72f87b7c7400 562 else{ //play the startup sound on each channel for it to be louder
Pokitto 6:72f87b7c7400 563 #if POK_GBSOUND > 0
Pokitto 6:72f87b7c7400 564 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 565 sound.playPattern(startupSound, 0);
Pokitto 6:72f87b7c7400 566 #endif
Pokitto 6:72f87b7c7400 567 #if(NUM_CHANNELS > 1)
Pokitto 6:72f87b7c7400 568 sound.playPattern(startupSound, 1);
Pokitto 6:72f87b7c7400 569 #endif
Pokitto 6:72f87b7c7400 570 #if(NUM_CHANNELS > 2)
Pokitto 6:72f87b7c7400 571 sound.playPattern(startupSound, 2);
Pokitto 6:72f87b7c7400 572 #endif
Pokitto 6:72f87b7c7400 573 #if(NUM_CHANNELS > 3)
Pokitto 6:72f87b7c7400 574 sound.playPattern(startupSound, 3);
Pokitto 6:72f87b7c7400 575 #endif
Pokitto 6:72f87b7c7400 576 #endif // POK_GBSOUND
Pokitto 6:72f87b7c7400 577 }
Pokitto 6:72f87b7c7400 578 #endif // POK ENABLE_SOUND
Pokitto 6:72f87b7c7400 579 }
Pokitto 6:72f87b7c7400 580
Pokitto 6:72f87b7c7400 581 void Core::init() {
Pokitto 6:72f87b7c7400 582 run_state = true;
Pokitto 6:72f87b7c7400 583 display.enableDirectPrinting(false);
Pokitto 6:72f87b7c7400 584 display.setFont(DEFAULT_FONT);
Pokitto 6:72f87b7c7400 585 initClock();
Pokitto 6:72f87b7c7400 586 initGPIO();
Pokitto 6:72f87b7c7400 587 initButtons();
Pokitto 6:72f87b7c7400 588 initRandom();
Pokitto 6:72f87b7c7400 589 //initAudio();
Pokitto 6:72f87b7c7400 590 //initDisplay();
Pokitto 6:72f87b7c7400 591 }
Pokitto 6:72f87b7c7400 592
Pokitto 6:72f87b7c7400 593 void Core::init(uint8_t switches) {
Pokitto 6:72f87b7c7400 594 run_state = true;
Pokitto 6:72f87b7c7400 595 display.enableDirectPrinting(false);
Pokitto 6:72f87b7c7400 596 display.setFont(DEFAULT_FONT);
Pokitto 6:72f87b7c7400 597 initClock();
Pokitto 6:72f87b7c7400 598 initGPIO();
Pokitto 6:72f87b7c7400 599 initButtons();
Pokitto 6:72f87b7c7400 600 initRandom();
Pokitto 6:72f87b7c7400 601 //initAudio();
Pokitto 6:72f87b7c7400 602 //initDisplay();
Pokitto 6:72f87b7c7400 603 }
Pokitto 6:72f87b7c7400 604
Pokitto 6:72f87b7c7400 605 void Core::initButtons() {
Pokitto 6:72f87b7c7400 606 #ifndef POK_SIM
Pokitto 6:72f87b7c7400 607 Pokitto::initButtons();
Pokitto 6:72f87b7c7400 608 #endif
Pokitto 6:72f87b7c7400 609 }
Pokitto 6:72f87b7c7400 610
Pokitto 6:72f87b7c7400 611 bool Core::isRunning() {
Pokitto 6:72f87b7c7400 612 #ifdef POK_SIM
Pokitto 6:72f87b7c7400 613 run_state = simulator.isRunning();
Pokitto 6:72f87b7c7400 614 #endif // POK_SIM
Pokitto 6:72f87b7c7400 615 return run_state;
Pokitto 6:72f87b7c7400 616 }
Pokitto 6:72f87b7c7400 617
Pokitto 6:72f87b7c7400 618 void Core::initDisplay() {
Pokitto 6:72f87b7c7400 619 #if POK_DISPLAYLOGO > 0
Pokitto 6:72f87b7c7400 620 showLogo();
Pokitto 6:72f87b7c7400 621 #endif
Pokitto 6:72f87b7c7400 622 #if POK_USE_CONSOLE > 0
Pokitto 6:72f87b7c7400 623 console.AddMessage(MSOURCE_LCD,MSG_INIT_OK);
Pokitto 6:72f87b7c7400 624 #endif
Pokitto 6:72f87b7c7400 625 }
Pokitto 6:72f87b7c7400 626
Pokitto 6:72f87b7c7400 627 void Core::showLogo() {
Pokitto 6:72f87b7c7400 628 uint32_t now;
Pokitto 6:72f87b7c7400 629 uint8_t state=0; //jump directly to logo, bypass teeth
Pokitto 17:10609a82d462 630 uint16_t counter=0, i=0;
Pokitto 6:72f87b7c7400 631 uint16_t sc;
Pokitto 6:72f87b7c7400 632 while (state < 255/6) {
Pokitto 6:72f87b7c7400 633 now=getTime();
Pokitto 6:72f87b7c7400 634 if (now>refreshtime) {
Pokitto 6:72f87b7c7400 635 refreshtime=now+30;
Pokitto 6:72f87b7c7400 636 switch (state) {
Pokitto 6:72f87b7c7400 637 case 0:
Pokitto 6:72f87b7c7400 638 /** POKITTO CLEAN **/
Pokitto 6:72f87b7c7400 639 display.directbgcolor = COLOR_BLACK;
Pokitto 6:72f87b7c7400 640 display.fillLCD(display.directbgcolor);
Pokitto 6:72f87b7c7400 641 sc = COLOR_BLACK;
Pokitto 6:72f87b7c7400 642 state++;
Pokitto 6:72f87b7c7400 643 break;
Pokitto 6:72f87b7c7400 644 case 1:
Pokitto 6:72f87b7c7400 645 /** POKITTO FADE IN **/
Pokitto 6:72f87b7c7400 646 display.directcolor = display.interpolateColor(sc, COLOR_GREEN, i);
Pokitto 6:72f87b7c7400 647 display.directBitmap(POK_LCD_W/2 - (*Pokitto_logo/2),POK_LCD_H/2-(*(Pokitto_logo+1)/2),Pokitto_logo,1,1);
Pokitto 6:72f87b7c7400 648 i += 28;
Pokitto 6:72f87b7c7400 649 if (i>=0xFF) { state++; i=0;}
Pokitto 6:72f87b7c7400 650 break;
Pokitto 6:72f87b7c7400 651 case 2:
Pokitto 6:72f87b7c7400 652 /** POKITTO WAIT **/
Pokitto 6:72f87b7c7400 653 display.directcolor = COLOR_GREEN;
Pokitto 6:72f87b7c7400 654 display.directBitmap(POK_LCD_W/2 - (*Pokitto_logo/2),POK_LCD_H/2-(*(Pokitto_logo+1)/2),Pokitto_logo,1,1);
Pokitto 6:72f87b7c7400 655 i+= 0x3F;
Pokitto 6:72f87b7c7400 656 if (i>0x3FF) state = 255;
Pokitto 6:72f87b7c7400 657 break;
Pokitto 6:72f87b7c7400 658 }
Pokitto 6:72f87b7c7400 659 if(buttons.aBtn()) state=255;
Pokitto 6:72f87b7c7400 660 }
Pokitto 6:72f87b7c7400 661 }
Pokitto 6:72f87b7c7400 662 }
Pokitto 6:72f87b7c7400 663
Pokitto 6:72f87b7c7400 664 void Core::readSettings() {
Pokitto 6:72f87b7c7400 665 // ToDo
Pokitto 6:72f87b7c7400 666 /*display.contrast = SCR_CONTRAST;
Pokitto 6:72f87b7c7400 667 backlight.backlightMin = BACKLIGHT_MIN;
Pokitto 6:72f87b7c7400 668 backlight.backlightMax = BACKLIGHT_MAX;
Pokitto 6:72f87b7c7400 669 backlight.ambientLightMin = AMBIENTLIGHT_MIN;
Pokitto 6:72f87b7c7400 670 backlight.ambientLightMax = AMBIENTLIGHT_MAX;
Pokitto 6:72f87b7c7400 671 */
Pokitto 6:72f87b7c7400 672 sound.setMaxVol(VOLUME_HEADPHONE_MAX);
Pokitto 6:72f87b7c7400 673 sound.globalVolume = VOLUME_STARTUP;
Pokitto 6:72f87b7c7400 674
Pokitto 6:72f87b7c7400 675 startMenuTimer = START_MENU_TIMER;
Pokitto 6:72f87b7c7400 676 /*
Pokitto 6:72f87b7c7400 677 battery.thresolds[0] = BAT_LVL_CRITIC;
Pokitto 6:72f87b7c7400 678 battery.thresolds[1] = BAT_LVL_LOW;
Pokitto 6:72f87b7c7400 679 battery.thresolds[2] = BAT_LVL_MED;
Pokitto 6:72f87b7c7400 680 battery.thresolds[3] = BAT_LVL_FULL;*/
Pokitto 6:72f87b7c7400 681 }
Pokitto 6:72f87b7c7400 682
Pokitto 6:72f87b7c7400 683 void Core::titleScreen(const char* name){
Pokitto 6:72f87b7c7400 684 titleScreen(name, 0);
Pokitto 6:72f87b7c7400 685 }
Pokitto 6:72f87b7c7400 686
Pokitto 6:72f87b7c7400 687 void Core::titleScreen(const uint8_t* logo){
Pokitto 6:72f87b7c7400 688 titleScreen((""), logo);
Pokitto 6:72f87b7c7400 689 }
Pokitto 6:72f87b7c7400 690
Pokitto 6:72f87b7c7400 691 void Core::titleScreen(){
Pokitto 6:72f87b7c7400 692 titleScreen((""));
Pokitto 6:72f87b7c7400 693 }
Pokitto 6:72f87b7c7400 694
Pokitto 6:72f87b7c7400 695 void Core::titleScreen(const char* name, const uint8_t *logo){
Pokitto 6:72f87b7c7400 696 display.setFont(font5x7);
Pokitto 6:72f87b7c7400 697 if(startMenuTimer){
Pokitto 6:72f87b7c7400 698 display.fontSize = 1;
Pokitto 6:72f87b7c7400 699 display.textWrap = false;
Pokitto 6:72f87b7c7400 700 display.persistence = false;
Pokitto 6:72f87b7c7400 701 battery.show = false;
Pokitto 6:72f87b7c7400 702 display.setColor(BLACK);
Pokitto 6:72f87b7c7400 703 while(isRunning()){
Pokitto 6:72f87b7c7400 704 if(update()){
Pokitto 6:72f87b7c7400 705 uint8_t logoOffset = name[0]?display.fontHeight:0; //add an offset the logo when there is a name to display
Pokitto 6:72f87b7c7400 706 //draw graphics
Pokitto 6:72f87b7c7400 707 display.setColorDepth(1);
Pokitto 6:72f87b7c7400 708 display.setColor(3);
Pokitto 6:72f87b7c7400 709 //display.drawBitmap(0,0, gamebuinoLogo);
Pokitto 6:72f87b7c7400 710 display.setColor(1);
Pokitto 6:72f87b7c7400 711 if(logo){
Pokitto 6:72f87b7c7400 712 display.drawBitmap(0, 12+logoOffset, logo);
Pokitto 6:72f87b7c7400 713 }
Pokitto 6:72f87b7c7400 714 display.cursorX = 0;
Pokitto 6:72f87b7c7400 715 display.cursorY = 12;
Pokitto 6:72f87b7c7400 716 display.print(name);
Pokitto 6:72f87b7c7400 717
Pokitto 6:72f87b7c7400 718 //A button
Pokitto 6:72f87b7c7400 719 display.cursorX = LCDWIDTH - display.fontWidth*3 -1;
Pokitto 6:72f87b7c7400 720 display.cursorY = LCDHEIGHT - display.fontHeight*3 - 3;
Pokitto 6:72f87b7c7400 721 if((frameCount/16)%2)
Pokitto 6:72f87b7c7400 722 display.println(("\25 \20"));
Pokitto 6:72f87b7c7400 723 else
Pokitto 6:72f87b7c7400 724 display.println(("\25\20 "));
Pokitto 6:72f87b7c7400 725 //B button
Pokitto 6:72f87b7c7400 726 display.cursorX = LCDWIDTH - display.fontWidth*3 - 1;
Pokitto 6:72f87b7c7400 727 display.cursorY++;
Pokitto 6:72f87b7c7400 728 if(sound.globalVolume)
Pokitto 6:72f87b7c7400 729 display.println(("\26\23\24"));
Pokitto 6:72f87b7c7400 730 else
Pokitto 6:72f87b7c7400 731 display.println(("\26\23x"));
Pokitto 6:72f87b7c7400 732 //C button
Pokitto 6:72f87b7c7400 733 display.cursorX = LCDWIDTH - display.fontWidth*3 - 1;
Pokitto 6:72f87b7c7400 734 display.cursorY++;
Pokitto 6:72f87b7c7400 735 //display.println(F("\27SD"));
Pokitto 6:72f87b7c7400 736
Pokitto 6:72f87b7c7400 737 //toggle volume when B is pressed
Pokitto 6:72f87b7c7400 738 if(buttons.pressed(BTN_B)){
Pokitto 6:72f87b7c7400 739 sound.setVolume(sound.getVolume() + 1);
Pokitto 6:72f87b7c7400 740 sound.playTick();
Pokitto 6:72f87b7c7400 741 }
Pokitto 6:72f87b7c7400 742 //leave the menu
Pokitto 6:72f87b7c7400 743 if(buttons.pressed(BTN_A) || ((frameCount>=startMenuTimer)&&(startMenuTimer != 255))){
Pokitto 6:72f87b7c7400 744 startMenuTimer = 255; //don't automatically skip the title screen next time it's displayed
Pokitto 6:72f87b7c7400 745 sound.stopPattern(0);
Pokitto 6:72f87b7c7400 746 sound.playOK();
Pokitto 6:72f87b7c7400 747 break;
Pokitto 6:72f87b7c7400 748 }
Pokitto 6:72f87b7c7400 749 //flash the loader
Pokitto 6:72f87b7c7400 750 //if(buttons.pressed(BTN_C))
Pokitto 6:72f87b7c7400 751 // ToDo changeGame();
Pokitto 6:72f87b7c7400 752 }
Pokitto 6:72f87b7c7400 753 }
Pokitto 6:72f87b7c7400 754 battery.show = true;
Pokitto 6:72f87b7c7400 755 }
Pokitto 6:72f87b7c7400 756 }
Pokitto 6:72f87b7c7400 757
Pokitto 6:72f87b7c7400 758 bool Core::update(bool useDirectMode) {
Pokitto 6:72f87b7c7400 759 #if POK_STREAMING_MUSIC
Pokitto 6:72f87b7c7400 760 sound.updateStream();
Pokitto 6:72f87b7c7400 761 #endif
Pokitto 6:72f87b7c7400 762
Pokitto 6:72f87b7c7400 763 if ((((nextFrameMillis - getTime())) > timePerFrame) && frameEndMicros) { //if time to render a new frame is reached and the frame end has ran once
Pokitto 6:72f87b7c7400 764 nextFrameMillis = getTime() + timePerFrame;
Pokitto 6:72f87b7c7400 765 frameCount++;
Pokitto 6:72f87b7c7400 766
Pokitto 6:72f87b7c7400 767 frameEndMicros = 0;
Pokitto 6:72f87b7c7400 768 backlight.update();
Pokitto 6:72f87b7c7400 769 buttons.update();
Pokitto 6:72f87b7c7400 770 battery.update();
Pokitto 6:72f87b7c7400 771
Pokitto 6:72f87b7c7400 772 return true;
Pokitto 6:72f87b7c7400 773
Pokitto 6:72f87b7c7400 774 } else {
Pokitto 6:72f87b7c7400 775 if (!frameEndMicros) { //runs once at the end of the frame
Pokitto 6:72f87b7c7400 776 #if POK_ENABLE_SOUND > 0
Pokitto 6:72f87b7c7400 777 sound.updateTrack();
Pokitto 6:72f87b7c7400 778 sound.updatePattern();
Pokitto 6:72f87b7c7400 779 sound.updateNote();
Pokitto 6:72f87b7c7400 780 #endif
Pokitto 6:72f87b7c7400 781 updatePopup();
Pokitto 6:72f87b7c7400 782 displayBattery();
Pokitto 6:72f87b7c7400 783
Pokitto 6:72f87b7c7400 784 if(!useDirectMode)
Pokitto 6:72f87b7c7400 785 display.update(); //send the buffer to the screen
Pokitto 6:72f87b7c7400 786
Pokitto 6:72f87b7c7400 787 frameEndMicros = 1; //jonne
Pokitto 6:72f87b7c7400 788
Pokitto 6:72f87b7c7400 789 }
Pokitto 6:72f87b7c7400 790 return false;
Pokitto 6:72f87b7c7400 791 }
Pokitto 6:72f87b7c7400 792 }
Pokitto 6:72f87b7c7400 793
Pokitto 6:72f87b7c7400 794 void Core::displayBattery(){
Pokitto 6:72f87b7c7400 795 #if (ENABLE_BATTERY > 0)
Pokitto 6:72f87b7c7400 796 //display.setColor(BLACK, WHITE);
Pokitto 6:72f87b7c7400 797 uint8_t ox,oy;
Pokitto 6:72f87b7c7400 798 ox=display.cursorX;
Pokitto 6:72f87b7c7400 799 oy=display.cursorY;
Pokitto 6:72f87b7c7400 800 display.cursorX = LCDWIDTH-display.fontWidth+1;
Pokitto 6:72f87b7c7400 801 display.cursorY = 0;
Pokitto 6:72f87b7c7400 802 switch(battery.level){
Pokitto 6:72f87b7c7400 803 case 0://battery critic, power down
Pokitto 6:72f87b7c7400 804 sound.stopPattern();
Pokitto 6:72f87b7c7400 805 backlight.set(0);
Pokitto 6:72f87b7c7400 806 display.clear();
Pokitto 6:72f87b7c7400 807 display.fontSize = 1;
Pokitto 6:72f87b7c7400 808 display.print(("LOW BATTERY\n"));
Pokitto 6:72f87b7c7400 809 display.print(battery.voltage);
Pokitto 6:72f87b7c7400 810 display.print(("mV\n\nPLEASE\nTURN OFF"));
Pokitto 6:72f87b7c7400 811 display.update();
Pokitto 6:72f87b7c7400 812 break;
Pokitto 6:72f87b7c7400 813 case 1: //empty battery
Pokitto 6:72f87b7c7400 814 if((frameCount % 16) < 8) display.print('\7'); //blinking battery
Pokitto 6:72f87b7c7400 815 else display.print('x');
Pokitto 6:72f87b7c7400 816 break;
Pokitto 6:72f87b7c7400 817 case 2://low battery
Pokitto 6:72f87b7c7400 818 case 3://full battery
Pokitto 6:72f87b7c7400 819 case 4://full battery
Pokitto 6:72f87b7c7400 820 if(battery.show){
Pokitto 6:72f87b7c7400 821 display.print(char(5+battery.level));
Pokitto 6:72f87b7c7400 822 }
Pokitto 6:72f87b7c7400 823 break;
Pokitto 6:72f87b7c7400 824 default:
Pokitto 6:72f87b7c7400 825 if(battery.show){
Pokitto 6:72f87b7c7400 826 display.print('/');
Pokitto 6:72f87b7c7400 827 }
Pokitto 6:72f87b7c7400 828 break;
Pokitto 6:72f87b7c7400 829 }
Pokitto 6:72f87b7c7400 830 display.cursorX = ox;
Pokitto 6:72f87b7c7400 831 display.cursorY = oy;
Pokitto 6:72f87b7c7400 832 #endif
Pokitto 6:72f87b7c7400 833 }
Pokitto 6:72f87b7c7400 834
Pokitto 6:72f87b7c7400 835 char* Core::filemenu(char *ext) {
Pokitto 6:72f87b7c7400 836 display.persistence = false;
Pokitto 6:72f87b7c7400 837 uint16_t oldpal0=display.palette[0];
Pokitto 6:72f87b7c7400 838 uint16_t oldpal1=display.palette[1];
Pokitto 6:72f87b7c7400 839 uint16_t oldpal2=display.palette[2];
Pokitto 6:72f87b7c7400 840 display.palette[2]=COLOR_GREEN;
Pokitto 6:72f87b7c7400 841 display.palette[1]=COLOR_WHITE;
Pokitto 6:72f87b7c7400 842 display.palette[0]=COLOR_BLACK;
Pokitto 6:72f87b7c7400 843 uint8_t oldbg=display.bgcolor;
Pokitto 6:72f87b7c7400 844 uint8_t oldfg=display.color;
Pokitto 6:72f87b7c7400 845 display.color=1;
Pokitto 6:72f87b7c7400 846 display.bgcolor=0;
Pokitto 6:72f87b7c7400 847
Pokitto 6:72f87b7c7400 848 int8_t activeItem = 0;
Pokitto 6:72f87b7c7400 849 int16_t currentY = 100;
Pokitto 6:72f87b7c7400 850 int16_t targetY = 0, rowh = display.fontHeight + 2;
Pokitto 6:72f87b7c7400 851 boolean exit = false;
Pokitto 6:72f87b7c7400 852
Pokitto 6:72f87b7c7400 853 char* txt;
Pokitto 6:72f87b7c7400 854
Pokitto 6:72f87b7c7400 855
Pokitto 6:72f87b7c7400 856 while (isRunning()) {
Pokitto 6:72f87b7c7400 857 if (update()) {
Pokitto 6:72f87b7c7400 858 getFirstFile(ext);
Pokitto 6:72f87b7c7400 859 if (buttons.pressed(BTN_A) || buttons.pressed(BTN_B) || buttons.pressed(BTN_C)) {
Pokitto 6:72f87b7c7400 860 exit = true; //time to exit menu !
Pokitto 6:72f87b7c7400 861 targetY = - display.fontHeight * 10 - 2; //send the menu out of the screen
Pokitto 6:72f87b7c7400 862 if (buttons.pressed(BTN_A)) {
Pokitto 6:72f87b7c7400 863 //answer = activeItem;
Pokitto 6:72f87b7c7400 864 sound.playOK();
Pokitto 6:72f87b7c7400 865 } else {
Pokitto 6:72f87b7c7400 866 sound.playCancel();
Pokitto 6:72f87b7c7400 867 }
Pokitto 6:72f87b7c7400 868 }
Pokitto 6:72f87b7c7400 869 if (exit == false) {
Pokitto 6:72f87b7c7400 870 if (buttons.repeat(BTN_DOWN,4)) {
Pokitto 6:72f87b7c7400 871 activeItem++;
Pokitto 6:72f87b7c7400 872 sound.playTick();
Pokitto 6:72f87b7c7400 873 }
Pokitto 6:72f87b7c7400 874 if (buttons.repeat(BTN_UP,4)) {
Pokitto 6:72f87b7c7400 875 activeItem--;
Pokitto 6:72f87b7c7400 876 sound.playTick();
Pokitto 6:72f87b7c7400 877 }
Pokitto 6:72f87b7c7400 878 //don't go out of the menu
Pokitto 6:72f87b7c7400 879 //if (activeItem == length) activeItem = 0;
Pokitto 6:72f87b7c7400 880 //if (activeItem < 0) activeItem = length - 1;
Pokitto 6:72f87b7c7400 881 if (currentY>targetY) currentY-=16;
Pokitto 6:72f87b7c7400 882 if (currentY<targetY) currentY=targetY;
Pokitto 6:72f87b7c7400 883 //targetY = -rowh * activeItem + (rowh+4); //center the menu on the active item
Pokitto 6:72f87b7c7400 884 } else { //exit :
Pokitto 6:72f87b7c7400 885 if (currentY>targetY) currentY-=16;
Pokitto 6:72f87b7c7400 886 if (currentY<targetY) currentY=targetY;
Pokitto 6:72f87b7c7400 887 if ((currentY - targetY) <= 1)
Pokitto 6:72f87b7c7400 888 {
Pokitto 6:72f87b7c7400 889 display.bgcolor=oldbg;
Pokitto 6:72f87b7c7400 890 display.color=oldfg;
Pokitto 6:72f87b7c7400 891 display.palette[0] = oldpal0;
Pokitto 6:72f87b7c7400 892 display.palette[1] = oldpal1;
Pokitto 6:72f87b7c7400 893 display.palette[2] = oldpal2;
Pokitto 6:72f87b7c7400 894 return selectedfile;
Pokitto 6:72f87b7c7400 895 }
Pokitto 6:72f87b7c7400 896
Pokitto 6:72f87b7c7400 897 }
Pokitto 6:72f87b7c7400 898 //draw a fancy menu
Pokitto 6:72f87b7c7400 899 //currentY = 0;//(currentY + targetY) / 2 + 5;
Pokitto 6:72f87b7c7400 900 display.cursorX = 0;
Pokitto 6:72f87b7c7400 901 display.cursorY = currentY;
Pokitto 6:72f87b7c7400 902 display.textWrap = false;
Pokitto 17:10609a82d462 903 uint16_t fc,bc;
Pokitto 17:10609a82d462 904 fc = display.color;
Pokitto 17:10609a82d462 905 bc = display.bgcolor;
Pokitto 6:72f87b7c7400 906 //getFirstFile(ext);
Pokitto 6:72f87b7c7400 907 for (int i = 0; i<20; i++) {
Pokitto 6:72f87b7c7400 908 display.invisiblecolor=255;
Pokitto 6:72f87b7c7400 909 display.cursorY = currentY + rowh * i;
Pokitto 6:72f87b7c7400 910 if (i==3) display.color=1;
Pokitto 6:72f87b7c7400 911 if (i == activeItem){
Pokitto 6:72f87b7c7400 912 display.cursorX = 3;
Pokitto 6:72f87b7c7400 913
Pokitto 6:72f87b7c7400 914 //display.fillRoundRect(0, currentY + display.fontHeight * activeItem - 2, LCDWIDTH, (display.fontHeight+3), 3);
Pokitto 6:72f87b7c7400 915 display.color=2;
Pokitto 6:72f87b7c7400 916 display.fillRect(0, currentY + rowh * activeItem - 2, LCDWIDTH, (rowh));
Pokitto 6:72f87b7c7400 917 display.setColor(0,2);
Pokitto 6:72f87b7c7400 918 } else display.setColor(1,0);
Pokitto 6:72f87b7c7400 919 //display.println((char*)*(const unsigned int*)(items+i));
Pokitto 6:72f87b7c7400 920 //display.println((int)i);
Pokitto 6:72f87b7c7400 921 txt = getNextFile(ext);
Pokitto 6:72f87b7c7400 922 if (txt) {
Pokitto 6:72f87b7c7400 923 display.println(txt);
Pokitto 6:72f87b7c7400 924 if (i == activeItem) {
Pokitto 6:72f87b7c7400 925 strcpy(selectedfile,txt);
Pokitto 6:72f87b7c7400 926 }
Pokitto 6:72f87b7c7400 927 } else i--;
Pokitto 6:72f87b7c7400 928 display.setColor(1,0);
Pokitto 6:72f87b7c7400 929 } // draw menu loop
Pokitto 6:72f87b7c7400 930 } // update
Pokitto 6:72f87b7c7400 931 }
Pokitto 6:72f87b7c7400 932 return 0;
Pokitto 6:72f87b7c7400 933 }
Pokitto 6:72f87b7c7400 934
Pokitto 6:72f87b7c7400 935 char* Core::filemenu() {
Pokitto 6:72f87b7c7400 936 return filemenu("");
Pokitto 6:72f87b7c7400 937 }
Pokitto 6:72f87b7c7400 938
Pokitto 6:72f87b7c7400 939 int8_t Core::menu(const char* const* items, uint8_t length) {
Pokitto 6:72f87b7c7400 940 #if (ENABLE_GUI > 0)
Pokitto 6:72f87b7c7400 941 display.persistence = false;
Pokitto 6:72f87b7c7400 942 int8_t activeItem = 0;
Pokitto 6:72f87b7c7400 943 int16_t currentY = display.height;
Pokitto 6:72f87b7c7400 944 int16_t targetY = 0, rowh = display.fontHeight + 2;
Pokitto 6:72f87b7c7400 945 boolean exit = false;
Pokitto 6:72f87b7c7400 946 int8_t answer = -1;
Pokitto 6:72f87b7c7400 947 while (isRunning()) {
Pokitto 6:72f87b7c7400 948 if (update()) {
Pokitto 6:72f87b7c7400 949 if (buttons.pressed(BTN_A) || buttons.pressed(BTN_B) || buttons.pressed(BTN_C)) {
Pokitto 6:72f87b7c7400 950 exit = true; //time to exit menu !
Pokitto 6:72f87b7c7400 951 targetY = - display.fontHeight * length - 2; //send the menu out of the screen
Pokitto 6:72f87b7c7400 952 if (buttons.pressed(BTN_A)) {
Pokitto 6:72f87b7c7400 953 answer = activeItem;
Pokitto 6:72f87b7c7400 954 sound.playOK();
Pokitto 6:72f87b7c7400 955 } else {
Pokitto 6:72f87b7c7400 956 sound.playCancel();
Pokitto 6:72f87b7c7400 957 }
Pokitto 6:72f87b7c7400 958 }
Pokitto 6:72f87b7c7400 959 if (exit == false) {
Pokitto 6:72f87b7c7400 960 if (buttons.repeat(BTN_DOWN,4)) {
Pokitto 6:72f87b7c7400 961 activeItem++;
Pokitto 6:72f87b7c7400 962 sound.playTick();
Pokitto 6:72f87b7c7400 963 }
Pokitto 6:72f87b7c7400 964 if (buttons.repeat(BTN_UP,4)) {
Pokitto 6:72f87b7c7400 965 activeItem--;
Pokitto 6:72f87b7c7400 966 sound.playTick();
Pokitto 6:72f87b7c7400 967 }
Pokitto 6:72f87b7c7400 968 //don't go out of the menu
Pokitto 6:72f87b7c7400 969 if (activeItem == length) activeItem = 0;
Pokitto 6:72f87b7c7400 970 if (activeItem < 0) activeItem = length - 1;
Pokitto 6:72f87b7c7400 971
Pokitto 6:72f87b7c7400 972 targetY = -rowh * activeItem + (rowh+4); //center the menu on the active item
Pokitto 6:72f87b7c7400 973 } else { //exit :
Pokitto 6:72f87b7c7400 974 if ((currentY - targetY) <= 1)
Pokitto 6:72f87b7c7400 975 return (answer);
Pokitto 6:72f87b7c7400 976 }
Pokitto 6:72f87b7c7400 977 //draw a fancy menu
Pokitto 6:72f87b7c7400 978 currentY = (currentY + targetY) / 2;
Pokitto 6:72f87b7c7400 979 display.cursorX = 0;
Pokitto 6:72f87b7c7400 980 display.cursorY = currentY;
Pokitto 6:72f87b7c7400 981 display.textWrap = false;
Pokitto 6:72f87b7c7400 982 uint16_t fc,bc;
Pokitto 6:72f87b7c7400 983 fc = display.color;
Pokitto 6:72f87b7c7400 984 bc = display.bgcolor;
Pokitto 6:72f87b7c7400 985 for (byte i = 0; i < length; i++) {
Pokitto 6:72f87b7c7400 986 display.cursorY = currentY + rowh * i;
Pokitto 6:72f87b7c7400 987 if (i == activeItem){
Pokitto 6:72f87b7c7400 988 display.cursorX = 3;
Pokitto 6:72f87b7c7400 989
Pokitto 6:72f87b7c7400 990 //display.fillRoundRect(0, currentY + display.fontHeight * activeItem - 2, LCDWIDTH, (display.fontHeight+3), 3);
Pokitto 6:72f87b7c7400 991 display.fillRect(0, currentY + rowh * activeItem - 2, LCDWIDTH, (rowh));
Pokitto 6:72f87b7c7400 992 display.setColor(bc,fc);
Pokitto 6:72f87b7c7400 993 } else display.setColor(fc,bc);
Pokitto 6:72f87b7c7400 994
Pokitto 6:72f87b7c7400 995 display.println((char*)*(const unsigned int*)(items+i));
Pokitto 6:72f87b7c7400 996 display.setColor(fc,bc);
Pokitto 6:72f87b7c7400 997 }
Pokitto 6:72f87b7c7400 998
Pokitto 6:72f87b7c7400 999 }
Pokitto 6:72f87b7c7400 1000 }
Pokitto 6:72f87b7c7400 1001 #else
Pokitto 6:72f87b7c7400 1002 return 0;
Pokitto 6:72f87b7c7400 1003 #endif
Pokitto 6:72f87b7c7400 1004 return 0;
Pokitto 6:72f87b7c7400 1005 }
Pokitto 6:72f87b7c7400 1006
Pokitto 6:72f87b7c7400 1007 void Core::keyboard(char* text, uint8_t length) {
Pokitto 6:72f87b7c7400 1008 #if (ENABLE_GUI > 0)
Pokitto 6:72f87b7c7400 1009 display.persistence = false;
Pokitto 6:72f87b7c7400 1010 //memset(text, 0, length); //clear the text
Pokitto 6:72f87b7c7400 1011 text[length-1] = '\0';
Pokitto 6:72f87b7c7400 1012 //active character in the typing area
Pokitto 6:72f87b7c7400 1013 int8_t activeChar = 0;
Pokitto 6:72f87b7c7400 1014 //selected char on the keyboard
Pokitto 6:72f87b7c7400 1015 int8_t activeX = 0;
Pokitto 6:72f87b7c7400 1016 int8_t activeY = 2;
Pokitto 6:72f87b7c7400 1017 //position of the keyboard on the screen
Pokitto 6:72f87b7c7400 1018 int8_t currentX = LCDWIDTH;
Pokitto 6:72f87b7c7400 1019 int8_t currentY = LCDHEIGHT;
Pokitto 6:72f87b7c7400 1020 int8_t targetX = 0;
Pokitto 6:72f87b7c7400 1021 int8_t targetY = 0;
Pokitto 6:72f87b7c7400 1022
Pokitto 6:72f87b7c7400 1023 while (1) {
Pokitto 6:72f87b7c7400 1024 if (update()) {
Pokitto 6:72f87b7c7400 1025 //move the character selector
Pokitto 6:72f87b7c7400 1026 if (buttons.repeat(BTN_DOWN, 4)) {
Pokitto 6:72f87b7c7400 1027 activeY++;
Pokitto 6:72f87b7c7400 1028 sound.playTick();
Pokitto 6:72f87b7c7400 1029 }
Pokitto 6:72f87b7c7400 1030 if (buttons.repeat(BTN_UP, 4)) {
Pokitto 6:72f87b7c7400 1031 activeY--;
Pokitto 6:72f87b7c7400 1032 sound.playTick();
Pokitto 6:72f87b7c7400 1033 }
Pokitto 6:72f87b7c7400 1034 if (buttons.repeat(BTN_RIGHT, 4)) {
Pokitto 6:72f87b7c7400 1035 activeX++;
Pokitto 6:72f87b7c7400 1036 sound.playTick();
Pokitto 6:72f87b7c7400 1037 }
Pokitto 6:72f87b7c7400 1038 if (buttons.repeat(BTN_LEFT, 4)) {
Pokitto 6:72f87b7c7400 1039 activeX--;
Pokitto 6:72f87b7c7400 1040 sound.playTick();
Pokitto 6:72f87b7c7400 1041 }
Pokitto 6:72f87b7c7400 1042 //don't go out of the keyboard
Pokitto 6:72f87b7c7400 1043 if (activeX == KEYBOARD_W) activeX = 0;
Pokitto 6:72f87b7c7400 1044 if (activeX < 0) activeX = KEYBOARD_W - 1;
Pokitto 6:72f87b7c7400 1045 if (activeY == KEYBOARD_H) activeY = 0;
Pokitto 6:72f87b7c7400 1046 if (activeY < 0) activeY = KEYBOARD_H - 1;
Pokitto 6:72f87b7c7400 1047 //set the keyboard position on screen
Pokitto 6:72f87b7c7400 1048 targetX = -(display.fontWidth+1) * activeX + LCDWIDTH / 2 - 3;
Pokitto 6:72f87b7c7400 1049 targetY = -(display.fontHeight+1) * activeY + LCDHEIGHT / 2 - 4 - display.fontHeight;
Pokitto 6:72f87b7c7400 1050 //smooth the keyboard displacement
Pokitto 6:72f87b7c7400 1051 currentX = (targetX + currentX) / 2;
Pokitto 6:72f87b7c7400 1052 currentY = (targetY + currentY) / 2;
Pokitto 6:72f87b7c7400 1053 //type character
Pokitto 6:72f87b7c7400 1054 if (buttons.pressed(BTN_A)) {
Pokitto 6:72f87b7c7400 1055 if (activeChar < (length-1)) {
Pokitto 6:72f87b7c7400 1056 byte thisChar = activeX + KEYBOARD_W * activeY;
Pokitto 6:72f87b7c7400 1057 if((thisChar == 0)||(thisChar == 10)||(thisChar == 13)) //avoid line feed and carriage return
Pokitto 6:72f87b7c7400 1058 continue;
Pokitto 6:72f87b7c7400 1059 text[activeChar] = thisChar;
Pokitto 6:72f87b7c7400 1060 text[activeChar+1] = '\0';
Pokitto 6:72f87b7c7400 1061 }
Pokitto 6:72f87b7c7400 1062 activeChar++;
Pokitto 6:72f87b7c7400 1063 sound.playOK();
Pokitto 6:72f87b7c7400 1064 if (activeChar > length)
Pokitto 6:72f87b7c7400 1065 activeChar = length;
Pokitto 6:72f87b7c7400 1066 }
Pokitto 6:72f87b7c7400 1067 //erase character
Pokitto 6:72f87b7c7400 1068 if (buttons.pressed(BTN_B)) {
Pokitto 6:72f87b7c7400 1069 activeChar--;
Pokitto 6:72f87b7c7400 1070 sound.playCancel();
Pokitto 6:72f87b7c7400 1071 if (activeChar >= 0)
Pokitto 6:72f87b7c7400 1072 text[activeChar] = 0;
Pokitto 6:72f87b7c7400 1073 else
Pokitto 6:72f87b7c7400 1074 activeChar = 0;
Pokitto 6:72f87b7c7400 1075 }
Pokitto 6:72f87b7c7400 1076 //leave menu
Pokitto 6:72f87b7c7400 1077 if (buttons.pressed(BTN_C)) {
Pokitto 6:72f87b7c7400 1078 sound.playOK();
Pokitto 6:72f87b7c7400 1079 while (1) {
Pokitto 6:72f87b7c7400 1080 if (update()) {
Pokitto 6:72f87b7c7400 1081 //display.setCursor(0,0);
Pokitto 6:72f87b7c7400 1082 display.println(("You entered\n"));
Pokitto 6:72f87b7c7400 1083 display.print(text);
Pokitto 6:72f87b7c7400 1084 display.println(("\n\n\n\x15:okay \x16:edit"));
Pokitto 6:72f87b7c7400 1085 if(buttons.pressed(BTN_A)){
Pokitto 6:72f87b7c7400 1086 sound.playOK();
Pokitto 6:72f87b7c7400 1087 return;
Pokitto 6:72f87b7c7400 1088 }
Pokitto 6:72f87b7c7400 1089 if(buttons.pressed(BTN_B)){
Pokitto 6:72f87b7c7400 1090 sound.playCancel();
Pokitto 6:72f87b7c7400 1091 break;
Pokitto 6:72f87b7c7400 1092 }
Pokitto 6:72f87b7c7400 1093 }
Pokitto 6:72f87b7c7400 1094 }
Pokitto 6:72f87b7c7400 1095 }
Pokitto 6:72f87b7c7400 1096 //draw the keyboard
Pokitto 6:72f87b7c7400 1097 for (int8_t y = 0; y < KEYBOARD_H; y++) {
Pokitto 6:72f87b7c7400 1098 for (int8_t x = 0; x < KEYBOARD_W; x++) {
Pokitto 6:72f87b7c7400 1099 display.drawChar(currentX + x * (display.fontWidth+1), currentY + y * (display.fontHeight+1), x + y * KEYBOARD_W, 1);
Pokitto 6:72f87b7c7400 1100 }
Pokitto 6:72f87b7c7400 1101 }
Pokitto 6:72f87b7c7400 1102 //draw instruction
Pokitto 6:72f87b7c7400 1103 display.cursorX = currentX-display.fontWidth*6-2;
Pokitto 6:72f87b7c7400 1104 display.cursorY = currentY+1*(display.fontHeight+1);
Pokitto 6:72f87b7c7400 1105 display.print(("\25type"));
Pokitto 6:72f87b7c7400 1106
Pokitto 6:72f87b7c7400 1107 display.cursorX = currentX-display.fontWidth*6-2;
Pokitto 6:72f87b7c7400 1108 display.cursorY = currentY+2*(display.fontHeight+1);
Pokitto 6:72f87b7c7400 1109 display.print(("\26back"));
Pokitto 6:72f87b7c7400 1110
Pokitto 6:72f87b7c7400 1111 display.cursorX = currentX-display.fontWidth*6-2;
Pokitto 6:72f87b7c7400 1112 display.cursorY = currentY+3*(display.fontHeight+1);
Pokitto 6:72f87b7c7400 1113 display.print(("\27save"));
Pokitto 6:72f87b7c7400 1114
Pokitto 6:72f87b7c7400 1115 //erase some pixels around the selected character
Pokitto 6:72f87b7c7400 1116 display.setColor(WHITE);
Pokitto 6:72f87b7c7400 1117 display.drawFastHLine(currentX + activeX * (display.fontWidth+1) - 1, currentY + activeY * (display.fontHeight+1) - 2, 7);
Pokitto 6:72f87b7c7400 1118 //draw the selection rectangle
Pokitto 6:72f87b7c7400 1119 display.setColor(BLACK);
Pokitto 6:72f87b7c7400 1120 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);
Pokitto 6:72f87b7c7400 1121 //draw keyboard outline
Pokitto 6:72f87b7c7400 1122 //display.drawRoundRect(currentX - 6, currentY - 6, KEYBOARD_W * (display.fontWidth+1) + 12, KEYBOARD_H * (display.fontHeight+1) + 12, 8, BLACK);
Pokitto 6:72f87b7c7400 1123 //text field
Pokitto 6:72f87b7c7400 1124 display.drawFastHLine(0, LCDHEIGHT-display.fontHeight-2, LCDWIDTH);
Pokitto 6:72f87b7c7400 1125 display.setColor(WHITE);
Pokitto 6:72f87b7c7400 1126 display.fillRect(0, LCDHEIGHT-display.fontHeight-1, LCDWIDTH, display.fontHeight+1);
Pokitto 6:72f87b7c7400 1127 //typed text
Pokitto 6:72f87b7c7400 1128 display.cursorX = 0;
Pokitto 6:72f87b7c7400 1129 display.cursorY = LCDHEIGHT-display.fontHeight;
Pokitto 6:72f87b7c7400 1130 display.setColor(BLACK);
Pokitto 6:72f87b7c7400 1131 display.print(text);
Pokitto 6:72f87b7c7400 1132 //blinking cursor
Pokitto 6:72f87b7c7400 1133 if (((frameCount % 8) < 4) && (activeChar < (length-1)))
Pokitto 6:72f87b7c7400 1134 display.drawChar(display.fontWidth * activeChar, LCDHEIGHT-display.fontHeight, '_',1);
Pokitto 6:72f87b7c7400 1135 }
Pokitto 6:72f87b7c7400 1136 }
Pokitto 6:72f87b7c7400 1137 #endif
Pokitto 6:72f87b7c7400 1138 }
Pokitto 6:72f87b7c7400 1139
Pokitto 6:72f87b7c7400 1140 void Core::popup(const char* text, uint8_t duration){
Pokitto 6:72f87b7c7400 1141 #if (ENABLE_GUI > 0)
Pokitto 6:72f87b7c7400 1142 popupText = text;
Pokitto 6:72f87b7c7400 1143 popupTimeLeft = duration+12;
Pokitto 6:72f87b7c7400 1144 #endif
Pokitto 6:72f87b7c7400 1145 }
Pokitto 6:72f87b7c7400 1146
Pokitto 6:72f87b7c7400 1147 void Core::updatePopup(){
Pokitto 6:72f87b7c7400 1148 #if (ENABLE_GUI > 0)
Pokitto 6:72f87b7c7400 1149 if (popupTimeLeft){
Pokitto 6:72f87b7c7400 1150 uint8_t yOffset = 0;
Pokitto 6:72f87b7c7400 1151 if(popupTimeLeft<12){
Pokitto 6:72f87b7c7400 1152 yOffset = 12-popupTimeLeft;
Pokitto 6:72f87b7c7400 1153 }
Pokitto 6:72f87b7c7400 1154 display.fontSize = 1;
Pokitto 6:72f87b7c7400 1155 display.setColor(WHITE);
Pokitto 6:72f87b7c7400 1156 display.fillRoundRect(0,LCDHEIGHT-display.fontHeight+yOffset-3,84,display.fontHeight+3,3);
Pokitto 6:72f87b7c7400 1157 display.setColor(BLACK);
Pokitto 6:72f87b7c7400 1158 display.drawRoundRect(0,LCDHEIGHT-display.fontHeight+yOffset-3,84,display.fontHeight+3,3);
Pokitto 6:72f87b7c7400 1159 display.cursorX = 4;
Pokitto 6:72f87b7c7400 1160 display.cursorY = LCDHEIGHT-display.fontHeight+yOffset-1;
Pokitto 6:72f87b7c7400 1161 display.print(popupText);
Pokitto 6:72f87b7c7400 1162 popupTimeLeft--;
Pokitto 6:72f87b7c7400 1163 }
Pokitto 6:72f87b7c7400 1164 #endif
Pokitto 6:72f87b7c7400 1165 }
Pokitto 6:72f87b7c7400 1166
Pokitto 6:72f87b7c7400 1167 void Core::setFrameRate(uint8_t fps) {
Pokitto 6:72f87b7c7400 1168 timePerFrame = 1000 / fps;
Pokitto 6:72f87b7c7400 1169 sound.prescaler = fps / 20;
Pokitto 6:72f87b7c7400 1170 sound.prescaler = __avrmax(1, sound.prescaler);
Pokitto 6:72f87b7c7400 1171 }
Pokitto 6:72f87b7c7400 1172
Pokitto 6:72f87b7c7400 1173 void Core::pickRandomSeed(){
Pokitto 6:72f87b7c7400 1174 initRandom();
Pokitto 6:72f87b7c7400 1175 }
Pokitto 6:72f87b7c7400 1176
Pokitto 6:72f87b7c7400 1177 bool Core::collidePointRect(int16_t x1, int16_t y1 ,int16_t x2 ,int16_t y2, int16_t w, int16_t h){
Pokitto 6:72f87b7c7400 1178 if((x1>=x2)&&(x1<x2+w))
Pokitto 6:72f87b7c7400 1179 if((y1>=y2)&&(y1<y2+h))
Pokitto 6:72f87b7c7400 1180 return true;
Pokitto 6:72f87b7c7400 1181 return false;
Pokitto 6:72f87b7c7400 1182 }
Pokitto 6:72f87b7c7400 1183
Pokitto 6:72f87b7c7400 1184 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){
Pokitto 6:72f87b7c7400 1185 return !( x2 >= x1+w1 ||
Pokitto 6:72f87b7c7400 1186 x2+w2 <= x1 ||
Pokitto 6:72f87b7c7400 1187 y2 >= y1+h1 ||
Pokitto 6:72f87b7c7400 1188 y2+h2 <= y1 );
Pokitto 6:72f87b7c7400 1189 }
Pokitto 6:72f87b7c7400 1190
Pokitto 6:72f87b7c7400 1191 bool Core::collideBitmapBitmap(int16_t x1, int16_t y1, const uint8_t* b1, int16_t x2, int16_t y2, const uint8_t* b2){
Pokitto 6:72f87b7c7400 1192 int16_t w1 = pgm_read_byte(b1);
Pokitto 6:72f87b7c7400 1193 int16_t h1 = pgm_read_byte(b1 + 1);
Pokitto 6:72f87b7c7400 1194 int16_t w2 = pgm_read_byte(b2);
Pokitto 6:72f87b7c7400 1195 int16_t h2 = pgm_read_byte(b2 + 1);
Pokitto 6:72f87b7c7400 1196
Pokitto 6:72f87b7c7400 1197 if(collideRectRect(x1, y1, w1, h1, x2, y2, w2, h2) == false){
Pokitto 6:72f87b7c7400 1198 return false;
Pokitto 6:72f87b7c7400 1199 }
Pokitto 6:72f87b7c7400 1200
Pokitto 6:72f87b7c7400 1201 int16_t xmin = (x1>=x2)? 0 : x2-x1;
Pokitto 6:72f87b7c7400 1202 int16_t ymin = (y1>=y2)? 0 : y2-y1;
Pokitto 6:72f87b7c7400 1203 int16_t xmax = (x1+w1>=x2+w2)? x2+w2-x1 : w1;
Pokitto 6:72f87b7c7400 1204 int16_t ymax = (y1+h1>=y2+h2)? y2+h2-y1 : h1;
Pokitto 6:72f87b7c7400 1205 for(uint8_t y = ymin; y < ymax; y++){
Pokitto 6:72f87b7c7400 1206 for(uint8_t x = xmin; x < xmax; x++){
Pokitto 6:72f87b7c7400 1207 if(display.getBitmapPixel(b1, x, y) && display.getBitmapPixel(b2, x1+x-x2, y1+y-y2)){
Pokitto 6:72f87b7c7400 1208 return true;
Pokitto 6:72f87b7c7400 1209 }
Pokitto 6:72f87b7c7400 1210 }
Pokitto 6:72f87b7c7400 1211 }
Pokitto 6:72f87b7c7400 1212 return false;
Pokitto 6:72f87b7c7400 1213 }
Pokitto 6:72f87b7c7400 1214
Pokitto 6:72f87b7c7400 1215
Pokitto 6:72f87b7c7400 1216 //** EOF **//
Pokitto 6:72f87b7c7400 1217
Pokitto 6:72f87b7c7400 1218
Pokitto 6:72f87b7c7400 1219
Pokitto 6:72f87b7c7400 1220
Pokitto 6:72f87b7c7400 1221
Pokitto 6:72f87b7c7400 1222
Pokitto 6:72f87b7c7400 1223
Pokitto 6:72f87b7c7400 1224
Pokitto 17:10609a82d462 1225