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

Committer:
Pokitto
Date:
Sun Oct 22 19:02:56 2017 +0000
Revision:
20:fa6899411a24
BLv3 mechanism installed

Who changed what in which revision?

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