emuapi.cpp
1 #define KEYMAP_PRESENT 1 2 3 extern "C" { 4 #include "emuapi.h" 5 #include "iopins.h" 6 } 7 8 #ifdef HAS_T4_VGA 9 #include "vga_t_dma.h" 10 const uint16_t deflogo[] = { 11 0,0 12 }; 13 static const uint16_t * logo = deflogo; 14 #else 15 #include "tft_t_dma.h" 16 #include "logo.h" 17 #endif 18 19 #include "bmpjoy.h" 20 #include "bmpvbar.h" 21 #ifdef OLD_LAYOUT 22 #include "bmpvga.h" 23 #include "bmptft.h" 24 #endif 25 26 27 #ifdef HAS_I2CKBD 28 #include <Wire.h> 29 #endif 30 31 #ifdef HAS_USBKEY 32 #include "USBHost_t36.h" // Read this header first for key info 33 USBHost myusb; 34 KeyboardController keyboard1(myusb); 35 #endif 36 static uint8_t usbnavpad=0; 37 38 #ifdef USE_SDFS 39 #include "uSDFS.h" 40 static FATFS fatfs; 41 static FIL file; 42 #else 43 44 #ifdef USE_SDFAT 45 #include "SdFat.h" 46 #include "sdios.h" 47 48 #ifndef SDCARD_SS_PIN 49 const uint8_t SD_CS_PIN = SS; 50 51 #else // SDCARD_SS_PIN 52 // Assume built-in SD is used. 53 const uint8_t SD_CS_PIN = SDCARD_SS_PIN; 54 #endif // SDCARD_SS_PIN 55 56 #define SD_CONFIG SdioConfig(FIFO_SDIO) 57 58 // Try to select the best SD card configuration. 59 #if HAS_SDIO_CLASS 60 #define SD_CONFIG SdioConfig(FIFO_SDIO) 61 #elif ENABLE_DEDICATED_SPI 62 #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI) 63 #else // HAS_SDIO_CLASS 64 #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI) 65 #endif // HAS_SDIO_CLASS 66 //------------------------------------------------------------------------------ 67 68 #if SD_FAT_TYPE == 0 69 #elif SD_FAT_TYPE == 1 70 #define SdFat SdFat32 71 #define File File32 72 #elif SD_FAT_TYPE == 2 73 #define SdFat SdExFat 74 #define File ExFile 75 #elif SD_FAT_TYPE == 3 76 #define SdFat SdFs 77 #define File FsFile 78 #endif // SD_FAT_TYPE 79 static SdFat SD; 80 #else 81 #include <SD.h> 82 #endif 83 static File file; 84 #endif 85 86 #define CALIBRATION_FILE "/cal.cfg" 87 88 #define MKEY_L1 1 89 #define MKEY_L2 2 90 #define MKEY_L3 3 91 #define MKEY_L4 4 92 #define MKEY_L5 5 93 #define MKEY_L6 6 94 #define MKEY_L7 7 95 #define MKEY_L8 8 96 #define MKEY_L9 9 97 #define MKEY_UP 20 98 #define MKEY_DOWN 21 99 #define MKEY_JOY 22 100 #define MKEY_TFT 23 101 #define MKEY_VGA 24 102 103 #define MAX_FILES 64 104 #define MAX_FILENAME_SIZE 24 105 #define MAX_MENULINES (MKEY_L9) 106 #define TEXT_HEIGHT 16 107 #define TEXT_WIDTH 8 108 #define MENU_FILE_XOFFSET (6*TEXT_WIDTH) 109 #define MENU_FILE_YOFFSET (2*TEXT_HEIGHT) 110 #define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH) 111 #define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT) 112 #define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40) 113 #define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT) 114 #define MENU_VBAR_XOFFSET (0*TEXT_WIDTH) 115 #define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET) 116 117 #define MENU_TFT_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) 118 #define MENU_TFT_YOFFSET (MENU_VBAR_YOFFSET+32) 119 #define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) 120 #define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37) 121 122 extern TFT_T_DMA tft; 123 124 static char romspath[64]; 125 static int nbFiles=0; 126 static int curFile=0; 127 static int topFile=0; 128 static char selection[MAX_FILENAME_SIZE+1]=""; 129 static char files[MAX_FILES][MAX_FILENAME_SIZE]; 130 static bool menuRedraw=true; 131 132 static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1; 133 static bool i2cKeyboardPresent = false; 134 static unsigned short * keys; 135 static int keyMap; 136 137 const unsigned short menutouchareas[] = { 138 TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET, 139 TAREA_WH,MENU_FILE_W, TEXT_HEIGHT, 140 TAREA_NEW_COL,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT, 141 142 TAREA_XY,MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET, 143 TAREA_WH,32,48, 144 TAREA_NEW_COL, 72,72,8,40, 145 146 TAREA_XY,MENU_TFT_XOFFSET,MENU_TFT_YOFFSET, 147 TAREA_WH,32,37, 148 TAREA_NEW_COL, 38,38, 149 150 TAREA_END}; 151 152 const unsigned short menutouchactions[] = { 153 MKEY_L1,MKEY_L2,MKEY_L3,MKEY_L4,MKEY_L5,MKEY_L6,MKEY_L7,MKEY_L8,MKEY_L9, 154 MKEY_UP,MKEY_DOWN,ACTION_NONE,MKEY_JOY, 155 MKEY_TFT,MKEY_VGA}; 156 157 158 static int keypadval=0; 159 static boolean joySwapped = false; 160 static uint16_t bLastState; 161 static int xRef; 162 static int yRef; 163 static uint8_t prev_zt=0; 164 165 static bool menuOn=true; 166 static bool callibrationOn=false; 167 static int callibrationStep=0; 168 169 170 static char captureTouchZone(const unsigned short * areas, const unsigned short * actions, int *rx, int *ry, int *rw, int * rh) { 171 uint16_t xt=0; 172 uint16_t yt=0; 173 uint16_t zt=0; 174 boolean hDir=true; 175 176 if (tft.isTouching()) 177 { 178 if (prev_zt == 0) { 179 prev_zt =1; 180 tft.readCal(&xt,&yt,&zt); 181 if (zt<1000) { 182 prev_zt=0; 183 return ACTION_NONE; 184 } 185 int i=0; 186 int k=0; 187 int y2=0, y1=0; 188 int x2=0, x1=0; 189 int x=KEYBOARD_X,y=KEYBOARD_Y; 190 int w=TAREA_W_DEF,h=TAREA_H_DEF; 191 uint8_t s; 192 while ( (s=areas[i++]) != TAREA_END ) { 193 if (s == TAREA_XY) { 194 x = areas[i++]; 195 y = areas[i++]; 196 x2 = x; 197 y2 = y; 198 } 199 else if (s == TAREA_WH) { 200 w = areas[i++]; 201 h = areas[i++]; 202 } 203 else if (s == TAREA_NEW_ROW) { 204 hDir = true; 205 y1 = y2; 206 y2 = y1 + h; 207 x2 = x; 208 } 209 else if (s == TAREA_NEW_COL) { 210 hDir = false; 211 x1 = x2; 212 x2 = x1 + w; 213 y2 = y; 214 } 215 else { 216 if (hDir) { 217 x1 = x2; 218 x2 = x1+s; 219 } else { 220 y1 = y2; 221 y2 = y1+s; 222 } 223 if ( (yt >= y1) && (yt < y2) && (xt >= x1) && (xt < x2) ) { 224 *rx = x1; 225 *ry = y1; 226 *rw = x2-x1; 227 *rh = y2-y1; 228 return (actions[k]); 229 } 230 k++; 231 } 232 } 233 } 234 prev_zt =1; 235 } else { 236 prev_zt=0; 237 } 238 239 return ACTION_NONE; 240 } 241 242 243 244 245 246 247 248 249 void emu_printf(char * text) 250 { 251 Serial.println(text); 252 } 253 254 void emu_printf(int val) 255 { 256 Serial.println(val); 257 } 258 259 void emu_printi(int val) 260 { 261 Serial.println(val,HEX); 262 } 263 264 void emu_printh(int val) 265 { 266 Serial.println(val,HEX); 267 } 268 269 static int malbufpt = 0; 270 static char malbuf[EXTRA_HEAP]; 271 272 void * emu_Malloc(int size) 273 { 274 void * retval = malloc(size); 275 if (!retval) { 276 emu_printf("failled to allocate"); 277 emu_printf(size); 278 emu_printf("fallback"); 279 if ( (malbufpt+size) < sizeof(malbuf) ) { 280 retval = (void *)&malbuf[malbufpt]; 281 malbufpt += size; 282 } 283 else { 284 emu_printf("failure to allocate"); 285 } 286 } 287 else { 288 emu_printf("could allocate dynamic "); 289 emu_printf(size); 290 } 291 292 return retval; 293 } 294 295 void * emu_MallocI(int size) 296 { 297 void * retval = NULL; 298 299 if ( (malbufpt+size) < sizeof(malbuf) ) { 300 retval = (void *)&malbuf[malbufpt]; 301 malbufpt += size; 302 emu_printf("could allocate static "); 303 emu_printf(size); 304 } 305 else { 306 emu_printf("failure to allocate"); 307 } 308 309 return retval; 310 } 311 void emu_Free(void * pt) 312 { 313 free(pt); 314 } 315 316 317 318 319 320 int emu_ReadAnalogJoyX(int min, int max) 321 { 322 int val = analogRead(PIN_JOY2_A1X); 323 #if INVX 324 val = 4095 - val; 325 #endif 326 val = val-xRef; 327 val = ((val*140)/100); 328 if ( (val > -512) && (val < 512) ) val = 0; 329 val = val+2048; 330 return (val*(max-min))/4096; 331 } 332 333 int emu_ReadAnalogJoyY(int min, int max) 334 { 335 int val = analogRead(PIN_JOY2_A2Y); 336 #if INVY 337 val = 4095 - val; 338 #endif 339 val = val-yRef; 340 val = ((val*120)/100); 341 if ( (val > -512) && (val < 512) ) val = 0; 342 //val = (val*(max-min))/4096; 343 val = val+2048; 344 //return val+(max-min)/2; 345 return (val*(max-min))/4096; 346 } 347 348 349 static uint16_t readAnalogJoystick(void) 350 { 351 uint16_t joysval = 0; 352 353 int xReading = emu_ReadAnalogJoyX(0,256); 354 if (xReading > 128) joysval |= MASK_JOY2_LEFT; 355 else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; 356 357 int yReading = emu_ReadAnalogJoyY(0,256); 358 if (yReading < 128) joysval |= MASK_JOY2_UP; 359 else if (yReading > 128) joysval |= MASK_JOY2_DOWN; 360 361 #ifdef PIN_JOY2_BTN 362 joysval |= (digitalRead(PIN_JOY2_BTN) == HIGH ? 0 : MASK_JOY2_BTN); 363 #endif 364 return (joysval); 365 } 366 367 368 int emu_SwapJoysticks(int statusOnly) { 369 if (!statusOnly) { 370 if (joySwapped) { 371 joySwapped = false; 372 } 373 else { 374 joySwapped = true; 375 } 376 } 377 return(joySwapped?1:0); 378 } 379 380 int emu_GetPad(void) 381 { 382 return(keypadval/*|((joySwapped?1:0)<<7)*/); 383 } 384 385 int emu_ReadKeys(void) 386 { 387 uint16_t retval; 388 uint16_t j1 = readAnalogJoystick(); 389 uint16_t j2 = 0; 390 391 // Second joystick 392 #if INVY 393 #ifdef PIN_JOY1_1 394 if ( digitalRead(PIN_JOY1_1) == LOW ) j2 |= MASK_JOY2_DOWN; 395 #endif 396 #ifdef PIN_JOY1_2 397 if ( digitalRead(PIN_JOY1_2) == LOW ) j2 |= MASK_JOY2_UP; 398 #endif 399 #else 400 #ifdef PIN_JOY1_1 401 if ( digitalRead(PIN_JOY1_1) == LOW ) j2 |= MASK_JOY2_UP; 402 #endif 403 #ifdef PIN_JOY1_2 404 if ( digitalRead(PIN_JOY1_2) == LOW ) j2 |= MASK_JOY2_DOWN; 405 #endif 406 #endif 407 #if INVX 408 #ifdef PIN_JOY1_3 409 if ( digitalRead(PIN_JOY1_3) == LOW ) j2 |= MASK_JOY2_LEFT; 410 #endif 411 #ifdef PIN_JOY1_4 412 if ( digitalRead(PIN_JOY1_4) == LOW ) j2 |= MASK_JOY2_RIGHT; 413 #endif 414 #else 415 #ifdef PIN_JOY1_3 416 if ( digitalRead(PIN_JOY1_3) == LOW ) j2 |= MASK_JOY2_RIGHT; 417 #endif 418 #ifdef PIN_JOY1_4 419 if ( digitalRead(PIN_JOY1_4) == LOW ) j2 |= MASK_JOY2_LEFT; 420 #endif 421 #endif 422 #ifdef PIN_JOY1_BTN 423 if ( digitalRead(PIN_JOY1_BTN) == LOW ) j2 |= MASK_JOY2_BTN; 424 #endif 425 if (joySwapped) { 426 retval = ((j1 << 8) | j2); 427 } 428 else { 429 retval = ((j2 << 8) | j1); 430 } 431 432 if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP; 433 if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN; 434 if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT; 435 if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT; 436 if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN; 437 438 #ifdef PIN_KEY_USER1 439 if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1; 440 #endif 441 #ifdef PIN_KEY_USER2 442 if ( digitalRead(PIN_KEY_USER2) == LOW ) retval |= MASK_KEY_USER2; 443 #endif 444 #ifdef PIN_KEY_USER3 445 if ( digitalRead(PIN_KEY_USER3) == LOW ) retval |= MASK_KEY_USER3; 446 #endif 447 #ifdef PIN_KEY_USER4 448 if ( digitalRead(PIN_KEY_USER4) == LOW ) retval |= MASK_KEY_USER4; 449 #endif 450 451 //Serial.println(retval,HEX); 452 453 if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) 454 || (retval & MASK_KEY_USER4 ) ) 455 { 456 // Reset procedure T3.X and T4.0 by Frank Boesing !! 457 #if defined(__IMXRT1052__) || defined(__IMXRT1062__) 458 uint32_t tmp = SNVS_LPCR; // save control register 459 460 SNVS_LPSR |= 1; 461 462 // disable alarm 463 SNVS_LPCR &= ~0x02; 464 while (SNVS_LPCR & 0x02); 465 466 __disable_irq(); 467 //get Time: 468 uint32_t lsb, msb; 469 do { 470 msb = SNVS_LPSRTCMR; 471 lsb = SNVS_LPSRTCLR; 472 } while ( (SNVS_LPSRTCLR != lsb) | (SNVS_LPSRTCMR != msb) ); 473 uint32_t secs = (msb << 17) | (lsb >> 15); 474 475 //set alarm 476 secs += 2; 477 SNVS_LPTAR = secs; 478 while (SNVS_LPTAR != secs); 479 480 SNVS_LPCR = tmp | 0x02; // restore control register and set alarm 481 while (!(SNVS_LPCR & 0x02)); 482 483 SNVS_LPCR |= (1 << 6); // turn off power 484 while (1) asm("wfi"); 485 #else 486 *(volatile uint32_t *)0xE000ED0C = 0x5FA0004; 487 while (true) { 488 ; 489 } 490 #endif 491 } 492 493 return (retval); 494 } 495 496 unsigned short emu_DebounceLocalKeys(void) 497 { 498 uint16_t bCurState = emu_ReadKeys(); 499 uint16_t bClick = bCurState & ~bLastState; 500 bLastState = bCurState; 501 502 return (bClick); 503 } 504 505 int emu_ReadI2CKeyboard(void) { 506 int retval=0; 507 #ifdef HAS_I2CKBD 508 if (i2cKeyboardPresent) { 509 byte msg[7]={0,0,0,0,0,0,0}; 510 Wire.requestFrom(8, 7); // request 7 bytes from slave device #8 511 int i = 0; 512 int hitindex=-1; 513 while (Wire.available() && (i<7) ) { // slave may send less than requested 514 byte b = Wire.read(); // receive a byte 515 if (b != 0xff) hitindex=i; 516 msg[i++] = b; 517 } 518 519 if (hitindex >=0 ) { 520 /* 521 Serial.println(msg[0], BIN); 522 Serial.println(msg[1], BIN); 523 Serial.println(msg[2], BIN); 524 Serial.println(msg[3], BIN); 525 Serial.println(msg[4], BIN); 526 Serial.println(msg[5], BIN); 527 Serial.println(msg[6], BIN); 528 */ 529 unsigned short match = (~msg[hitindex])&0x00FF | (hitindex<<8); 530 //Serial.println(match,HEX); 531 for (i=0; i<sizeof(i2ckeys); i++) { 532 if (match == i2ckeys[i]) { 533 //Serial.println((int)keys[i]); 534 return (keys[i]); 535 } 536 } 537 } 538 } 539 #endif 540 return(retval); 541 } 542 543 void emu_InitJoysticks(void) { 544 545 // Second Joystick 546 #ifdef PIN_JOY1_1 547 pinMode(PIN_JOY1_1, INPUT_PULLUP); 548 #endif 549 #ifdef PIN_JOY1_2 550 pinMode(PIN_JOY1_2, INPUT_PULLUP); 551 #endif 552 #ifdef PIN_JOY1_3 553 pinMode(PIN_JOY1_3, INPUT_PULLUP); 554 #endif 555 #ifdef PIN_JOY1_4 556 pinMode(PIN_JOY1_4, INPUT_PULLUP); 557 #endif 558 #ifdef PIN_JOY1_BTN 559 pinMode(PIN_JOY1_BTN, INPUT_PULLUP); 560 #endif 561 562 #ifdef PIN_KEY_USER1 563 pinMode(PIN_KEY_USER1, INPUT_PULLUP); 564 #endif 565 #ifdef PIN_KEY_USER2 566 pinMode(PIN_KEY_USER2, INPUT_PULLUP); 567 #endif 568 #ifdef PIN_KEY_USER3 569 pinMode(PIN_KEY_USER3, INPUT_PULLUP); 570 #endif 571 #ifdef PIN_KEY_USER4 572 pinMode(PIN_KEY_USER4, INPUT_PULLUP); 573 #endif 574 #ifdef PIN_JOY2_BTN 575 pinMode(PIN_JOY2_BTN, INPUT_PULLUP); 576 #endif 577 analogReadResolution(12); 578 xRef=0; yRef=0; 579 for (int i=0; i<10; i++) { 580 xRef += analogRead(PIN_JOY2_A1X); 581 yRef += analogRead(PIN_JOY2_A2Y); 582 delay(20); 583 } 584 585 #if INVX 586 xRef = 4095 -xRef/10; 587 #else 588 xRef /= 10; 589 #endif 590 #if INVY 591 yRef = 4095 -yRef/10; 592 #else 593 yRef /= 10; 594 #endif 595 } 596 597 598 599 static bool vkbKeepOn = false; 600 static bool vkbActive = false; 601 static bool vkeyRefresh=false; 602 static bool exitVkbd = false; 603 static uint8_t keyPressCount=0; 604 605 606 bool virtualkeyboardIsActive(void) { 607 return (vkbActive); 608 } 609 610 void toggleVirtualkeyboard(bool keepOn) { 611 612 if (keepOn) { 613 tft.drawSpriteNoDma(0,0,logo); 614 //prev_zt = 0; 615 vkbKeepOn = true; 616 vkbActive = true; 617 exitVkbd = false; 618 } 619 else { 620 vkbKeepOn = false; 621 if ( (vkbActive) /*|| (exitVkbd)*/ ) { 622 tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) ); 623 tft.startDMA(); 624 //prev_zt = 0; 625 vkbActive = false; 626 exitVkbd = false; 627 } 628 else { 629 tft.stopDMA(); 630 tft.drawSpriteNoDma(0,0,logo); 631 //prev_zt = 0; 632 vkbActive = true; 633 exitVkbd = false; 634 } 635 } 636 } 637 638 639 void handleVirtualkeyboard() { 640 int rx=0,ry=0,rw=0,rh=0; 641 642 if (keyPressCount == 0) { 643 keypadval = 0; 644 } else { 645 keyPressCount--; 646 } 647 648 if ( (!virtualkeyboardIsActive()) && (tft.isTouching()) && (!keyPressCount) ) { 649 toggleVirtualkeyboard(false); 650 return; 651 } 652 653 if ( ( (vkbKeepOn) || (virtualkeyboardIsActive()) ) ) { 654 char c = captureTouchZone(keysw, keys, &rx,&ry,&rw,&rh); 655 if (c) { 656 657 tft.drawRectNoDma( rx,ry,rw,rh, KEYBOARD_HIT_COLOR ); 658 if ( (c >=1) && (c <= ACTION_MAXKBDVAL) ) { 659 660 keypadval = c; 661 keyPressCount = 10; 662 delay(50); 663 vkeyRefresh = true; 664 exitVkbd = true; 665 } 666 else if (c == ACTION_EXITKBD) { 667 vkeyRefresh = true; 668 exitVkbd = true; 669 } 670 } 671 } 672 673 if (vkeyRefresh) { 674 vkeyRefresh = false; 675 tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh); 676 } 677 678 if ( (exitVkbd) && (vkbActive) ) { 679 if (!vkbKeepOn) { 680 toggleVirtualkeyboard(false); 681 } 682 else { 683 toggleVirtualkeyboard(true); 684 } 685 } 686 } 687 688 int emu_setKeymap(int index) { 689 } 690 691 692 693 694 static int readNbFiles(void) { 695 int totalFiles = 0; 696 697 #ifdef USE_SDFS 698 DIR dir; 699 FILINFO entry; 700 f_opendir(&dir, romspath); 701 while ( (true) && (totalFiles<MAX_FILES) ) { 702 f_readdir(&dir, &entry); 703 if (!entry.fname[0]) { 704 // no more files 705 break; 706 } 707 char * filename = entry.fname; 708 Serial.println(filename); 709 if ( !(entry.fattrib & AM_DIR) ) { 710 strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1); 711 totalFiles++; 712 } 713 else { 714 if ( (strcmp(filename,".")) && (strcmp(filename,"..")) ) { 715 strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1); 716 totalFiles++; 717 } 718 } 719 } 720 f_closedir(&dir); 721 #else 722 File entry; 723 file = SD.open(romspath); 724 while ( (true) && (totalFiles<MAX_FILES) ) { 725 entry = file.openNextFile(); 726 if (! entry) { 727 // no more files 728 break; 729 } 730 #ifdef USE_SDFAT 731 char filename[MAX_FILENAME_SIZE]; 732 entry.getName(&filename[0], MAX_FILENAME_SIZE); 733 #else 734 char * filename = entry.name(); 735 #endif 736 Serial.println(filename); 737 if (!entry.isDirectory()) { 738 strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1); 739 totalFiles++; 740 } 741 else { 742 if ( (strcmp(filename,".")) && (strcmp(filename,"..")) ) { 743 strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1); 744 totalFiles++; 745 } 746 } 747 entry.close(); 748 } 749 file.close(); 750 #endif 751 return totalFiles; 752 } 753 754 755 756 void backgroundMenu(void) { 757 menuRedraw=true; 758 tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); 759 tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true); 760 #ifndef HAS_T4_VGA 761 tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar); 762 #endif 763 #ifdef OLD_LAYOUT 764 tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft); 765 tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga); 766 #endif 767 } 768 769 int handleMenu(uint16_t bClick) 770 { 771 int action = ACTION_NONE; 772 773 char newpath[80]; 774 strcpy(newpath, romspath); 775 strcat(newpath, "/"); 776 strcat(newpath, selection); 777 778 int rx=0,ry=0,rw=0,rh=0; 779 char c = 0; //captureTouchZone(menutouchareas, menutouchactions, &rx,&ry,&rw,&rh); 780 781 if ( (bClick & MASK_JOY2_BTN) || (c == MKEY_TFT) ) { 782 emu_printf(newpath); 783 #ifdef USE_SDFS 784 FILINFO entry; 785 f_stat(newpath, &entry); 786 if ( (entry.fattrib & AM_DIR) ) { 787 #else 788 File file = SD.open(newpath); 789 if (file.isDirectory()) { 790 #endif 791 strcpy(romspath,newpath); 792 curFile = 0; 793 nbFiles = readNbFiles(); 794 } 795 else { 796 action = ACTION_RUNTFT; 797 } 798 menuRedraw=true; 799 } 800 else if ( (bClick & MASK_KEY_USER1) || (c == MKEY_VGA) ) { 801 menuRedraw=true; 802 action = ACTION_RUNVGA; 803 } 804 else if ( (c >= MKEY_L1) && (c <= MKEY_L9) ) { 805 if ( (topFile+(int)c-1) <= (nbFiles-1) ) 806 { 807 curFile = topFile + (int)c -1; 808 menuRedraw=true; 809 //tft.drawRectNoDma( rx,ry,rw,rh, KEYBOARD_HIT_COLOR ); 810 } 811 } 812 else if (bClick & MASK_JOY2_UP) { 813 if (curFile!=0) { 814 menuRedraw=true; 815 curFile--; 816 } 817 } 818 else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) || (c == MKEY_UP) ) { 819 if ((curFile-9)>=0) { 820 menuRedraw=true; 821 curFile -= 9; 822 } else if (curFile!=0) { 823 menuRedraw=true; 824 curFile--; 825 } 826 } 827 else if (bClick & MASK_JOY2_DOWN) { 828 if ((curFile<(nbFiles-1)) && (nbFiles)) { 829 curFile++; 830 menuRedraw=true; 831 } 832 } 833 else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) || (c == MKEY_DOWN) ) { 834 if ((curFile<(nbFiles-9)) && (nbFiles)) { 835 curFile += 9; 836 menuRedraw=true; 837 } 838 else if ((curFile<(nbFiles-1)) && (nbFiles)) { 839 curFile++; 840 menuRedraw=true; 841 } 842 } 843 else if ( (bClick & MASK_KEY_USER2) || (c == MKEY_JOY) ) { 844 emu_SwapJoysticks(0); 845 menuRedraw=true; 846 } 847 848 if (menuRedraw && nbFiles) { 849 int fileIndex = 0; 850 tft.drawRectNoDma(MENU_FILE_XOFFSET,MENU_FILE_YOFFSET, MENU_FILE_W, MENU_FILE_H, MENU_FILE_BGCOLOR); 851 // if (curFile <= (MAX_MENULINES/2-1)) topFile=0; 852 // else topFile=curFile-(MAX_MENULINES/2); 853 if (curFile <= (MAX_MENULINES-1)) topFile=0; 854 else topFile=curFile-(MAX_MENULINES/2); 855 856 //Serial.print("curfile: "); 857 //Serial.println(curFile); 858 //Serial.print("topFile: "); 859 //Serial.println(topFile); 860 861 int i=0; 862 while (i<MAX_MENULINES) { 863 if (fileIndex>=nbFiles) { 864 // no more files 865 break; 866 } 867 char * filename = &files[fileIndex][0]; 868 if (fileIndex >= topFile) { 869 if ((i+topFile) < nbFiles ) { 870 if ((i+topFile)==curFile) { 871 tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); 872 strcpy(selection,filename); 873 } 874 else { 875 tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true); 876 } 877 } 878 i++; 879 } 880 fileIndex++; 881 } 882 883 #ifndef HAS_T4_VGA 884 tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy); 885 #endif 886 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); 887 menuRedraw=false; 888 } 889 890 return (action); 891 } 892 893 bool menuActive(void) 894 { 895 return (menuOn); 896 } 897 898 void toggleMenu(bool on) { 899 if (on) { 900 callibrationOn=false; 901 menuOn=true; 902 backgroundMenu(); 903 } else { 904 menuOn = false; 905 } 906 } 907 908 char * menuSelection(void) 909 { 910 return (selection); 911 } 912 913 914 915 916 static void callibrationInit(void) 917 { 918 callibrationOn=true; 919 menuOn=false; 920 callibrationStep = 0; 921 calMinX=0,calMinY=0,calMaxX=0,calMaxY=0; 922 tft.fillScreenNoDma(RGBVAL16(0xff,0xff,0xff)); 923 tft.drawTextNoDma(0,100, " Callibration process:", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 924 tft.drawTextNoDma(0,116, " Hit the red cross at each corner", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 925 tft.drawTextNoDma(0,0, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 926 prev_zt = 1; 927 } 928 929 930 static void readCallibration(void) 931 { 932 char fileBuffer[64]; 933 934 #ifdef USE_SDFS 935 FIL file; 936 int retval; 937 if( !(f_open(&file, CALIBRATION_FILE, FA_READ)) ) { 938 if( !(f_read (&file, fileBuffer, 64, &retval)) ) { 939 if (retval == 64) { 940 sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY); 941 } 942 } 943 f_close(&file); 944 } 945 #else 946 File file = SD.open(CALIBRATION_FILE, O_READ); 947 if (file) { 948 if ( file.read(fileBuffer, 64) ) { 949 sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY); 950 } 951 file.close(); 952 Serial.println("Current callibration params:"); 953 Serial.println(calMinX); 954 Serial.println(calMinY); 955 Serial.println(calMaxX); 956 Serial.println(calMaxY); 957 } 958 #endif 959 else { 960 Serial.println("Callibration read error"); 961 } 962 tft.callibrateTouch(calMinX,calMinY,calMaxX,calMaxY); 963 } 964 965 static void writeCallibration(void) 966 { 967 tft.callibrateTouch(calMinX,calMinY,calMaxX,calMaxY); 968 969 #ifdef USE_SDFS 970 FIL file; 971 int retval; 972 if( !(f_open(&file, CALIBRATION_FILE, FA_WRITE)) ) { 973 //if( !(f_read (&file, fileBuffer, 64, &retval)) ) { 974 // if (retval == 64) { 975 // sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY); 976 // } 977 //} 978 f_close(&file); 979 } 980 #else 981 File file = SD.open(CALIBRATION_FILE, O_WRITE | O_CREAT | O_TRUNC); 982 if (file) { 983 file.print(calMinX); 984 file.print(" "); 985 file.print(calMinY); 986 file.print(" "); 987 file.print(calMaxX); 988 file.print(" "); 989 file.println(calMaxY); 990 file.close(); 991 } 992 #endif 993 else { 994 Serial.println("Callibration write error"); 995 } 996 } 997 998 999 bool callibrationActive(void) 1000 { 1001 return (callibrationOn); 1002 } 1003 1004 1005 1006 int handleCallibration(uint16_t bClick) { 1007 uint16_t xt=0; 1008 uint16_t yt=0; 1009 uint16_t zt=0; 1010 if (tft.isTouching()) { 1011 if (prev_zt == 0) { 1012 prev_zt = 1; 1013 tft.readRaw(&xt,&yt,&zt); 1014 if (zt < 1000) { 1015 return 0; 1016 } 1017 switch (callibrationStep) 1018 { 1019 case 0: 1020 callibrationStep++; 1021 tft.drawTextNoDma(0,0, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true); 1022 tft.drawTextNoDma(TFT_REALWIDTH-8,0, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 1023 calMinX += xt; 1024 calMinY += yt; 1025 break; 1026 case 1: 1027 callibrationStep++; 1028 tft.drawTextNoDma(TFT_REALWIDTH-8,0, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true); 1029 tft.drawTextNoDma(TFT_REALWIDTH-8,TFT_REALHEIGHT-16, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 1030 calMaxX += xt; 1031 calMinY += yt; 1032 break; 1033 case 2: 1034 callibrationStep++; 1035 tft.drawTextNoDma(TFT_REALWIDTH-8,TFT_REALHEIGHT-16, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true); 1036 tft.drawTextNoDma(0,TFT_REALHEIGHT-16, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 1037 calMaxX += xt; 1038 calMaxY += yt; 1039 break; 1040 case 3: 1041 tft.fillScreenNoDma(RGBVAL16(0xff,0xff,0xff)); 1042 tft.drawTextNoDma(0,100, " Callibration done!", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 1043 tft.drawTextNoDma(0,116, " (Click center to exit)", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 1044 callibrationStep++; 1045 calMinX += xt; 1046 calMaxY += yt; 1047 break; 1048 case 4: 1049 //Serial.println(xt); 1050 //Serial.println(yt); 1051 if ( (xt > (TFT_REALWIDTH/4)) && (xt < (TFT_REALWIDTH*3)/4) 1052 && (yt > (TFT_REALHEIGHT/4)) && (yt < (TFT_REALHEIGHT*3)/4) ) { 1053 calMinX /= 2; 1054 calMinY /= 2; 1055 calMaxX /= 2; 1056 calMaxY /= 2; 1057 writeCallibration(); 1058 toggleMenu(true); 1059 } 1060 else { 1061 callibrationInit(); 1062 } 1063 break; 1064 1065 } 1066 delay(100); 1067 } 1068 } 1069 else { 1070 prev_zt = 0; 1071 } 1072 } 1073 1074 1075 1076 1077 1078 int emu_FileOpen(char * filename) 1079 { 1080 int retval = 0; 1081 1082 char filepath[80]; 1083 strcpy(filepath, romspath); 1084 strcat(filepath, "/"); 1085 strcat(filepath, filename); 1086 emu_printf("FileOpen..."); 1087 emu_printf(filepath); 1088 #ifdef USE_SDFS 1089 if( !(f_open(&file, filepath, FA_READ)) ) { 1090 #else 1091 if ((file = SD.open(filepath, O_READ))) { 1092 #endif 1093 retval = 1; 1094 } 1095 else { 1096 emu_printf("FileOpen failed"); 1097 } 1098 return (retval); 1099 } 1100 1101 int emu_FileRead(char * buf, int size) 1102 { 1103 unsigned char buffer[256]; 1104 1105 int remaining = size; 1106 int byteread = 0; 1107 int retval=0; 1108 if (size < 256) { 1109 #ifdef USE_SDFS 1110 if( !(f_read (&file, buffer, size, &retval)) ) 1111 #else 1112 retval = file.read(buffer, size); 1113 #endif 1114 if (retval>0) { 1115 memcpy(buf,buffer,retval); 1116 byteread += retval; 1117 } 1118 } 1119 else { 1120 while (remaining>0) { 1121 #ifdef USE_SDFS 1122 if( !(f_read (&file, buffer, 256, &retval)) ) 1123 //f_read (&file, buffer, 256, &retval); 1124 #else 1125 retval = file.read(buffer, 256); 1126 #endif 1127 if (retval>0) { 1128 //emu_printi(retval); 1129 memcpy(buf,buffer,retval); 1130 buf += retval; 1131 byteread += retval; 1132 remaining -= retval; 1133 } 1134 else { 1135 break; 1136 } 1137 } 1138 } 1139 1140 return byteread; 1141 } 1142 1143 unsigned char emu_FileGetc(void) { 1144 unsigned char c; 1145 #ifdef USE_SDFS 1146 int retval=0; 1147 if( !(f_read (&file, &c, 1, &retval)) ) 1148 #else 1149 int retval = file.read(&c, 1); 1150 #endif 1151 if (retval != 1) { 1152 emu_printf("emu_FileGetc failed"); 1153 } 1154 return c; 1155 } 1156 1157 1158 void emu_FileClose(void) 1159 { 1160 #ifdef USE_SDFS 1161 f_close(&file); 1162 #else 1163 file.close(); 1164 #endif 1165 } 1166 1167 int emu_FileSize(char * filename) 1168 { 1169 int filesize=0; 1170 char filepath[80]; 1171 strcpy(filepath, romspath); 1172 strcat(filepath, "/"); 1173 strcat(filepath, filename); 1174 emu_printf("FileSize..."); 1175 emu_printf(filepath); 1176 #ifdef USE_SDFS 1177 FILINFO entry; 1178 f_stat(filepath, &entry); 1179 filesize = entry.fsize; 1180 #else 1181 if ((file = SD.open(filepath, O_READ))) 1182 { 1183 emu_printf("filesize is..."); 1184 filesize = file.size(); 1185 emu_printf(filesize); 1186 file.close(); 1187 } 1188 #endif 1189 1190 return(filesize); 1191 } 1192 1193 int emu_FileSeek(int seek) 1194 { 1195 #ifdef USE_SDFS 1196 f_lseek(&file, seek); 1197 #else 1198 file.seek(seek); 1199 #endif 1200 return (seek); 1201 } 1202 1203 int emu_FileTell(void) 1204 { 1205 #ifdef USE_SDFS 1206 return (f_tell(&file)); 1207 #else 1208 return (50); 1209 #endif 1210 } 1211 1212 1213 int emu_LoadFile(char * filename, char * buf, int size) 1214 { 1215 int filesize = 0; 1216 1217 char filepath[80]; 1218 strcpy(filepath, romspath); 1219 strcat(filepath, "/"); 1220 strcat(filepath, filename); 1221 emu_printf("LoadFile..."); 1222 emu_printf(filepath); 1223 #ifdef USE_SDFS 1224 if( !(f_open(&file, filepath, FA_READ)) ) { 1225 filesize = f_size(&file); 1226 emu_printf(filesize); 1227 if (size >= filesize) 1228 { 1229 int retval=0; 1230 if( (f_read (&file, buf, filesize, &retval)) ) { 1231 emu_printf("File read failed"); 1232 } 1233 } 1234 f_close(&file); 1235 } 1236 #else 1237 if ((file = SD.open(filepath, O_READ))) 1238 { 1239 filesize = file.size(); 1240 emu_printf(filesize); 1241 1242 if (size >= filesize) 1243 { 1244 if (emu_FileRead(buf, filesize) != filesize) 1245 { 1246 emu_printf("File read failed"); 1247 } 1248 } 1249 file.close(); 1250 } 1251 #endif 1252 1253 return(filesize); 1254 } 1255 1256 int emu_LoadFileSeek(char * filename, char * buf, int size, int seek) 1257 { 1258 int filesize = 0; 1259 1260 char filepath[80]; 1261 strcpy(filepath, romspath); 1262 strcat(filepath, "/"); 1263 strcat(filepath, filename); 1264 emu_printf("LoadFileSeek..."); 1265 emu_printf(filepath); 1266 #ifdef USE_SDFS 1267 if( !(f_open(&file, filepath, FA_READ)) ) { 1268 f_lseek(&file, seek); 1269 emu_printf(size); 1270 if (size >= filesize) 1271 { 1272 int retval=0; 1273 if( (!f_read (&file, buf, size, &retval)) ) 1274 if (retval != size) 1275 { 1276 emu_printf("File read failed"); 1277 } 1278 } 1279 f_close(&file); 1280 } 1281 #else 1282 if ((file = SD.open(filepath, O_READ))) 1283 { 1284 file.seek(seek); 1285 emu_printf(size); 1286 if (file.read(buf, size) != size) { 1287 emu_printf("File read failed"); 1288 } 1289 file.close(); 1290 } 1291 #endif 1292 1293 return(filesize); 1294 } 1295 1296 const uint32_t FILE_SIZE_MB = 8; 1297 const uint32_t FILE_SIZE = 1000000UL*FILE_SIZE_MB; 1298 #ifdef USE_SDFS 1299 static FIL tempfile; 1300 #else 1301 static File tempfile; 1302 #endif 1303 1304 void emu_FileTempInit(void) 1305 { 1306 #ifdef USE_SDFS 1307 if( (f_open(&tempfile, SDFSDEV "/bench.dat", FA_READ| FA_WRITE )) ) { 1308 #else 1309 #ifdef USE_SDFAT 1310 if (!tempfile.open("/bench.dat", O_RDWR /*| O_CREAT | O_TRUNC*/)) { 1311 #else 1312 if ((tempfile = SD.open("/bench.dat", O_RDWR))) { 1313 #endif 1314 #endif 1315 Serial.println("psram open failed"); 1316 } 1317 /* 1318 else { 1319 uint8_t buf[256]; 1320 Serial.println("psram creating"); 1321 file = SD.open("/bench.dat", O_RDWR | O_CREAT | O_TRUNC); 1322 if (file) { 1323 Serial.println("psram opened"); 1324 file.truncate(0); 1325 1326 if (!file.preAllocate(FILE_SIZE)) { 1327 Serial.println("allocate failed"); 1328 } 1329 for(int i=0;i<FILE_SIZE/256;i++){ 1330 file.write(buf, 256); 1331 Serial.println(i); 1332 1333 } 1334 Serial.println("psram created"); 1335 } 1336 1337 //file.close(); 1338 } 1339 */ 1340 #ifdef USE_SDFS 1341 FILINFO entry; 1342 f_stat(SDFSDEV "/bench.dat", &entry); 1343 int fs=entry.fsize; 1344 #else 1345 int fs=tempfile.size(); 1346 #endif 1347 Serial.print("psram size is "); 1348 Serial.println(fs); 1349 } 1350 1351 void emu_FileTempRead(int addr, unsigned char * val, int n) 1352 { 1353 #ifdef USE_SDFS 1354 f_lseek(&file, addr); 1355 int retval=0; 1356 f_read (&file, val, n, &retval); 1357 #else 1358 tempfile.seek(addr); 1359 tempfile.read(val, n); 1360 #endif 1361 } 1362 1363 void emu_FileTempWrite(int addr, unsigned char val) 1364 { 1365 uint8_t v=val; 1366 #ifdef USE_SDFS 1367 f_lseek(&tempfile, addr); 1368 int retval=0; 1369 f_write (&tempfile, &v, 1, &retval); 1370 #else 1371 tempfile.seek(addr); 1372 tempfile.write(&v, 1); 1373 #endif 1374 } 1375 1376 #ifdef HAS_USBKEY 1377 void OnPress(auto key) 1378 { 1379 uint8_t keymodifier = keyboard1.getModifiers(); 1380 1381 if(keymodifier == 0x40){ 1382 // ALTGR Key modifier FR Keyboard 1383 switch (key) { 1384 #ifdef LAYOUT_FRENCH 1385 case 233 : key = '~' ; break; 1386 case 34 : key = '#' ; break; 1387 case 39 : key = '{' ; break; 1388 case 40 : key = '[' ; break; 1389 case 45 : key = '|' ; break; 1390 case 232 : key = '`' ; break; 1391 case 95 : key = 92 ; break; 1392 case 231 : key = '^' ; break; 1393 case 224 : key = '@' ; break; 1394 case 41 : key = ']' ; break; 1395 case 61 : key = '}' ; break; 1396 #endif 1397 #ifdef LAYOUT_FRENCH_BELGIAN 1398 case 38 : key = '|' ; break; //1 1399 case 233 : key = '@' ; break; //2 1400 case 34 : key = '#' ; break; //3 1401 case 167 : key = '^' ; break; //6 1402 case 231 : key = '{' ; break; //9 1403 case 224 : key = '}' ; break; //0 1404 case 36 : key = ']' ; break; //$ 1405 case 61 : key = '~' ; break; //= 1406 #endif 1407 } 1408 } 1409 1410 if (menuActive()) 1411 { 1412 switch (key) 1413 { 1414 case 217: 1415 usbnavpad |= MASK_JOY2_DOWN; 1416 break; 1417 case 218: 1418 usbnavpad |= MASK_JOY2_UP; 1419 break; 1420 case 216: 1421 usbnavpad |= MASK_JOY2_LEFT; 1422 break; 1423 case 215: 1424 usbnavpad |= MASK_JOY2_RIGHT; 1425 break; 1426 case 10: 1427 usbnavpad |= MASK_JOY2_BTN; 1428 break; 1429 } 1430 } 1431 else 1432 { 1433 emu_KeyboardOnDown(keymodifier, key); 1434 } 1435 } 1436 1437 void OnRelease(int key) 1438 { 1439 uint8_t keymodifier = keyboard1.getModifiers(); 1440 1441 if(keymodifier == 0x40){ 1442 // ALTGR Key modifier FR Keyboard 1443 switch (key) { 1444 #ifdef LAYOUT_FRENCH 1445 case 233 : key = '~' ; break; 1446 case 34 : key = '#' ; break; 1447 case 39 : key = '{' ; break; 1448 case 40 : key = '[' ; break; 1449 case 45 : key = '|' ; break; 1450 case 232 : key = '`' ; break; 1451 case 95 : key = 92 ; break; 1452 case 231 : key = '^' ; break; 1453 case 224 : key = '@' ; break; 1454 case 41 : key = ']' ; break; 1455 case 61 : key = '}' ; break; 1456 #endif 1457 #ifdef LAYOUT_FRENCH_BELGIAN 1458 case 38 : key = '|' ; break; //1 1459 case 233 : key = '@' ; break; //2 1460 case 34 : key = '#' ; break; //3 1461 case 167 : key = '^' ; break; //6 1462 case 231 : key = '{' ; break; //9 1463 case 224 : key = '}' ; break; //0 1464 case 36 : key = ']' ; break; //$ 1465 case 61 : key = '~' ; break; //= 1466 #endif 1467 } 1468 } 1469 1470 if (menuActive()) 1471 { 1472 switch (key) 1473 { 1474 case 217: 1475 usbnavpad &= ~MASK_JOY2_DOWN; 1476 break; 1477 case 218: 1478 usbnavpad &= ~MASK_JOY2_UP; 1479 break; 1480 case 216: 1481 usbnavpad &= ~MASK_JOY2_LEFT; 1482 break; 1483 case 215: 1484 usbnavpad &= ~MASK_JOY2_RIGHT; 1485 break; 1486 case 10: 1487 usbnavpad &= ~MASK_JOY2_BTN; 1488 break; 1489 } 1490 } 1491 else 1492 { 1493 emu_KeyboardOnUp(keymodifier, key); 1494 } 1495 } 1496 #endif 1497 1498 void emu_init(void) 1499 { 1500 Serial.begin(115200); 1501 1502 #ifdef HAS_USBKEY 1503 myusb.begin(); 1504 keyboard1.attachPress(OnPress); 1505 keyboard1.attachRelease(OnRelease); 1506 #endif 1507 1508 #ifdef USE_SDFS 1509 strcpy(romspath,SDFSDEV); 1510 strcat(romspath,ROMSDIR); 1511 FRESULT rc; 1512 if((rc = f_mount (&fatfs, romspath, 1))) { 1513 emu_printf("Fail mounting SDFS"); 1514 } 1515 else { 1516 rc = f_chdrive(ROMSDIR); 1517 } 1518 #else 1519 #ifdef USE_SDFAT 1520 while (!SD.begin(SD_CONFIG)) 1521 #else 1522 while (!SD.begin(SD_CS)) 1523 #endif 1524 { 1525 Serial.println("SD begin failed, retrying..."); 1526 delay(1000); 1527 } 1528 strcpy(romspath,ROMSDIR); 1529 #endif 1530 1531 nbFiles = readNbFiles(); 1532 1533 Serial.print("SD initialized, files found: "); 1534 Serial.println(nbFiles); 1535 1536 emu_InitJoysticks(); 1537 #ifdef SWAP_JOYSTICK 1538 joySwapped = true; 1539 #else 1540 joySwapped = false; 1541 #endif 1542 readCallibration(); 1543 1544 if ((tft.isTouching()) || (emu_ReadKeys() & MASK_JOY2_BTN) ) { 1545 callibrationInit(); 1546 } 1547 else 1548 { 1549 toggleMenu(true); 1550 } 1551 } 1552 1553 1554 void emu_start(void) 1555 { 1556 #ifdef HAS_I2CKBD 1557 byte msg[7]={0,0,0,0,0,0,0}; 1558 Wire.begin(); // join i2c bus SDA2/SCL2 1559 Wire.requestFrom(8, 7); // request 7 bytes from slave device #8 1560 int i = 0; 1561 while (Wire.available() && (i<7) ) { // slave may send less than requested 1562 byte b = Wire.read(); // receive a byte 1563 msg[i++] = b; 1564 } 1565 /* 1566 Serial.println(msg[0], BIN); 1567 Serial.println(msg[1], BIN); 1568 Serial.println(msg[2], BIN); 1569 Serial.println(msg[3], BIN); 1570 Serial.println(msg[4], BIN); 1571 Serial.println(msg[5], BIN); 1572 Serial.println(msg[6], BIN); 1573 */ 1574 if ( (msg[0] == 0xff) && (msg[1] == 0xff) && 1575 (msg[2] == 0xff) && (msg[3] == 0xff) && 1576 (msg[4] == 0xff) && (msg[5] == 0xff) && (msg[6] == 0xff)) { 1577 i2cKeyboardPresent = true; 1578 Serial.println("i2C keyboard found"); 1579 } 1580 #endif 1581 1582 usbnavpad = 0; 1583 1584 keys = key_map1; 1585 keyMap = 0; 1586 }