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