emuapi.cpp
1 #define KEYMAP_PRESENT 1 2 3 #define PROGMEM 4 5 #include "pico.h" 6 #include "pico/stdlib.h" 7 #include "hardware/adc.h" 8 #include <stdio.h> 9 #include <string.h> 10 11 extern "C" { 12 #include "emuapi.h" 13 #include "iopins.h" 14 } 15 16 static bool emu_writeConfig(void); 17 static bool emu_readConfig(void); 18 static bool emu_eraseConfig(void); 19 static bool emu_writeGfxConfig(void); 20 static bool emu_readGfxConfig(void); 21 static bool emu_eraseGfxConfig(void); 22 23 #include "pico_dsp.h" 24 extern PICO_DSP tft; 25 26 #define MAX_FILENAME_PATH 64 27 #define NB_FILE_HANDLER 4 28 #define AUTORUN_FILENAME "autorun.txt" 29 #define GFX_CFG_FILENAME "gfxmode.txt" 30 31 #define MAX_FILES 64 32 #define MAX_FILENAME_SIZE 24 33 #define MAX_MENULINES 9 34 #define TEXT_HEIGHT 16 35 #define TEXT_WIDTH 8 36 #define MENU_FILE_XOFFSET (6*TEXT_WIDTH) 37 #define MENU_FILE_YOFFSET (2*TEXT_HEIGHT) 38 #define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH) 39 #define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT) 40 #define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40) 41 #define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT) 42 #define MENU_VBAR_XOFFSET (0*TEXT_WIDTH) 43 #define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET) 44 45 #define MENU_TFT_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) 46 #define MENU_TFT_YOFFSET (MENU_VBAR_YOFFSET+32) 47 #define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) 48 #define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37) 49 50 51 52 static int nbFiles=0; 53 static int curFile=0; 54 static int topFile=0; 55 static char selection[MAX_FILENAME_PATH]=""; 56 static char selected_filename[MAX_FILENAME_SIZE]=""; 57 static char files[MAX_FILES][MAX_FILENAME_SIZE]; 58 static bool menuRedraw=true; 59 60 #if (defined(PICOMPUTER) || defined(PICOZX) ) 61 static const unsigned short * keys; 62 static unsigned char keymatrix[7]; 63 static int keymatrix_hitrow=-1; 64 static bool key_fn=false; 65 static bool key_alt=false; 66 static uint32_t keypress_t_ms=0; 67 static uint32_t last_t_ms=0; 68 static uint32_t hundred_ms_cnt=0; 69 static bool ledflash_toggle=false; 70 #endif 71 static int keyMap; 72 73 static bool joySwapped = false; 74 static uint16_t bLastState; 75 static int xRef; 76 static int yRef; 77 static uint8_t usbnavpad=0; 78 79 static bool menuOn=true; 80 static bool autorun=false; 81 82 83 /******************************** 84 * Generic output and malloc 85 ********************************/ 86 void emu_printf(const char * text) 87 { 88 printf("%s\n",text); 89 } 90 91 void emu_printf(int val) 92 { 93 printf("%d\n",val); 94 } 95 96 void emu_printi(int val) 97 { 98 printf("%d\n",val); 99 } 100 101 void emu_printh(int val) 102 { 103 printf("0x%.8\n",val); 104 } 105 106 static int malbufpt = 0; 107 static char malbuf[EXTRA_HEAP]; 108 109 void * emu_Malloc(int size) 110 { 111 void * retval = malloc(size); 112 if (!retval) { 113 emu_printf("failled to allocate"); 114 emu_printf(size); 115 emu_printf("fallback"); 116 if ( (malbufpt+size) < sizeof(malbuf) ) { 117 retval = (void *)&malbuf[malbufpt]; 118 malbufpt += size; 119 } 120 else { 121 emu_printf("failure to allocate"); 122 } 123 } 124 else { 125 emu_printf("could allocate dynamic "); 126 emu_printf(size); 127 } 128 129 return retval; 130 } 131 132 void * emu_MallocI(int size) 133 { 134 void * retval = NULL; 135 136 if ( (malbufpt+size) < sizeof(malbuf) ) { 137 retval = (void *)&malbuf[malbufpt]; 138 malbufpt += size; 139 emu_printf("could allocate static "); 140 emu_printf(size); 141 } 142 else { 143 emu_printf("failure to allocate"); 144 } 145 146 return retval; 147 } 148 void emu_Free(void * pt) 149 { 150 free(pt); 151 } 152 153 void emu_drawText(unsigned short x, unsigned short y, const char * text, unsigned short fgcolor, unsigned short bgcolor, int doublesize) 154 { 155 tft.drawText(x, y, text, fgcolor, bgcolor, doublesize?true:false); 156 } 157 158 159 /******************************** 160 * OSKB handling 161 ********************************/ 162 #if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA) 163 // On screen keyboard position 164 #define KXOFF 28 //64 165 #define KYOFF 96 166 #define KWIDTH 11 //22 167 #define KHEIGHT 3 168 169 static bool oskbOn = false; 170 static int cxpos = 0; 171 static int cypos = 0; 172 static int oskbMap = 0; 173 static uint16_t oskbBLastState = 0; 174 175 static void lineOSKB2(int kxoff, int kyoff, char * str, int row) 176 { 177 char c[2] = {'A',0}; 178 const char * cpt = str; 179 for (int i=0; i<KWIDTH; i++) 180 { 181 c[0] = *cpt++; 182 c[1] = 0; 183 uint16_t bg = RGBVAL16(0x00,0x00,0xff); 184 if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0xff,0x00,0x00); 185 tft.drawTextNoDma(kxoff+8*i,kyoff, &c[0], RGBVAL16(0x00,0xff,0xff), bg, ((i&1)?false:true)); 186 } 187 } 188 189 static void lineOSKB(int kxoff, int kyoff, char * str, int row) 190 { 191 char c[4] = {' ',0,' ',0}; 192 const char * cpt = str; 193 for (int i=0; i<KWIDTH; i++) 194 { 195 c[1] = *cpt++; 196 uint16_t bg; 197 if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0); 198 else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff); 199 if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0x00,0xff,0xff); 200 tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+0 , " ", RGBVAL16(0x00,0x00,0x00), bg, false); 201 tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+8 , &c[0], RGBVAL16(0x00,0x00,0x00), bg, true); 202 tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+24, " ", RGBVAL16(0x00,0x00,0x00), bg, false); 203 } 204 } 205 206 207 static void drawOskb(void) 208 { 209 // lineOSKB2(KXOFF,KYOFF+0, (char *)"Q1W2E3R4T5Y6U7I8O9P0<=", 0); 210 // lineOSKB2(KXOFF,KYOFF+16, (char *)" A!S@D#F$G%H+J&K*L-EN", 1); 211 // lineOSKB2(KXOFF,KYOFF+32, (char *)" Z(X)C?V/B\"N<M>.,SP ", 2); 212 /* 213 if (oskbMap == 0) { 214 lineOSKB(KXOFF,KYOFF, keylables_map1_0, 0); 215 lineOSKB(KXOFF,KYOFF, keylables_map1_1, 1); 216 lineOSKB(KXOFF,KYOFF, keylables_map1_2, 2); 217 } 218 else if (oskbMap == 1) { 219 lineOSKB(KXOFF,KYOFF, keylables_map2_0, 0); 220 lineOSKB(KXOFF,KYOFF, keylables_map2_1, 1); 221 lineOSKB(KXOFF,KYOFF, keylables_map2_2, 2); 222 } 223 else { 224 lineOSKB(KXOFF,KYOFF, keylables_map3_0, 0); 225 lineOSKB(KXOFF,KYOFF, keylables_map3_1, 1); 226 lineOSKB(KXOFF,KYOFF, keylables_map3_2, 2); 227 } 228 */ 229 } 230 231 void toggleOskb(bool forceoff) { 232 if (forceoff) oskbOn=true; 233 if (oskbOn) { 234 oskbOn = false; 235 tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); 236 tft.drawTextNoDma(0,32, "Press USER2 to toggle onscreen keyboard.", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true); 237 } else { 238 oskbOn = true; 239 tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); 240 tft.drawTextNoDma(0,32, " Press USER2 to exit onscreen keyboard. ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true); 241 tft.drawTextNoDma(0,64, " (USER1 to toggle between keymaps) ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true); 242 tft.drawRectNoDma(KXOFF,KYOFF, 22*8, 3*16, RGBVAL16(0x00,0x00,0xFF)); 243 drawOskb(); 244 } 245 } 246 247 static int handleOskb(void) 248 { 249 int retval = 0; 250 251 uint16_t bClick = bLastState & ~oskbBLastState; 252 oskbBLastState = bLastState; 253 /* 254 static const char * digits = "0123456789ABCDEF"; 255 char buf[5] = {0,0,0,0,0}; 256 int val = bClick; 257 buf[0] = digits[(val>>12)&0xf]; 258 buf[1] = digits[(val>>8)&0xf]; 259 buf[2] = digits[(val>>4)&0xf]; 260 buf[3] = digits[val&0xf]; 261 tft.drawTextNoDma(0,KYOFF+ 64,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),1); 262 */ 263 if (bClick & MASK_KEY_USER2) 264 { 265 toggleOskb(false); 266 } 267 if (oskbOn) 268 { 269 bool updated = true; 270 if (bClick & MASK_KEY_USER1) 271 { 272 oskbMap += 1; 273 if (oskbMap == 3) oskbMap = 0; 274 } 275 else if (bClick & MASK_JOY2_LEFT) 276 { 277 cxpos++; 278 if (cxpos >= KWIDTH) cxpos = 0; 279 } 280 else if (bClick & MASK_JOY2_RIGHT) 281 { 282 cxpos--; 283 if (cxpos < 0) cxpos = KWIDTH-1; 284 } 285 else if (bClick & MASK_JOY2_DOWN) 286 { 287 cypos++; 288 if (cypos >= KHEIGHT) cypos = 0; 289 } 290 else if (bClick & MASK_JOY2_UP) 291 { 292 cypos--; 293 if (cypos < 0) cypos = KHEIGHT-1; 294 } 295 else if (oskbBLastState & MASK_JOY2_BTN) 296 { 297 retval = cypos*KWIDTH+cxpos+1; 298 if (retval) { 299 retval--; 300 //if (retval & 1) retval = key_map2[retval>>1]; 301 //else retval = key_map1[retval>>1]; 302 if (oskbMap == 0) { 303 retval = key_map1[retval]; 304 } 305 else if (oskbMap == 1) { 306 retval = key_map2[retval]; 307 } 308 else { 309 retval = key_map3[retval]; 310 } 311 //if (retval) { toggleOskb(true); updated=false; }; 312 } 313 } 314 else { 315 updated=false; 316 } 317 if (updated) drawOskb(); 318 } 319 320 return retval; 321 } 322 #endif 323 324 /******************************** 325 * Input and keyboard 326 ********************************/ 327 int emu_ReadAnalogJoyX(int min, int max) 328 { 329 adc_select_input(0); 330 int val = adc_read(); 331 #if INVX 332 val = 4095 - val; 333 #endif 334 val = val-xRef; 335 val = ((val*140)/100); 336 if ( (val > -512) && (val < 512) ) val = 0; 337 val = val+2048; 338 return (val*(max-min))/4096; 339 } 340 341 int emu_ReadAnalogJoyY(int min, int max) 342 { 343 adc_select_input(1); 344 int val = adc_read(); 345 #if INVY 346 val = 4095 - val; 347 #endif 348 val = val-yRef; 349 val = ((val*120)/100); 350 if ( (val > -512) && (val < 512) ) val = 0; 351 //val = (val*(max-min))/4096; 352 val = val+2048; 353 //return val+(max-min)/2; 354 return (val*(max-min))/4096; 355 } 356 357 358 static uint16_t readAnalogJoystick(void) 359 { 360 uint16_t joysval = 0; 361 #ifdef PIN_JOY2_A1X 362 int xReading = emu_ReadAnalogJoyX(0,256); 363 if (xReading > 128) joysval |= MASK_JOY2_LEFT; 364 else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; 365 366 int yReading = emu_ReadAnalogJoyY(0,256); 367 if (yReading < 128) joysval |= MASK_JOY2_UP; 368 else if (yReading > 128) joysval |= MASK_JOY2_DOWN; 369 #endif 370 // First joystick 371 #if INVY 372 #ifdef PIN_JOY2_1 373 if ( !gpio_get(PIN_JOY2_1) ) joysval |= MASK_JOY2_DOWN; 374 #endif 375 #ifdef PIN_JOY2_2 376 if ( !gpio_get(PIN_JOY2_2) ) joysval |= MASK_JOY2_UP; 377 #endif 378 #else 379 #ifdef PIN_JOY2_1 380 if ( !gpio_get(PIN_JOY2_1) ) joysval |= MASK_JOY2_UP; 381 #endif 382 #ifdef PIN_JOY2_2 383 if ( !gpio_get(PIN_JOY2_2) ) joysval |= MASK_JOY2_DOWN; 384 #endif 385 #endif 386 #if INVX 387 #ifdef PIN_JOY2_3 388 if ( !gpio_get(PIN_JOY2_3) ) joysval |= MASK_JOY2_LEFT; 389 #endif 390 #ifdef PIN_JOY2_4 391 if ( !gpio_get(PIN_JOY2_4) ) joysval |= MASK_JOY2_RIGHT; 392 #endif 393 #else 394 #ifdef PIN_JOY2_3 395 if ( !gpio_get(PIN_JOY2_3) ) joysval |= MASK_JOY2_RIGHT; 396 #endif 397 #ifdef PIN_JOY2_4 398 if ( !gpio_get(PIN_JOY2_4) ) joysval |= MASK_JOY2_LEFT; 399 #endif 400 #endif 401 #ifdef PIN_JOY2_BTN 402 joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); 403 #endif 404 405 return (joysval); 406 } 407 408 409 int emu_SwapJoysticks(int statusOnly) { 410 if (!statusOnly) { 411 if (joySwapped) { 412 joySwapped = false; 413 } 414 else { 415 joySwapped = true; 416 } 417 } 418 return(joySwapped?1:0); 419 } 420 421 int emu_GetPad(void) 422 { 423 return(bLastState/*|((joySwapped?1:0)<<7)*/); 424 } 425 426 int emu_ReadKeys(void) 427 { 428 uint16_t retval; 429 uint16_t j1 = readAnalogJoystick(); 430 uint16_t j2 = 0; 431 432 // Second joystick 433 #if INVY 434 #ifdef PIN_JOY1_1 435 if ( !gpio_get(PIN_JOY1_1) ) j2 |= MASK_JOY2_DOWN; 436 #endif 437 #ifdef PIN_JOY1_2 438 if ( !gpio_get(PIN_JOY1_2) ) j2 |= MASK_JOY2_UP; 439 #endif 440 #else 441 #ifdef PIN_JOY1_1 442 if ( !gpio_get(PIN_JOY1_1) ) j2 |= MASK_JOY2_UP; 443 #endif 444 #ifdef PIN_JOY1_2 445 if ( !gpio_get(PIN_JOY1_2) ) j2 |= MASK_JOY2_DOWN; 446 #endif 447 #endif 448 #if INVX 449 #ifdef PIN_JOY1_3 450 if ( !gpio_get(PIN_JOY1_3) ) j2 |= MASK_JOY2_LEFT; 451 #endif 452 #ifdef PIN_JOY1_4 453 if ( !gpio_get(PIN_JOY1_4) ) j2 |= MASK_JOY2_RIGHT; 454 #endif 455 #else 456 #ifdef PIN_JOY1_3 457 if ( !gpio_get(PIN_JOY1_3) ) j2 |= MASK_JOY2_RIGHT; 458 #endif 459 #ifdef PIN_JOY1_4 460 if ( !gpio_get(PIN_JOY1_4) ) j2 |= MASK_JOY2_LEFT; 461 #endif 462 #endif 463 #ifdef PIN_JOY1_BTN 464 if ( !gpio_get(PIN_JOY1_BTN) ) j2 |= MASK_JOY2_BTN; 465 #endif 466 467 468 if (joySwapped) { 469 retval = ((j1 << 8) | j2); 470 } 471 else { 472 retval = ((j2 << 8) | j1); 473 } 474 475 if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP; 476 if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN; 477 if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT; 478 if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT; 479 if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN; 480 481 #ifdef PIN_KEY_USER1 482 if ( !gpio_get(PIN_KEY_USER1) ) retval |= MASK_KEY_USER1; 483 #endif 484 #ifdef PIN_KEY_USER2 485 if ( !gpio_get(PIN_KEY_USER2) ) retval |= MASK_KEY_USER2; 486 #endif 487 #ifdef PIN_KEY_USER3 488 if ( !gpio_get(PIN_KEY_USER3) ) retval |= MASK_KEY_USER3; 489 #endif 490 #ifdef PIN_KEY_USER4 491 if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; 492 #endif 493 494 495 #if (defined(PICOMPUTER) || defined(PICOZX) ) 496 keymatrix_hitrow = -1; 497 unsigned char row; 498 #ifdef PICOZX 499 unsigned short cols[7]={KCOLOUT1,KCOLOUT2,KCOLOUT3,KCOLOUT4,KCOLOUT5,KCOLOUT6,KCOLOUT7}; 500 unsigned char keymatrixtmp[7]; 501 for (int i=0;i<7;i++){ 502 #else 503 unsigned short cols[6]={KCOLOUT1,KCOLOUT2,KCOLOUT3,KCOLOUT4,KCOLOUT5,KCOLOUT6}; 504 unsigned char keymatrixtmp[6]; 505 for (int i=0;i<6;i++){ 506 #endif 507 gpio_set_dir(cols[i], GPIO_OUT); 508 gpio_put(cols[i], 0); 509 #ifdef SWAP_ALT_DEL 510 sleep_us(1); 511 //__asm volatile ("nop\n"); // 4-8ns 512 #endif 513 row=0; 514 #ifdef PICOZX 515 row |= (gpio_get(KROWIN1) ? 0 : 0x04); 516 row |= (gpio_get(KROWIN1) ? 0 : 0x04); 517 row |= (gpio_get(KROWIN1) ? 0 : 0x04); 518 row |= (gpio_get(KROWIN1) ? 0 : 0x04); 519 row |= (gpio_get(KROWIN2) ? 0 : 0x01); 520 row |= (gpio_get(KROWIN3) ? 0 : 0x08); 521 row |= (gpio_get(KROWIN4) ? 0 : 0x02); 522 row |= (gpio_get(KROWIN5) ? 0 : 0x10); 523 row |= (gpio_get(KROWIN6) ? 0 : 0x20); 524 row |= (gpio_get(KROWIN7) ? 0 : 0x40); 525 #else 526 row |= (gpio_get(KROWIN2) ? 0 : 0x01); 527 row |= (gpio_get(KROWIN2) ? 0 : 0x01); 528 row |= (gpio_get(KROWIN2) ? 0 : 0x01); 529 row |= (gpio_get(KROWIN2) ? 0 : 0x01); 530 row |= (gpio_get(KROWIN4) ? 0 : 0x02); 531 row |= (gpio_get(KROWIN1) ? 0 : 0x04); 532 row |= (gpio_get(KROWIN3) ? 0 : 0x08); 533 row |= (gpio_get(KROWIN5) ? 0 : 0x10); 534 row |= (gpio_get(KROWIN6) ? 0 : 0x20); 535 #endif 536 //gpio_set_dir(cols[i], GPIO_OUT); 537 gpio_put(cols[i], 1); 538 gpio_set_dir(cols[i], GPIO_IN); 539 gpio_disable_pulls(cols[i]); 540 keymatrixtmp[i] = row; 541 } 542 543 #ifdef SWAP_ALT_DEL 544 // Swap ALT and DEL 545 unsigned char alt = keymatrixtmp[0] & 0x02; 546 unsigned char del = keymatrixtmp[5] & 0x20; 547 keymatrixtmp[0] &= ~0x02; 548 keymatrixtmp[5] &= ~0x20; 549 if (alt) keymatrixtmp[5] |= 0x20; 550 if (del) keymatrixtmp[0] |= 0x02; 551 #endif 552 553 554 #ifdef PICOZX 555 for (int i=0;i<7;i++){ 556 #else 557 bool alt_pressed=false; 558 if ( keymatrixtmp[5] & 0x20 ) {alt_pressed=true; keymatrixtmp[5] &= ~0x20;}; 559 for (int i=0;i<6;i++){ 560 #endif 561 row = keymatrixtmp[i]; 562 if (row) keymatrix_hitrow=i; 563 keymatrix[i] = row; 564 } 565 566 #ifdef PICOZX 567 //row = keymatrix[6]; 568 if ( row & 0x02 ) retval |= MASK_KEY_USER1; 569 if ( row & 0x10 ) retval |= MASK_KEY_USER2; 570 if ( row & 0x20 ) retval |= MASK_KEY_USER3; 571 if ( row & 0x40 ) retval |= MASK_KEY_USER4; 572 row = keymatrix[0]; 573 key_fn = false; 574 key_alt = false; 575 if ( row & 0x20 ) {key_fn = true; keymatrix[0] &= ~0x20;} 576 if ( row & 0x40 ) {key_alt = true;keymatrix[0] &= ~0x40; } 577 //19,20,21,22,26,27,28 578 #if INVX 579 if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; 580 if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; 581 #else 582 if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; 583 if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; 584 #endif 585 #if INVY 586 if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; 587 if ( row & 0x10 ) retval |= MASK_JOY2_UP; 588 #else 589 if ( row & 0x10 ) retval |= MASK_JOY2_DOWN; 590 if ( row & 0x8 ) retval |= MASK_JOY2_UP; 591 #endif 592 if ( row & 0x04 ) retval |= MASK_JOY2_BTN; 593 594 #else // end PICOZX 595 //6,9,15,8,7,22 596 #if INVX 597 if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; 598 if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; 599 #else 600 if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; 601 if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; 602 #endif 603 #if INVY 604 if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; 605 if ( row & 0x4 ) retval |= MASK_JOY2_UP; 606 #else 607 if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; 608 if ( row & 0x8 ) retval |= MASK_JOY2_UP; 609 #endif 610 if ( row & 0x10 ) retval |= MASK_JOY2_BTN; 611 612 if ( key_fn ) retval |= MASK_KEY_USER2; 613 if ( ( key_fn ) && (keymatrix[0] == 0x02 )) retval |= MASK_KEY_USER1; 614 615 // Handle LED flash 616 uint32_t time_ms=to_ms_since_boot (get_absolute_time()); 617 if ((time_ms-last_t_ms) > 100) { 618 last_t_ms = time_ms; 619 if (ledflash_toggle == false) { 620 ledflash_toggle = true; 621 } 622 else { 623 ledflash_toggle = false; 624 } 625 } 626 627 if ( alt_pressed ) { 628 if (key_fn == false) 629 { 630 // Release to Press transition 631 if (hundred_ms_cnt == 0) { 632 keypress_t_ms=time_ms; 633 hundred_ms_cnt += 1; // 1 634 } 635 else { 636 hundred_ms_cnt += 1; // 2 637 if (hundred_ms_cnt >= 2) 638 { 639 hundred_ms_cnt = 0; 640 /* 641 if ( (time_ms-keypress_t_ms) < 500) 642 { 643 if (key_alt == false) 644 { 645 key_alt = true; 646 } 647 else 648 { 649 key_alt = false; 650 } 651 } 652 */ 653 } 654 } 655 } 656 else { 657 // Keep press 658 if (hundred_ms_cnt == 1) { 659 if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 2000) 660 { 661 if (key_alt == false) 662 { 663 key_alt = true; 664 } 665 else 666 { 667 key_alt = false; 668 } 669 hundred_ms_cnt = 0; 670 } 671 } 672 } 673 key_fn = true; 674 } 675 else { 676 key_fn = false; 677 } 678 679 #ifdef KLED 680 // Handle LED 681 if (key_alt == true) { 682 gpio_put(KLED, (ledflash_toggle?1:0)); 683 } 684 else { 685 if (key_fn == true) { 686 gpio_put(KLED, 1); 687 } 688 else { 689 gpio_put(KLED, 0); 690 } 691 } 692 #endif 693 694 #endif 695 696 697 #endif 698 699 //Serial.println(retval,HEX); 700 701 if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) 702 || (retval & MASK_KEY_USER4 ) ) 703 { 704 } 705 706 #if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA) 707 if (oskbOn) { 708 retval |= MASK_OSKB; 709 } 710 #endif 711 712 return (retval); 713 } 714 715 unsigned short emu_DebounceLocalKeys(void) 716 { 717 uint16_t bCurState = emu_ReadKeys(); 718 uint16_t bClick = bCurState & ~bLastState; 719 bLastState = bCurState; 720 721 return (bClick); 722 } 723 724 int emu_ReadI2CKeyboard(void) { 725 int retval=0; 726 #if (defined(PICOMPUTER) || defined(PICOZX) ) 727 if (key_alt) { 728 keys = (const unsigned short *)key_map3; 729 } 730 else if (key_fn) { 731 keys = (const unsigned short *)key_map2; 732 } 733 else { 734 keys = (const unsigned short *)key_map1; 735 } 736 if (keymatrix_hitrow >=0 ) { 737 unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; 738 for (int i=0; i<sizeof(matkeys)/sizeof(unsigned short); i++) { 739 if (match == matkeys[i]) { 740 hundred_ms_cnt = 0; 741 return (keys[i]); 742 } 743 } 744 } 745 #endif 746 #if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA) 747 if (!menuOn) { 748 retval = handleOskb(); 749 } 750 #endif 751 return(retval); 752 } 753 754 unsigned char emu_ReadI2CKeyboard2(int row) { 755 int retval=0; 756 #if (defined(PICOMPUTER) || defined(PICOZX) ) 757 retval = keymatrix[row]; 758 #endif 759 return retval; 760 } 761 762 763 void emu_InitJoysticks(void) { 764 765 // Second Joystick 766 #ifdef PIN_JOY1_1 767 gpio_set_pulls(PIN_JOY1_1,true,false); 768 gpio_set_dir(PIN_JOY1_1,GPIO_IN); 769 #endif 770 #ifdef PIN_JOY1_2 771 gpio_set_pulls(PIN_JOY1_2,true,false); 772 gpio_set_dir(PIN_JOY1_2,GPIO_IN); 773 #endif 774 #ifdef PIN_JOY1_3 775 gpio_set_pulls(PIN_JOY1_3,true,false); 776 gpio_set_dir(PIN_JOY1_3,GPIO_IN); 777 #endif 778 #ifdef PIN_JOY1_4 779 gpio_set_pulls(PIN_JOY1_4,true,false); 780 gpio_set_dir(PIN_JOY1_4,GPIO_IN); 781 #endif 782 #ifdef PIN_JOY1_BTN 783 gpio_set_pulls(PIN_JOY1_BTN,true,false); 784 gpio_set_dir(PIN_JOY1_BTN,GPIO_IN); 785 #endif 786 787 // User keys 788 #ifdef PIN_KEY_USER1 789 gpio_set_pulls(PIN_KEY_USER1,true,false); 790 gpio_set_dir(PIN_KEY_USER1,GPIO_IN); 791 #endif 792 #ifdef PIN_KEY_USER2 793 gpio_set_dir(PIN_KEY_USER2,GPIO_IN); 794 gpio_set_pulls(PIN_KEY_USER2,true,false); 795 #endif 796 #ifdef PIN_KEY_USER3 797 gpio_set_pulls(PIN_KEY_USER3,true,false); 798 gpio_set_dir(PIN_KEY_USER3,GPIO_IN); 799 #endif 800 #ifdef PIN_KEY_USER4 801 gpio_set_pulls(PIN_KEY_USER4,true,false); 802 gpio_set_dir(PIN_KEY_USER4,GPIO_IN); 803 #endif 804 805 // First Joystick 806 #ifdef PIN_JOY2_1 807 gpio_set_pulls(PIN_JOY2_1,true,false); 808 gpio_set_dir(PIN_JOY2_1,GPIO_IN); 809 gpio_set_input_enabled(PIN_JOY2_1, true); // Force ADC as digital input 810 #endif 811 #ifdef PIN_JOY2_2 812 gpio_set_pulls(PIN_JOY2_2,true,false); 813 gpio_set_dir(PIN_JOY2_2,GPIO_IN); 814 gpio_set_input_enabled(PIN_JOY2_2, true); // Force ADC as digital input 815 #endif 816 #ifdef PIN_JOY2_3 817 gpio_set_pulls(PIN_JOY2_3,true,false); 818 gpio_set_dir(PIN_JOY2_3,GPIO_IN); 819 gpio_set_input_enabled(PIN_JOY2_3, true); // Force ADC as digital input 820 #endif 821 #ifdef PIN_JOY2_4 822 gpio_set_pulls(PIN_JOY2_4,true,false); 823 gpio_set_dir(PIN_JOY2_4,GPIO_IN); 824 #endif 825 #ifdef PIN_JOY2_BTN 826 gpio_set_pulls(PIN_JOY2_BTN,true,false); 827 gpio_set_dir(PIN_JOY2_BTN,GPIO_IN); 828 #endif 829 830 #ifdef PIN_JOY2_A1X 831 adc_init(); 832 adc_gpio_init(PIN_JOY2_A1X); 833 adc_gpio_init(PIN_JOY2_A2Y); 834 xRef=0; yRef=0; 835 for (int i=0; i<10; i++) { 836 adc_select_input(0); 837 xRef += adc_read(); 838 adc_select_input(1); 839 yRef += adc_read(); 840 sleep_ms(20); 841 } 842 #if INVX 843 xRef = 4095 -xRef/10; 844 #else 845 xRef /= 10; 846 #endif 847 #if INVY 848 yRef = 4095 -yRef/10; 849 #else 850 yRef /= 10; 851 #endif 852 #endif 853 854 #if (defined(PICOMPUTER) || defined(PICOZX) ) 855 // keyboard LED 856 #ifdef KLED 857 gpio_init(KLED); 858 gpio_set_dir(KLED, GPIO_OUT); 859 gpio_put(KLED, 1); 860 #endif 861 // Output (rows) 862 gpio_init(KCOLOUT1); 863 gpio_init(KCOLOUT2); 864 gpio_init(KCOLOUT3); 865 gpio_init(KCOLOUT4); 866 gpio_init(KCOLOUT5); 867 gpio_init(KCOLOUT6); 868 #ifdef PICOZX 869 gpio_init(KCOLOUT7); 870 #endif 871 gpio_set_dir(KCOLOUT1, GPIO_OUT); 872 gpio_set_dir(KCOLOUT2, GPIO_OUT); 873 gpio_set_dir(KCOLOUT3, GPIO_OUT); 874 gpio_set_dir(KCOLOUT4, GPIO_OUT); 875 gpio_set_dir(KCOLOUT5, GPIO_OUT); 876 gpio_set_dir(KCOLOUT6, GPIO_OUT); 877 #ifdef PICOZX 878 gpio_set_dir(KCOLOUT7, GPIO_OUT); 879 #endif 880 gpio_put(KCOLOUT1, 1); 881 gpio_put(KCOLOUT2, 1); 882 gpio_put(KCOLOUT3, 1); 883 gpio_put(KCOLOUT4, 1); 884 gpio_put(KCOLOUT5, 1); 885 gpio_put(KCOLOUT6, 1); 886 #ifdef PICOZX 887 gpio_put(KCOLOUT7, 1); 888 #endif 889 // but set as input floating when not used! 890 gpio_set_dir(KCOLOUT1, GPIO_IN); 891 gpio_set_dir(KCOLOUT2, GPIO_IN); 892 gpio_set_dir(KCOLOUT3, GPIO_IN); 893 gpio_set_dir(KCOLOUT4, GPIO_IN); 894 gpio_set_dir(KCOLOUT5, GPIO_IN); 895 gpio_set_dir(KCOLOUT6, GPIO_IN); 896 #ifdef PICOZX 897 gpio_set_dir(KCOLOUT7, GPIO_IN); 898 #endif 899 gpio_disable_pulls(KCOLOUT1); 900 gpio_disable_pulls(KCOLOUT2); 901 gpio_disable_pulls(KCOLOUT3); 902 gpio_disable_pulls(KCOLOUT4); 903 gpio_disable_pulls(KCOLOUT5); 904 gpio_disable_pulls(KCOLOUT6); 905 #ifdef PICOZX 906 gpio_disable_pulls(KCOLOUT7); 907 #endif 908 // Input pins (cols) 909 gpio_init(KROWIN1); 910 gpio_init(KROWIN2); 911 gpio_init(KROWIN3); 912 gpio_init(KROWIN4); 913 gpio_init(KROWIN5); 914 gpio_init(KROWIN6); 915 #ifdef PICOZX 916 gpio_init(KROWIN7); 917 #endif 918 gpio_set_dir(KROWIN1,GPIO_IN); 919 gpio_set_dir(KROWIN2,GPIO_IN); 920 gpio_set_dir(KROWIN3,GPIO_IN); 921 gpio_set_dir(KROWIN4,GPIO_IN); 922 gpio_set_dir(KROWIN5,GPIO_IN); 923 gpio_set_dir(KROWIN6,GPIO_IN); 924 #ifdef PICOZX 925 gpio_set_dir(KROWIN7,GPIO_IN); 926 #endif 927 gpio_pull_up(KROWIN1); 928 gpio_pull_up(KROWIN2); 929 gpio_pull_up(KROWIN3); 930 gpio_pull_up(KROWIN4); 931 gpio_pull_up(KROWIN5); 932 gpio_pull_up(KROWIN6); 933 #ifdef PICOZX 934 gpio_pull_up(KROWIN7); 935 #endif 936 #endif 937 } 938 939 int emu_setKeymap(int index) { 940 return 0; 941 } 942 943 944 945 /******************************** 946 * Menu file loader UI 947 ********************************/ 948 #include "ff.h" 949 static FATFS fatfs; 950 static FIL file; 951 extern "C" int sd_init_driver(void); 952 953 #ifdef FILEBROWSER 954 static int readNbFiles(char * rootdir) { 955 int totalFiles = 0; 956 957 DIR dir; 958 FILINFO entry; 959 FRESULT fr = f_findfirst(&dir, &entry, rootdir, "*"); 960 while ( (fr == FR_OK) && (entry.fname[0]) && (totalFiles<MAX_FILES) ) { 961 if (!entry.fname[0]) { 962 // no more files 963 break; 964 } 965 char * filename = entry.fname; 966 if ( !(entry.fattrib & AM_DIR) ) { 967 if (strcmp(filename,AUTORUN_FILENAME)) { 968 strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1); 969 totalFiles++; 970 } 971 } 972 else { 973 if ( (strcmp(filename,".")) && (strcmp(filename,"..")) ) { 974 strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1); 975 totalFiles++; 976 } 977 } 978 fr = f_findnext(&dir, &entry); 979 } 980 f_closedir(&dir); 981 982 return totalFiles; 983 } 984 985 986 987 void backgroundMenu(void) { 988 menuRedraw=true; 989 tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); 990 tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true); 991 } 992 993 994 static void menuLeft(void) 995 { 996 #if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA) 997 toggleOskb(true); 998 #endif 999 } 1000 1001 1002 bool menuActive(void) 1003 { 1004 return (menuOn); 1005 } 1006 1007 void toggleMenu(bool on) { 1008 if (on) { 1009 menuOn = true; 1010 backgroundMenu(); 1011 } else { 1012 tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); 1013 menuOn = false; 1014 } 1015 } 1016 1017 int handleMenu(uint16_t bClick) 1018 { 1019 if (autorun) { 1020 menuLeft(); 1021 toggleMenu(false); 1022 menuRedraw=false; 1023 return (ACTION_RUN); 1024 } 1025 1026 if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_KEY_USER1) || (bClick & MASK_KEY_USER4) ) { 1027 char newpath[MAX_FILENAME_PATH]; 1028 strcpy(newpath, selection); 1029 strcat(newpath, "/"); 1030 strcat(newpath, selected_filename); 1031 strcpy(selection,newpath); 1032 emu_printf("new filepath is"); 1033 emu_printf(selection); 1034 FILINFO entry; 1035 FRESULT fr; 1036 fr = f_stat(selection, &entry); 1037 if ( (fr == FR_OK) && (entry.fattrib & AM_DIR) ) { 1038 curFile = 0; 1039 nbFiles = readNbFiles(selection); 1040 menuRedraw=true; 1041 } 1042 else 1043 { 1044 #ifdef PICOMPUTER 1045 if (key_alt) { 1046 emu_writeConfig(); 1047 } 1048 #endif 1049 #ifdef PICOZX 1050 if (bClick & MASK_KEY_USER4) { 1051 emu_writeConfig(); 1052 } 1053 #endif 1054 menuLeft(); 1055 toggleMenu(false); 1056 menuRedraw=false; 1057 #ifdef PICOZX 1058 if ( tft.getMode() != MODE_VGA_320x240) { 1059 if ( (bClick & MASK_KEY_USER1) ) { 1060 tft.begin(MODE_VGA_320x240); 1061 } 1062 } 1063 #endif 1064 return (ACTION_RUN); 1065 } 1066 } 1067 else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) { 1068 if (curFile!=0) { 1069 menuRedraw=true; 1070 curFile--; 1071 } 1072 } 1073 else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) { 1074 if ((curFile-9)>=0) { 1075 menuRedraw=true; 1076 curFile -= 9; 1077 } else if (curFile!=0) { 1078 menuRedraw=true; 1079 curFile--; 1080 } 1081 } 1082 else if ( (bClick & MASK_JOY2_DOWN) || (bClick & MASK_JOY1_DOWN) ) { 1083 if ((curFile<(nbFiles-1)) && (nbFiles)) { 1084 curFile++; 1085 menuRedraw=true; 1086 } 1087 } 1088 else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) { 1089 if ((curFile<(nbFiles-9)) && (nbFiles)) { 1090 curFile += 9; 1091 menuRedraw=true; 1092 } 1093 else if ((curFile<(nbFiles-1)) && (nbFiles)) { 1094 curFile++; 1095 menuRedraw=true; 1096 } 1097 } 1098 else if ( (bClick & MASK_KEY_USER2) ) { 1099 emu_SwapJoysticks(0); 1100 menuRedraw=true; 1101 } 1102 1103 if (menuRedraw && nbFiles) { 1104 int fileIndex = 0; 1105 tft.drawRectNoDma(MENU_FILE_XOFFSET,MENU_FILE_YOFFSET, MENU_FILE_W, MENU_FILE_H, MENU_FILE_BGCOLOR); 1106 // if (curFile <= (MAX_MENULINES/2-1)) topFile=0; 1107 // else topFile=curFile-(MAX_MENULINES/2); 1108 if (curFile <= (MAX_MENULINES-1)) topFile=0; 1109 else topFile=curFile-(MAX_MENULINES/2); 1110 1111 int i=0; 1112 while (i<MAX_MENULINES) { 1113 if (fileIndex>=nbFiles) { 1114 // no more files 1115 break; 1116 } 1117 char * filename = &files[fileIndex][0]; 1118 if (fileIndex >= topFile) { 1119 if ((i+topFile) < nbFiles ) { 1120 if ((i+topFile)==curFile) { 1121 tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); 1122 strcpy(selected_filename,filename); 1123 } 1124 else { 1125 tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true); 1126 } 1127 } 1128 i++; 1129 } 1130 fileIndex++; 1131 } 1132 1133 1134 tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false); 1135 menuRedraw=false; 1136 } 1137 1138 return (ACTION_NONE); 1139 } 1140 1141 char * menuSelection(void) 1142 { 1143 return (selection); 1144 } 1145 #endif 1146 1147 /******************************** 1148 * File IO 1149 ********************************/ 1150 int emu_FileOpen(const char * filepath, const char * mode) 1151 { 1152 int retval = 0; 1153 1154 emu_printf("FileOpen..."); 1155 emu_printf(filepath); 1156 if( !(f_open(&file, filepath, FA_READ)) ) { 1157 retval = 1; 1158 } 1159 else { 1160 emu_printf("FileOpen failed"); 1161 } 1162 return (retval); 1163 } 1164 1165 int emu_FileRead(void * buf, int size, int handler) 1166 { 1167 unsigned int retval=0; 1168 f_read (&file, (void*)buf, size, &retval); 1169 return retval; 1170 } 1171 1172 int emu_FileGetc(int handler) 1173 { 1174 unsigned char c; 1175 unsigned int retval=0; 1176 if( !(f_read (&file, &c, 1, &retval)) ) 1177 if (retval != 1) { 1178 emu_printf("emu_FileGetc failed"); 1179 } 1180 return (int)c; 1181 } 1182 1183 void emu_FileClose(int handler) 1184 { 1185 f_close(&file); 1186 } 1187 1188 int emu_FileSeek(int handler, int seek, int origin) 1189 { 1190 f_lseek(&file, seek); 1191 return (seek); 1192 } 1193 1194 int emu_FileTell(int handler) 1195 { 1196 return (f_tell(&file)); 1197 } 1198 1199 1200 unsigned int emu_FileSize(const char * filepath) 1201 { 1202 int filesize=0; 1203 emu_printf("FileSize..."); 1204 emu_printf(filepath); 1205 FILINFO entry; 1206 f_stat(filepath, &entry); 1207 filesize = entry.fsize; 1208 return(filesize); 1209 } 1210 1211 unsigned int emu_LoadFile(const char * filepath, void * buf, int size) 1212 { 1213 int filesize = 0; 1214 1215 emu_printf("LoadFile..."); 1216 emu_printf(filepath); 1217 if( !(f_open(&file, filepath, FA_READ)) ) { 1218 filesize = f_size(&file); 1219 emu_printf(filesize); 1220 if (size >= filesize) 1221 { 1222 unsigned int retval=0; 1223 if( (f_read (&file, buf, filesize, &retval)) ) { 1224 emu_printf("File read failed"); 1225 } 1226 } 1227 f_close(&file); 1228 } 1229 1230 return(filesize); 1231 } 1232 1233 static FIL outfile; 1234 1235 static bool emu_writeGfxConfig(void) 1236 { 1237 bool retval = false; 1238 if( !(f_open(&outfile, "/" GFX_CFG_FILENAME, FA_CREATE_NEW | FA_WRITE)) ) { 1239 f_close(&outfile); 1240 retval = true; 1241 } 1242 return retval; 1243 } 1244 1245 static bool emu_readGfxConfig(void) 1246 { 1247 bool retval = false; 1248 if( !(f_open(&outfile, "/" GFX_CFG_FILENAME, FA_READ)) ) { 1249 f_close(&outfile); 1250 retval = true; 1251 } 1252 return retval; 1253 } 1254 1255 static bool emu_eraseGfxConfig(void) 1256 { 1257 f_unlink ("/" GFX_CFG_FILENAME); 1258 return true; 1259 } 1260 1261 static bool emu_writeConfig(void) 1262 { 1263 bool retval = false; 1264 if( !(f_open(&outfile, ROMSDIR "/" AUTORUN_FILENAME, FA_CREATE_NEW | FA_WRITE)) ) { 1265 unsigned int sizeread=0; 1266 if( (f_write (&outfile, selection, strlen(selection), &sizeread)) ) { 1267 emu_printf("Config write failed"); 1268 } 1269 else { 1270 retval = true; 1271 } 1272 f_close(&outfile); 1273 } 1274 return retval; 1275 } 1276 1277 static bool emu_readConfig(void) 1278 { 1279 bool retval = false; 1280 if( !(f_open(&outfile, ROMSDIR "/" AUTORUN_FILENAME, FA_READ)) ) { 1281 unsigned int filesize = f_size(&outfile); 1282 unsigned int sizeread=0; 1283 if( (f_read (&outfile, selection, filesize, &sizeread)) ) { 1284 emu_printf("Config read failed"); 1285 } 1286 else { 1287 if (sizeread == filesize) { 1288 selection[filesize]=0; 1289 retval = true; 1290 } 1291 } 1292 f_close(&outfile); 1293 } 1294 return retval; 1295 } 1296 1297 static bool emu_eraseConfig(void) 1298 { 1299 f_unlink (ROMSDIR "/" AUTORUN_FILENAME); 1300 return true; 1301 } 1302 1303 1304 /******************************** 1305 * Initialization 1306 ********************************/ 1307 void emu_init(void) 1308 { 1309 bool forceVga = false; 1310 #ifdef FILEBROWSER 1311 sd_init_driver(); 1312 FRESULT fr = f_mount(&fatfs, "0:", 1); 1313 1314 forceVga = emu_readGfxConfig(); 1315 1316 strcpy(selection,ROMSDIR); 1317 nbFiles = readNbFiles(selection); 1318 1319 emu_printf("SD initialized, files found: "); 1320 emu_printi(nbFiles); 1321 #endif 1322 1323 emu_InitJoysticks(); 1324 #ifdef SWAP_JOYSTICK 1325 joySwapped = true; 1326 #else 1327 joySwapped = false; 1328 #endif 1329 1330 int keypressed = emu_ReadKeys(); 1331 1332 #ifdef USE_VGA 1333 tft.begin(MODE_VGA_320x240); 1334 #else 1335 1336 #ifdef PICOZX 1337 // Force VGA if LEFT/RIGHT pressed 1338 if (keypressed & MASK_JOY2_UP) 1339 { 1340 tft.begin(MODE_VGA_320x240); 1341 #ifdef FILEBROWSER 1342 emu_writeGfxConfig(); 1343 #endif 1344 } 1345 else 1346 { 1347 if ( (keypressed & MASK_JOY2_LEFT) || (keypressed & MASK_JOY2_RIGHT) ) 1348 { 1349 #ifdef FILEBROWSER 1350 emu_eraseGfxConfig(); 1351 #endif 1352 forceVga = false; 1353 } 1354 if (forceVga) { 1355 tft.begin(MODE_VGA_320x240); 1356 } 1357 else 1358 { 1359 tft.begin(MODE_TFT_320x240); 1360 } 1361 } 1362 #else /* end PICOZX */ 1363 tft.begin(MODE_TFT_320x240); 1364 #endif 1365 1366 #endif 1367 1368 #ifndef USE_VGA 1369 #ifdef PICOMPUTER 1370 // Flip screen if UP pressed 1371 if (keypressed & MASK_JOY2_UP) 1372 { 1373 tft.flipscreen(true); 1374 } 1375 else 1376 { 1377 tft.flipscreen(false); 1378 } 1379 #endif 1380 #endif 1381 1382 if (keypressed & MASK_JOY2_DOWN) { 1383 tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) ); 1384 tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); 1385 tft.drawTextNoDma(64,48+24, (char*)"Please reset the board!", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); 1386 emu_eraseConfig(); 1387 } 1388 else { 1389 if (emu_readConfig()) { 1390 autorun = true; 1391 } 1392 } 1393 1394 #ifdef FILEBROWSER 1395 toggleMenu(true); 1396 #endif 1397 } 1398 1399 1400 void emu_start(void) 1401 { 1402 usbnavpad = 0; 1403 1404 keyMap = 0; 1405 }