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