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

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