kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
1588 wiersze
36 KiB
C++
1588 wiersze
36 KiB
C++
#define KEYMAP_PRESENT 1
|
|
|
|
extern "C" {
|
|
#include "emuapi.h"
|
|
#include "iopins.h"
|
|
}
|
|
|
|
#ifdef HAS_T4_VGA
|
|
#include "vga_t_dma.h"
|
|
const uint16_t deflogo[] = {
|
|
0,0
|
|
};
|
|
static const uint16_t * logo = deflogo;
|
|
#else
|
|
#include "tft_t_dma.h"
|
|
#include "logo.h"
|
|
#endif
|
|
|
|
#include "bmpjoy.h"
|
|
#include "bmpvbar.h"
|
|
#ifdef OLD_LAYOUT
|
|
#include "bmpvga.h"
|
|
#include "bmptft.h"
|
|
#endif
|
|
|
|
|
|
#ifdef HAS_I2CKBD
|
|
#include <Wire.h>
|
|
#endif
|
|
|
|
#ifdef HAS_USBKEY
|
|
#include "USBHost_t36.h" // Read this header first for key info
|
|
USBHost myusb;
|
|
USBHub hub1(myusb);
|
|
KeyboardController keyboard1(myusb);
|
|
#endif
|
|
static uint8_t usbnavpad=0;
|
|
|
|
#ifdef USE_SDFS
|
|
#include "uSDFS.h"
|
|
static FATFS fatfs;
|
|
static FIL file;
|
|
#else
|
|
|
|
#ifdef USE_SDFAT
|
|
#include "SdFat.h"
|
|
#include "sdios.h"
|
|
|
|
#ifndef SDCARD_SS_PIN
|
|
const uint8_t SD_CS_PIN = SS;
|
|
|
|
#else // SDCARD_SS_PIN
|
|
// Assume built-in SD is used.
|
|
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
|
|
#endif // SDCARD_SS_PIN
|
|
|
|
#define SD_CONFIG SdioConfig(FIFO_SDIO)
|
|
|
|
// Try to select the best SD card configuration.
|
|
#if HAS_SDIO_CLASS
|
|
#define SD_CONFIG SdioConfig(FIFO_SDIO)
|
|
#elif ENABLE_DEDICATED_SPI
|
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI)
|
|
#else // HAS_SDIO_CLASS
|
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI)
|
|
#endif // HAS_SDIO_CLASS
|
|
//------------------------------------------------------------------------------
|
|
|
|
#if SD_FAT_TYPE == 0
|
|
#elif SD_FAT_TYPE == 1
|
|
#define SdFat SdFat32
|
|
#define File File32
|
|
#elif SD_FAT_TYPE == 2
|
|
#define SdFat SdExFat
|
|
#define File ExFile
|
|
#elif SD_FAT_TYPE == 3
|
|
#define SdFat SdFs
|
|
#define File FsFile
|
|
#endif // SD_FAT_TYPE
|
|
static SdFat SD;
|
|
#else
|
|
#include <SD.h>
|
|
#endif
|
|
static File file;
|
|
#endif
|
|
|
|
#define CALIBRATION_FILE "/cal.cfg"
|
|
|
|
#define MKEY_L1 1
|
|
#define MKEY_L2 2
|
|
#define MKEY_L3 3
|
|
#define MKEY_L4 4
|
|
#define MKEY_L5 5
|
|
#define MKEY_L6 6
|
|
#define MKEY_L7 7
|
|
#define MKEY_L8 8
|
|
#define MKEY_L9 9
|
|
#define MKEY_UP 20
|
|
#define MKEY_DOWN 21
|
|
#define MKEY_JOY 22
|
|
#define MKEY_TFT 23
|
|
#define MKEY_VGA 24
|
|
|
|
#define MAX_FILES 64
|
|
#define MAX_FILENAME_SIZE 24
|
|
#define MAX_MENULINES (MKEY_L9)
|
|
#define TEXT_HEIGHT 16
|
|
#define TEXT_WIDTH 8
|
|
#define MENU_FILE_XOFFSET (6*TEXT_WIDTH)
|
|
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
|
|
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
|
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
|
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
|
|
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
|
|
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
|
|
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
|
|
|
|
#define MENU_TFT_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
|
|
#define MENU_TFT_YOFFSET (MENU_VBAR_YOFFSET+32)
|
|
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
|
|
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
|
|
|
|
extern TFT_T_DMA tft;
|
|
|
|
static char romspath[64];
|
|
static int nbFiles=0;
|
|
static int curFile=0;
|
|
static int topFile=0;
|
|
static char selection[MAX_FILENAME_SIZE+1]="";
|
|
static char files[MAX_FILES][MAX_FILENAME_SIZE];
|
|
static bool menuRedraw=true;
|
|
|
|
static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
|
static bool i2cKeyboardPresent = false;
|
|
static unsigned short * keys;
|
|
static int keyMap;
|
|
|
|
const unsigned short menutouchareas[] = {
|
|
TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
|
|
TAREA_WH,MENU_FILE_W, TEXT_HEIGHT,
|
|
TAREA_NEW_COL,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,
|
|
|
|
TAREA_XY,MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,
|
|
TAREA_WH,32,48,
|
|
TAREA_NEW_COL, 72,72,8,40,
|
|
|
|
TAREA_XY,MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,
|
|
TAREA_WH,32,37,
|
|
TAREA_NEW_COL, 38,38,
|
|
|
|
TAREA_END};
|
|
|
|
const unsigned short menutouchactions[] = {
|
|
MKEY_L1,MKEY_L2,MKEY_L3,MKEY_L4,MKEY_L5,MKEY_L6,MKEY_L7,MKEY_L8,MKEY_L9,
|
|
MKEY_UP,MKEY_DOWN,ACTION_NONE,MKEY_JOY,
|
|
MKEY_TFT,MKEY_VGA};
|
|
|
|
|
|
static int keypadval=0;
|
|
static boolean joySwapped = false;
|
|
static uint16_t bLastState;
|
|
static int xRef;
|
|
static int yRef;
|
|
static uint8_t prev_zt=0;
|
|
|
|
static bool menuOn=true;
|
|
static bool callibrationOn=false;
|
|
static int callibrationStep=0;
|
|
|
|
|
|
static char captureTouchZone(const unsigned short * areas, const unsigned short * actions, int *rx, int *ry, int *rw, int * rh) {
|
|
uint16_t xt=0;
|
|
uint16_t yt=0;
|
|
uint16_t zt=0;
|
|
boolean hDir=true;
|
|
|
|
if (tft.isTouching())
|
|
{
|
|
if (prev_zt == 0) {
|
|
prev_zt =1;
|
|
tft.readCal(&xt,&yt,&zt);
|
|
if (zt<1000) {
|
|
prev_zt=0;
|
|
return ACTION_NONE;
|
|
}
|
|
int i=0;
|
|
int k=0;
|
|
int y2=0, y1=0;
|
|
int x2=0, x1=0;
|
|
int x=KEYBOARD_X,y=KEYBOARD_Y;
|
|
int w=TAREA_W_DEF,h=TAREA_H_DEF;
|
|
uint8_t s;
|
|
while ( (s=areas[i++]) != TAREA_END ) {
|
|
if (s == TAREA_XY) {
|
|
x = areas[i++];
|
|
y = areas[i++];
|
|
x2 = x;
|
|
y2 = y;
|
|
}
|
|
else if (s == TAREA_WH) {
|
|
w = areas[i++];
|
|
h = areas[i++];
|
|
}
|
|
else if (s == TAREA_NEW_ROW) {
|
|
hDir = true;
|
|
y1 = y2;
|
|
y2 = y1 + h;
|
|
x2 = x;
|
|
}
|
|
else if (s == TAREA_NEW_COL) {
|
|
hDir = false;
|
|
x1 = x2;
|
|
x2 = x1 + w;
|
|
y2 = y;
|
|
}
|
|
else {
|
|
if (hDir) {
|
|
x1 = x2;
|
|
x2 = x1+s;
|
|
} else {
|
|
y1 = y2;
|
|
y2 = y1+s;
|
|
}
|
|
if ( (yt >= y1) && (yt < y2) && (xt >= x1) && (xt < x2) ) {
|
|
*rx = x1;
|
|
*ry = y1;
|
|
*rw = x2-x1;
|
|
*rh = y2-y1;
|
|
return (actions[k]);
|
|
}
|
|
k++;
|
|
}
|
|
}
|
|
}
|
|
prev_zt =1;
|
|
} else {
|
|
prev_zt=0;
|
|
}
|
|
|
|
return ACTION_NONE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void emu_printf(char * text)
|
|
{
|
|
Serial.println(text);
|
|
}
|
|
|
|
void emu_printf(int val)
|
|
{
|
|
Serial.println(val);
|
|
}
|
|
|
|
void emu_printi(int val)
|
|
{
|
|
Serial.println(val,HEX);
|
|
}
|
|
|
|
void emu_printh(int val)
|
|
{
|
|
Serial.println(val,HEX);
|
|
}
|
|
|
|
static int malbufpt = 0;
|
|
static char malbuf[EXTRA_HEAP];
|
|
|
|
void * emu_Malloc(int size)
|
|
{
|
|
void * retval = malloc(size);
|
|
if (!retval) {
|
|
emu_printf("failled to allocate");
|
|
emu_printf(size);
|
|
emu_printf("fallback");
|
|
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
|
retval = (void *)&malbuf[malbufpt];
|
|
malbufpt += size;
|
|
}
|
|
else {
|
|
emu_printf("failure to allocate");
|
|
}
|
|
}
|
|
else {
|
|
emu_printf("could allocate dynamic ");
|
|
emu_printf(size);
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
void * emu_MallocI(int size)
|
|
{
|
|
void * retval = NULL;
|
|
|
|
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
|
retval = (void *)&malbuf[malbufpt];
|
|
malbufpt += size;
|
|
emu_printf("could allocate static ");
|
|
emu_printf(size);
|
|
}
|
|
else {
|
|
emu_printf("failure to allocate");
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
void emu_Free(void * pt)
|
|
{
|
|
free(pt);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int emu_ReadAnalogJoyX(int min, int max)
|
|
{
|
|
int val = analogRead(PIN_JOY2_A1X);
|
|
#if INVX
|
|
val = 4095 - val;
|
|
#endif
|
|
val = val-xRef;
|
|
val = ((val*140)/100);
|
|
if ( (val > -512) && (val < 512) ) val = 0;
|
|
val = val+2048;
|
|
return (val*(max-min))/4096;
|
|
}
|
|
|
|
int emu_ReadAnalogJoyY(int min, int max)
|
|
{
|
|
int val = analogRead(PIN_JOY2_A2Y);
|
|
#if INVY
|
|
val = 4095 - val;
|
|
#endif
|
|
val = val-yRef;
|
|
val = ((val*120)/100);
|
|
if ( (val > -512) && (val < 512) ) val = 0;
|
|
//val = (val*(max-min))/4096;
|
|
val = val+2048;
|
|
//return val+(max-min)/2;
|
|
return (val*(max-min))/4096;
|
|
}
|
|
|
|
|
|
static uint16_t readAnalogJoystick(void)
|
|
{
|
|
uint16_t joysval = 0;
|
|
|
|
int xReading = emu_ReadAnalogJoyX(0,256);
|
|
if (xReading > 128) joysval |= MASK_JOY2_LEFT;
|
|
else if (xReading < 128) joysval |= MASK_JOY2_RIGHT;
|
|
|
|
int yReading = emu_ReadAnalogJoyY(0,256);
|
|
if (yReading < 128) joysval |= MASK_JOY2_UP;
|
|
else if (yReading > 128) joysval |= MASK_JOY2_DOWN;
|
|
|
|
#ifdef PIN_JOY2_BTN
|
|
joysval |= (digitalRead(PIN_JOY2_BTN) == HIGH ? 0 : MASK_JOY2_BTN);
|
|
#endif
|
|
return (joysval);
|
|
}
|
|
|
|
|
|
int emu_SwapJoysticks(int statusOnly) {
|
|
if (!statusOnly) {
|
|
if (joySwapped) {
|
|
joySwapped = false;
|
|
}
|
|
else {
|
|
joySwapped = true;
|
|
}
|
|
}
|
|
return(joySwapped?1:0);
|
|
}
|
|
|
|
int emu_GetPad(void)
|
|
{
|
|
return(keypadval/*|((joySwapped?1:0)<<7)*/);
|
|
}
|
|
|
|
int emu_ReadKeys(void)
|
|
{
|
|
uint16_t retval;
|
|
uint16_t j1 = readAnalogJoystick();
|
|
uint16_t j2 = 0;
|
|
|
|
// Second joystick
|
|
#if INVY
|
|
#ifdef PIN_JOY1_1
|
|
if ( digitalRead(PIN_JOY1_1) == LOW ) j2 |= MASK_JOY2_DOWN;
|
|
#endif
|
|
#ifdef PIN_JOY1_2
|
|
if ( digitalRead(PIN_JOY1_2) == LOW ) j2 |= MASK_JOY2_UP;
|
|
#endif
|
|
#else
|
|
#ifdef PIN_JOY1_1
|
|
if ( digitalRead(PIN_JOY1_1) == LOW ) j2 |= MASK_JOY2_UP;
|
|
#endif
|
|
#ifdef PIN_JOY1_2
|
|
if ( digitalRead(PIN_JOY1_2) == LOW ) j2 |= MASK_JOY2_DOWN;
|
|
#endif
|
|
#endif
|
|
#if INVX
|
|
#ifdef PIN_JOY1_3
|
|
if ( digitalRead(PIN_JOY1_3) == LOW ) j2 |= MASK_JOY2_LEFT;
|
|
#endif
|
|
#ifdef PIN_JOY1_4
|
|
if ( digitalRead(PIN_JOY1_4) == LOW ) j2 |= MASK_JOY2_RIGHT;
|
|
#endif
|
|
#else
|
|
#ifdef PIN_JOY1_3
|
|
if ( digitalRead(PIN_JOY1_3) == LOW ) j2 |= MASK_JOY2_RIGHT;
|
|
#endif
|
|
#ifdef PIN_JOY1_4
|
|
if ( digitalRead(PIN_JOY1_4) == LOW ) j2 |= MASK_JOY2_LEFT;
|
|
#endif
|
|
#endif
|
|
#ifdef PIN_JOY1_BTN
|
|
if ( digitalRead(PIN_JOY1_BTN) == LOW ) j2 |= MASK_JOY2_BTN;
|
|
#endif
|
|
if (joySwapped) {
|
|
retval = ((j1 << 8) | j2);
|
|
}
|
|
else {
|
|
retval = ((j2 << 8) | j1);
|
|
}
|
|
|
|
if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP;
|
|
if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN;
|
|
if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT;
|
|
if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT;
|
|
if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN;
|
|
|
|
#ifdef PIN_KEY_USER1
|
|
if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
|
|
#endif
|
|
#ifdef PIN_KEY_USER2
|
|
if ( digitalRead(PIN_KEY_USER2) == LOW ) retval |= MASK_KEY_USER2;
|
|
#endif
|
|
#ifdef PIN_KEY_USER3
|
|
if ( digitalRead(PIN_KEY_USER3) == LOW ) retval |= MASK_KEY_USER3;
|
|
#endif
|
|
#ifdef PIN_KEY_USER4
|
|
if ( digitalRead(PIN_KEY_USER4) == LOW ) retval |= MASK_KEY_USER4;
|
|
#endif
|
|
|
|
//Serial.println(retval,HEX);
|
|
|
|
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|
|
|| (retval & MASK_KEY_USER4 ) )
|
|
{
|
|
// Reset procedure T3.X and T4.0 by Frank Boesing !!
|
|
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
|
uint32_t tmp = SNVS_LPCR; // save control register
|
|
|
|
SNVS_LPSR |= 1;
|
|
|
|
// disable alarm
|
|
SNVS_LPCR &= ~0x02;
|
|
while (SNVS_LPCR & 0x02);
|
|
|
|
__disable_irq();
|
|
//get Time:
|
|
uint32_t lsb, msb;
|
|
do {
|
|
msb = SNVS_LPSRTCMR;
|
|
lsb = SNVS_LPSRTCLR;
|
|
} while ( (SNVS_LPSRTCLR != lsb) | (SNVS_LPSRTCMR != msb) );
|
|
uint32_t secs = (msb << 17) | (lsb >> 15);
|
|
|
|
//set alarm
|
|
secs += 2;
|
|
SNVS_LPTAR = secs;
|
|
while (SNVS_LPTAR != secs);
|
|
|
|
SNVS_LPCR = tmp | 0x02; // restore control register and set alarm
|
|
while (!(SNVS_LPCR & 0x02));
|
|
|
|
SNVS_LPCR |= (1 << 6); // turn off power
|
|
while (1) asm("wfi");
|
|
#else
|
|
*(volatile uint32_t *)0xE000ED0C = 0x5FA0004;
|
|
while (true) {
|
|
;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return (retval);
|
|
}
|
|
|
|
unsigned short emu_DebounceLocalKeys(void)
|
|
{
|
|
uint16_t bCurState = emu_ReadKeys();
|
|
uint16_t bClick = bCurState & ~bLastState;
|
|
bLastState = bCurState;
|
|
|
|
return (bClick);
|
|
}
|
|
|
|
int emu_ReadI2CKeyboard(void) {
|
|
int retval=0;
|
|
#ifdef HAS_I2CKBD
|
|
if (i2cKeyboardPresent) {
|
|
byte msg[7]={0,0,0,0,0,0,0};
|
|
Wire.requestFrom(8, 7); // request 7 bytes from slave device #8
|
|
int i = 0;
|
|
int hitindex=-1;
|
|
while (Wire.available() && (i<7) ) { // slave may send less than requested
|
|
byte b = Wire.read(); // receive a byte
|
|
if (b != 0xff) hitindex=i;
|
|
msg[i++] = b;
|
|
}
|
|
|
|
if (hitindex >=0 ) {
|
|
/*
|
|
Serial.println(msg[0], BIN);
|
|
Serial.println(msg[1], BIN);
|
|
Serial.println(msg[2], BIN);
|
|
Serial.println(msg[3], BIN);
|
|
Serial.println(msg[4], BIN);
|
|
Serial.println(msg[5], BIN);
|
|
Serial.println(msg[6], BIN);
|
|
*/
|
|
unsigned short match = (~msg[hitindex])&0x00FF | (hitindex<<8);
|
|
//Serial.println(match,HEX);
|
|
for (i=0; i<sizeof(i2ckeys); i++) {
|
|
if (match == i2ckeys[i]) {
|
|
//Serial.println((int)keys[i]);
|
|
return (keys[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return(retval);
|
|
}
|
|
|
|
void emu_InitJoysticks(void) {
|
|
|
|
// Second Joystick
|
|
#ifdef PIN_JOY1_1
|
|
pinMode(PIN_JOY1_1, INPUT_PULLUP);
|
|
#endif
|
|
#ifdef PIN_JOY1_2
|
|
pinMode(PIN_JOY1_2, INPUT_PULLUP);
|
|
#endif
|
|
#ifdef PIN_JOY1_3
|
|
pinMode(PIN_JOY1_3, INPUT_PULLUP);
|
|
#endif
|
|
#ifdef PIN_JOY1_4
|
|
pinMode(PIN_JOY1_4, INPUT_PULLUP);
|
|
#endif
|
|
#ifdef PIN_JOY1_BTN
|
|
pinMode(PIN_JOY1_BTN, INPUT_PULLUP);
|
|
#endif
|
|
|
|
#ifdef PIN_KEY_USER1
|
|
pinMode(PIN_KEY_USER1, INPUT_PULLUP);
|
|
#endif
|
|
#ifdef PIN_KEY_USER2
|
|
pinMode(PIN_KEY_USER2, INPUT_PULLUP);
|
|
#endif
|
|
#ifdef PIN_KEY_USER3
|
|
pinMode(PIN_KEY_USER3, INPUT_PULLUP);
|
|
#endif
|
|
#ifdef PIN_KEY_USER4
|
|
pinMode(PIN_KEY_USER4, INPUT_PULLUP);
|
|
#endif
|
|
#ifdef PIN_JOY2_BTN
|
|
pinMode(PIN_JOY2_BTN, INPUT_PULLUP);
|
|
#endif
|
|
analogReadResolution(12);
|
|
xRef=0; yRef=0;
|
|
for (int i=0; i<10; i++) {
|
|
xRef += analogRead(PIN_JOY2_A1X);
|
|
yRef += analogRead(PIN_JOY2_A2Y);
|
|
delay(20);
|
|
}
|
|
|
|
#if INVX
|
|
xRef = 4095 -xRef/10;
|
|
#else
|
|
xRef /= 10;
|
|
#endif
|
|
#if INVY
|
|
yRef = 4095 -yRef/10;
|
|
#else
|
|
yRef /= 10;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
static bool vkbKeepOn = false;
|
|
static bool vkbActive = false;
|
|
static bool vkeyRefresh=false;
|
|
static bool exitVkbd = false;
|
|
static uint8_t keyPressCount=0;
|
|
|
|
|
|
bool virtualkeyboardIsActive(void) {
|
|
return (vkbActive);
|
|
}
|
|
|
|
void toggleVirtualkeyboard(bool keepOn) {
|
|
|
|
if (keepOn) {
|
|
tft.drawSpriteNoDma(0,0,logo);
|
|
//prev_zt = 0;
|
|
vkbKeepOn = true;
|
|
vkbActive = true;
|
|
exitVkbd = false;
|
|
}
|
|
else {
|
|
vkbKeepOn = false;
|
|
if ( (vkbActive) /*|| (exitVkbd)*/ ) {
|
|
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
|
|
tft.startDMA();
|
|
//prev_zt = 0;
|
|
vkbActive = false;
|
|
exitVkbd = false;
|
|
}
|
|
else {
|
|
tft.stopDMA();
|
|
tft.drawSpriteNoDma(0,0,logo);
|
|
//prev_zt = 0;
|
|
vkbActive = true;
|
|
exitVkbd = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void handleVirtualkeyboard() {
|
|
int rx=0,ry=0,rw=0,rh=0;
|
|
|
|
if (keyPressCount == 0) {
|
|
keypadval = 0;
|
|
} else {
|
|
keyPressCount--;
|
|
}
|
|
|
|
if ( (!virtualkeyboardIsActive()) && (tft.isTouching()) && (!keyPressCount) ) {
|
|
toggleVirtualkeyboard(false);
|
|
return;
|
|
}
|
|
|
|
if ( ( (vkbKeepOn) || (virtualkeyboardIsActive()) ) ) {
|
|
char c = captureTouchZone(keysw, keys, &rx,&ry,&rw,&rh);
|
|
if (c) {
|
|
|
|
tft.drawRectNoDma( rx,ry,rw,rh, KEYBOARD_HIT_COLOR );
|
|
if ( (c >=1) && (c <= ACTION_MAXKBDVAL) ) {
|
|
|
|
keypadval = c;
|
|
keyPressCount = 10;
|
|
delay(50);
|
|
vkeyRefresh = true;
|
|
exitVkbd = true;
|
|
}
|
|
else if (c == ACTION_EXITKBD) {
|
|
vkeyRefresh = true;
|
|
exitVkbd = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (vkeyRefresh) {
|
|
vkeyRefresh = false;
|
|
tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh);
|
|
}
|
|
|
|
if ( (exitVkbd) && (vkbActive) ) {
|
|
if (!vkbKeepOn) {
|
|
toggleVirtualkeyboard(false);
|
|
}
|
|
else {
|
|
toggleVirtualkeyboard(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
int emu_setKeymap(int index) {
|
|
}
|
|
|
|
|
|
|
|
|
|
static int readNbFiles(void) {
|
|
int totalFiles = 0;
|
|
|
|
#ifdef USE_SDFS
|
|
DIR dir;
|
|
FILINFO entry;
|
|
f_opendir(&dir, romspath);
|
|
while ( (true) && (totalFiles<MAX_FILES) ) {
|
|
f_readdir(&dir, &entry);
|
|
if (!entry.fname[0]) {
|
|
// no more files
|
|
break;
|
|
}
|
|
char * filename = entry.fname;
|
|
Serial.println(filename);
|
|
if ( !(entry.fattrib & AM_DIR) ) {
|
|
strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1);
|
|
totalFiles++;
|
|
}
|
|
else {
|
|
if ( (strcmp(filename,".")) && (strcmp(filename,"..")) ) {
|
|
strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1);
|
|
totalFiles++;
|
|
}
|
|
}
|
|
}
|
|
f_closedir(&dir);
|
|
#else
|
|
File entry;
|
|
file = SD.open(romspath);
|
|
while ( (true) && (totalFiles<MAX_FILES) ) {
|
|
entry = file.openNextFile();
|
|
if (! entry) {
|
|
// no more files
|
|
break;
|
|
}
|
|
#ifdef USE_SDFAT
|
|
char filename[MAX_FILENAME_SIZE];
|
|
entry.getName(&filename[0], MAX_FILENAME_SIZE);
|
|
#else
|
|
char * filename = entry.name();
|
|
#endif
|
|
Serial.println(filename);
|
|
if (!entry.isDirectory()) {
|
|
strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1);
|
|
totalFiles++;
|
|
}
|
|
else {
|
|
if ( (strcmp(filename,".")) && (strcmp(filename,"..")) ) {
|
|
strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1);
|
|
totalFiles++;
|
|
}
|
|
}
|
|
entry.close();
|
|
}
|
|
file.close();
|
|
#endif
|
|
return totalFiles;
|
|
}
|
|
|
|
|
|
|
|
void backgroundMenu(void) {
|
|
menuRedraw=true;
|
|
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
|
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
|
#ifndef HAS_T4_VGA
|
|
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar);
|
|
#endif
|
|
#ifdef OLD_LAYOUT
|
|
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft);
|
|
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga);
|
|
#endif
|
|
}
|
|
|
|
int handleMenu(uint16_t bClick)
|
|
{
|
|
int action = ACTION_NONE;
|
|
|
|
char newpath[80];
|
|
strcpy(newpath, romspath);
|
|
strcat(newpath, "/");
|
|
strcat(newpath, selection);
|
|
|
|
int rx=0,ry=0,rw=0,rh=0;
|
|
char c = 0; //captureTouchZone(menutouchareas, menutouchactions, &rx,&ry,&rw,&rh);
|
|
|
|
if ( (bClick & MASK_JOY2_BTN) || (c == MKEY_TFT) ) {
|
|
emu_printf(newpath);
|
|
#ifdef USE_SDFS
|
|
FILINFO entry;
|
|
f_stat(newpath, &entry);
|
|
if ( (entry.fattrib & AM_DIR) ) {
|
|
#else
|
|
File file = SD.open(newpath);
|
|
if (file.isDirectory()) {
|
|
#endif
|
|
strcpy(romspath,newpath);
|
|
curFile = 0;
|
|
nbFiles = readNbFiles();
|
|
}
|
|
else {
|
|
action = ACTION_RUNTFT;
|
|
}
|
|
menuRedraw=true;
|
|
}
|
|
else if ( (bClick & MASK_KEY_USER1) || (c == MKEY_VGA) ) {
|
|
menuRedraw=true;
|
|
action = ACTION_RUNVGA;
|
|
}
|
|
else if ( (c >= MKEY_L1) && (c <= MKEY_L9) ) {
|
|
if ( (topFile+(int)c-1) <= (nbFiles-1) )
|
|
{
|
|
curFile = topFile + (int)c -1;
|
|
menuRedraw=true;
|
|
//tft.drawRectNoDma( rx,ry,rw,rh, KEYBOARD_HIT_COLOR );
|
|
}
|
|
}
|
|
else if (bClick & MASK_JOY2_UP) {
|
|
if (curFile!=0) {
|
|
menuRedraw=true;
|
|
curFile--;
|
|
}
|
|
}
|
|
else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) || (c == MKEY_UP) ) {
|
|
if ((curFile-9)>=0) {
|
|
menuRedraw=true;
|
|
curFile -= 9;
|
|
} else if (curFile!=0) {
|
|
menuRedraw=true;
|
|
curFile--;
|
|
}
|
|
}
|
|
else if (bClick & MASK_JOY2_DOWN) {
|
|
if ((curFile<(nbFiles-1)) && (nbFiles)) {
|
|
curFile++;
|
|
menuRedraw=true;
|
|
}
|
|
}
|
|
else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) || (c == MKEY_DOWN) ) {
|
|
if ((curFile<(nbFiles-9)) && (nbFiles)) {
|
|
curFile += 9;
|
|
menuRedraw=true;
|
|
}
|
|
else if ((curFile<(nbFiles-1)) && (nbFiles)) {
|
|
curFile++;
|
|
menuRedraw=true;
|
|
}
|
|
}
|
|
else if ( (bClick & MASK_KEY_USER2) || (c == MKEY_JOY) ) {
|
|
emu_SwapJoysticks(0);
|
|
menuRedraw=true;
|
|
}
|
|
|
|
if (menuRedraw && nbFiles) {
|
|
int fileIndex = 0;
|
|
tft.drawRectNoDma(MENU_FILE_XOFFSET,MENU_FILE_YOFFSET, MENU_FILE_W, MENU_FILE_H, MENU_FILE_BGCOLOR);
|
|
// if (curFile <= (MAX_MENULINES/2-1)) topFile=0;
|
|
// else topFile=curFile-(MAX_MENULINES/2);
|
|
if (curFile <= (MAX_MENULINES-1)) topFile=0;
|
|
else topFile=curFile-(MAX_MENULINES/2);
|
|
|
|
//Serial.print("curfile: ");
|
|
//Serial.println(curFile);
|
|
//Serial.print("topFile: ");
|
|
//Serial.println(topFile);
|
|
|
|
int i=0;
|
|
while (i<MAX_MENULINES) {
|
|
if (fileIndex>=nbFiles) {
|
|
// no more files
|
|
break;
|
|
}
|
|
char * filename = &files[fileIndex][0];
|
|
if (fileIndex >= topFile) {
|
|
if ((i+topFile) < nbFiles ) {
|
|
if ((i+topFile)==curFile) {
|
|
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
|
|
strcpy(selection,filename);
|
|
}
|
|
else {
|
|
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true);
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
fileIndex++;
|
|
}
|
|
|
|
#ifndef HAS_T4_VGA
|
|
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
|
#endif
|
|
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);
|
|
menuRedraw=false;
|
|
}
|
|
|
|
return (action);
|
|
}
|
|
|
|
bool menuActive(void)
|
|
{
|
|
return (menuOn);
|
|
}
|
|
|
|
void toggleMenu(bool on) {
|
|
if (on) {
|
|
callibrationOn=false;
|
|
menuOn=true;
|
|
backgroundMenu();
|
|
} else {
|
|
menuOn = false;
|
|
}
|
|
}
|
|
|
|
char * menuSelection(void)
|
|
{
|
|
return (selection);
|
|
}
|
|
|
|
|
|
|
|
|
|
static void callibrationInit(void)
|
|
{
|
|
callibrationOn=true;
|
|
menuOn=false;
|
|
callibrationStep = 0;
|
|
calMinX=0,calMinY=0,calMaxX=0,calMaxY=0;
|
|
tft.fillScreenNoDma(RGBVAL16(0xff,0xff,0xff));
|
|
tft.drawTextNoDma(0,100, " Callibration process:", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
|
|
tft.drawTextNoDma(0,116, " Hit the red cross at each corner", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
|
|
tft.drawTextNoDma(0,0, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
|
|
prev_zt = 1;
|
|
}
|
|
|
|
|
|
static void readCallibration(void)
|
|
{
|
|
char fileBuffer[64];
|
|
|
|
#ifdef USE_SDFS
|
|
FIL file;
|
|
int retval;
|
|
if( !(f_open(&file, CALIBRATION_FILE, FA_READ)) ) {
|
|
if( !(f_read (&file, fileBuffer, 64, &retval)) ) {
|
|
if (retval == 64) {
|
|
sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY);
|
|
}
|
|
}
|
|
f_close(&file);
|
|
}
|
|
#else
|
|
File file = SD.open(CALIBRATION_FILE, O_READ);
|
|
if (file) {
|
|
if ( file.read(fileBuffer, 64) ) {
|
|
sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY);
|
|
}
|
|
file.close();
|
|
Serial.println("Current callibration params:");
|
|
Serial.println(calMinX);
|
|
Serial.println(calMinY);
|
|
Serial.println(calMaxX);
|
|
Serial.println(calMaxY);
|
|
}
|
|
#endif
|
|
else {
|
|
Serial.println("Callibration read error");
|
|
}
|
|
tft.callibrateTouch(calMinX,calMinY,calMaxX,calMaxY);
|
|
}
|
|
|
|
static void writeCallibration(void)
|
|
{
|
|
tft.callibrateTouch(calMinX,calMinY,calMaxX,calMaxY);
|
|
|
|
#ifdef USE_SDFS
|
|
FIL file;
|
|
int retval;
|
|
if( !(f_open(&file, CALIBRATION_FILE, FA_WRITE)) ) {
|
|
//if( !(f_read (&file, fileBuffer, 64, &retval)) ) {
|
|
// if (retval == 64) {
|
|
// sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY);
|
|
// }
|
|
//}
|
|
f_close(&file);
|
|
}
|
|
#else
|
|
File file = SD.open(CALIBRATION_FILE, O_WRITE | O_CREAT | O_TRUNC);
|
|
if (file) {
|
|
file.print(calMinX);
|
|
file.print(" ");
|
|
file.print(calMinY);
|
|
file.print(" ");
|
|
file.print(calMaxX);
|
|
file.print(" ");
|
|
file.println(calMaxY);
|
|
file.close();
|
|
}
|
|
#endif
|
|
else {
|
|
Serial.println("Callibration write error");
|
|
}
|
|
}
|
|
|
|
|
|
bool callibrationActive(void)
|
|
{
|
|
return (callibrationOn);
|
|
}
|
|
|
|
|
|
|
|
int handleCallibration(uint16_t bClick) {
|
|
uint16_t xt=0;
|
|
uint16_t yt=0;
|
|
uint16_t zt=0;
|
|
if (tft.isTouching()) {
|
|
if (prev_zt == 0) {
|
|
prev_zt = 1;
|
|
tft.readRaw(&xt,&yt,&zt);
|
|
if (zt < 1000) {
|
|
return 0;
|
|
}
|
|
switch (callibrationStep)
|
|
{
|
|
case 0:
|
|
callibrationStep++;
|
|
tft.drawTextNoDma(0,0, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true);
|
|
tft.drawTextNoDma(TFT_REALWIDTH-8,0, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
|
|
calMinX += xt;
|
|
calMinY += yt;
|
|
break;
|
|
case 1:
|
|
callibrationStep++;
|
|
tft.drawTextNoDma(TFT_REALWIDTH-8,0, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true);
|
|
tft.drawTextNoDma(TFT_REALWIDTH-8,TFT_REALHEIGHT-16, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
|
|
calMaxX += xt;
|
|
calMinY += yt;
|
|
break;
|
|
case 2:
|
|
callibrationStep++;
|
|
tft.drawTextNoDma(TFT_REALWIDTH-8,TFT_REALHEIGHT-16, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true);
|
|
tft.drawTextNoDma(0,TFT_REALHEIGHT-16, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
|
|
calMaxX += xt;
|
|
calMaxY += yt;
|
|
break;
|
|
case 3:
|
|
tft.fillScreenNoDma(RGBVAL16(0xff,0xff,0xff));
|
|
tft.drawTextNoDma(0,100, " Callibration done!", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
|
|
tft.drawTextNoDma(0,116, " (Click center to exit)", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true);
|
|
callibrationStep++;
|
|
calMinX += xt;
|
|
calMaxY += yt;
|
|
break;
|
|
case 4:
|
|
//Serial.println(xt);
|
|
//Serial.println(yt);
|
|
if ( (xt > (TFT_REALWIDTH/4)) && (xt < (TFT_REALWIDTH*3)/4)
|
|
&& (yt > (TFT_REALHEIGHT/4)) && (yt < (TFT_REALHEIGHT*3)/4) ) {
|
|
calMinX /= 2;
|
|
calMinY /= 2;
|
|
calMaxX /= 2;
|
|
calMaxY /= 2;
|
|
writeCallibration();
|
|
toggleMenu(true);
|
|
}
|
|
else {
|
|
callibrationInit();
|
|
}
|
|
break;
|
|
|
|
}
|
|
delay(100);
|
|
}
|
|
}
|
|
else {
|
|
prev_zt = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
int emu_FileOpen(char * filename)
|
|
{
|
|
int retval = 0;
|
|
|
|
char filepath[80];
|
|
strcpy(filepath, romspath);
|
|
strcat(filepath, "/");
|
|
strcat(filepath, filename);
|
|
emu_printf("FileOpen...");
|
|
emu_printf(filepath);
|
|
#ifdef USE_SDFS
|
|
if( !(f_open(&file, filepath, FA_READ)) ) {
|
|
#else
|
|
if ((file = SD.open(filepath, O_READ))) {
|
|
#endif
|
|
retval = 1;
|
|
}
|
|
else {
|
|
emu_printf("FileOpen failed");
|
|
}
|
|
return (retval);
|
|
}
|
|
|
|
int emu_FileRead(char * buf, int size)
|
|
{
|
|
unsigned char buffer[256];
|
|
|
|
int remaining = size;
|
|
int byteread = 0;
|
|
int retval=0;
|
|
if (size < 256) {
|
|
#ifdef USE_SDFS
|
|
if( !(f_read (&file, buffer, size, &retval)) )
|
|
#else
|
|
retval = file.read(buffer, size);
|
|
#endif
|
|
if (retval>0) {
|
|
memcpy(buf,buffer,retval);
|
|
byteread += retval;
|
|
}
|
|
}
|
|
else {
|
|
while (remaining>0) {
|
|
#ifdef USE_SDFS
|
|
if( !(f_read (&file, buffer, 256, &retval)) )
|
|
//f_read (&file, buffer, 256, &retval);
|
|
#else
|
|
retval = file.read(buffer, 256);
|
|
#endif
|
|
if (retval>0) {
|
|
//emu_printi(retval);
|
|
memcpy(buf,buffer,retval);
|
|
buf += retval;
|
|
byteread += retval;
|
|
remaining -= retval;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return byteread;
|
|
}
|
|
|
|
unsigned char emu_FileGetc(void) {
|
|
unsigned char c;
|
|
#ifdef USE_SDFS
|
|
int retval=0;
|
|
if( !(f_read (&file, &c, 1, &retval)) )
|
|
#else
|
|
int retval = file.read(&c, 1);
|
|
#endif
|
|
if (retval != 1) {
|
|
emu_printf("emu_FileGetc failed");
|
|
}
|
|
return c;
|
|
}
|
|
|
|
|
|
void emu_FileClose(void)
|
|
{
|
|
#ifdef USE_SDFS
|
|
f_close(&file);
|
|
#else
|
|
file.close();
|
|
#endif
|
|
}
|
|
|
|
int emu_FileSize(char * filename)
|
|
{
|
|
int filesize=0;
|
|
char filepath[80];
|
|
strcpy(filepath, romspath);
|
|
strcat(filepath, "/");
|
|
strcat(filepath, filename);
|
|
emu_printf("FileSize...");
|
|
emu_printf(filepath);
|
|
#ifdef USE_SDFS
|
|
FILINFO entry;
|
|
f_stat(filepath, &entry);
|
|
filesize = entry.fsize;
|
|
#else
|
|
if ((file = SD.open(filepath, O_READ)))
|
|
{
|
|
emu_printf("filesize is...");
|
|
filesize = file.size();
|
|
emu_printf(filesize);
|
|
file.close();
|
|
}
|
|
#endif
|
|
|
|
return(filesize);
|
|
}
|
|
|
|
int emu_FileSeek(int seek)
|
|
{
|
|
#ifdef USE_SDFS
|
|
f_lseek(&file, seek);
|
|
#else
|
|
file.seek(seek);
|
|
#endif
|
|
return (seek);
|
|
}
|
|
|
|
int emu_FileTell(void)
|
|
{
|
|
#ifdef USE_SDFS
|
|
return (f_tell(&file));
|
|
#else
|
|
return (50);
|
|
#endif
|
|
}
|
|
|
|
|
|
int emu_LoadFile(char * filename, char * buf, int size)
|
|
{
|
|
int filesize = 0;
|
|
|
|
char filepath[80];
|
|
strcpy(filepath, romspath);
|
|
strcat(filepath, "/");
|
|
strcat(filepath, filename);
|
|
emu_printf("LoadFile...");
|
|
emu_printf(filepath);
|
|
#ifdef USE_SDFS
|
|
if( !(f_open(&file, filepath, FA_READ)) ) {
|
|
filesize = f_size(&file);
|
|
emu_printf(filesize);
|
|
if (size >= filesize)
|
|
{
|
|
int retval=0;
|
|
if( (f_read (&file, buf, filesize, &retval)) ) {
|
|
emu_printf("File read failed");
|
|
}
|
|
}
|
|
f_close(&file);
|
|
}
|
|
#else
|
|
if ((file = SD.open(filepath, O_READ)))
|
|
{
|
|
filesize = file.size();
|
|
emu_printf(filesize);
|
|
|
|
if (size >= filesize)
|
|
{
|
|
if (emu_FileRead(buf, filesize) != filesize)
|
|
{
|
|
emu_printf("File read failed");
|
|
}
|
|
}
|
|
file.close();
|
|
}
|
|
#endif
|
|
|
|
return(filesize);
|
|
}
|
|
|
|
int emu_LoadFileSeek(char * filename, char * buf, int size, int seek)
|
|
{
|
|
int filesize = 0;
|
|
|
|
char filepath[80];
|
|
strcpy(filepath, romspath);
|
|
strcat(filepath, "/");
|
|
strcat(filepath, filename);
|
|
emu_printf("LoadFileSeek...");
|
|
emu_printf(filepath);
|
|
#ifdef USE_SDFS
|
|
if( !(f_open(&file, filepath, FA_READ)) ) {
|
|
f_lseek(&file, seek);
|
|
emu_printf(size);
|
|
if (size >= filesize)
|
|
{
|
|
int retval=0;
|
|
if( (!f_read (&file, buf, size, &retval)) )
|
|
if (retval != size)
|
|
{
|
|
emu_printf("File read failed");
|
|
}
|
|
}
|
|
f_close(&file);
|
|
}
|
|
#else
|
|
if ((file = SD.open(filepath, O_READ)))
|
|
{
|
|
file.seek(seek);
|
|
emu_printf(size);
|
|
if (file.read(buf, size) != size) {
|
|
emu_printf("File read failed");
|
|
}
|
|
file.close();
|
|
}
|
|
#endif
|
|
|
|
return(filesize);
|
|
}
|
|
|
|
const uint32_t FILE_SIZE_MB = 8;
|
|
const uint32_t FILE_SIZE = 1000000UL*FILE_SIZE_MB;
|
|
#ifdef USE_SDFS
|
|
static FIL tempfile;
|
|
#else
|
|
static File tempfile;
|
|
#endif
|
|
|
|
void emu_FileTempInit(void)
|
|
{
|
|
#ifdef USE_SDFS
|
|
if( (f_open(&tempfile, SDFSDEV "/bench.dat", FA_READ| FA_WRITE )) ) {
|
|
#else
|
|
#ifdef USE_SDFAT
|
|
if (!tempfile.open("/bench.dat", O_RDWR /*| O_CREAT | O_TRUNC*/)) {
|
|
#else
|
|
if ((tempfile = SD.open("/bench.dat", O_RDWR))) {
|
|
#endif
|
|
#endif
|
|
Serial.println("psram open failed");
|
|
}
|
|
/*
|
|
else {
|
|
uint8_t buf[256];
|
|
Serial.println("psram creating");
|
|
file = SD.open("/bench.dat", O_RDWR | O_CREAT | O_TRUNC);
|
|
if (file) {
|
|
Serial.println("psram opened");
|
|
file.truncate(0);
|
|
|
|
if (!file.preAllocate(FILE_SIZE)) {
|
|
Serial.println("allocate failed");
|
|
}
|
|
for(int i=0;i<FILE_SIZE/256;i++){
|
|
file.write(buf, 256);
|
|
Serial.println(i);
|
|
|
|
}
|
|
Serial.println("psram created");
|
|
}
|
|
|
|
//file.close();
|
|
}
|
|
*/
|
|
#ifdef USE_SDFS
|
|
FILINFO entry;
|
|
f_stat(SDFSDEV "/bench.dat", &entry);
|
|
int fs=entry.fsize;
|
|
#else
|
|
int fs=tempfile.size();
|
|
#endif
|
|
Serial.print("psram size is ");
|
|
Serial.println(fs);
|
|
}
|
|
|
|
void emu_FileTempRead(int addr, unsigned char * val, int n)
|
|
{
|
|
#ifdef USE_SDFS
|
|
f_lseek(&file, addr);
|
|
int retval=0;
|
|
f_read (&file, val, n, &retval);
|
|
#else
|
|
tempfile.seek(addr);
|
|
tempfile.read(val, n);
|
|
#endif
|
|
}
|
|
|
|
void emu_FileTempWrite(int addr, unsigned char val)
|
|
{
|
|
uint8_t v=val;
|
|
#ifdef USE_SDFS
|
|
f_lseek(&tempfile, addr);
|
|
int retval=0;
|
|
f_write (&tempfile, &v, 1, &retval);
|
|
#else
|
|
tempfile.seek(addr);
|
|
tempfile.write(&v, 1);
|
|
#endif
|
|
}
|
|
|
|
#ifdef HAS_USBKEY
|
|
void OnPress(auto key)
|
|
{
|
|
uint8_t keymodifier = keyboard1.getModifiers();
|
|
|
|
if(keymodifier == 0x40){
|
|
// ALTGR Key modifier FR Keyboard
|
|
switch (key) {
|
|
#ifdef LAYOUT_FRENCH
|
|
case 233 : key = '~' ; break;
|
|
case 34 : key = '#' ; break;
|
|
case 39 : key = '{' ; break;
|
|
case 40 : key = '[' ; break;
|
|
case 45 : key = '|' ; break;
|
|
case 232 : key = '`' ; break;
|
|
case 95 : key = 92 ; break;
|
|
case 231 : key = '^' ; break;
|
|
case 224 : key = '@' ; break;
|
|
case 41 : key = ']' ; break;
|
|
case 61 : key = '}' ; break;
|
|
#endif
|
|
#ifdef LAYOUT_FRENCH_BELGIAN
|
|
case 38 : key = '|' ; break; //1
|
|
case 233 : key = '@' ; break; //2
|
|
case 34 : key = '#' ; break; //3
|
|
case 167 : key = '^' ; break; //6
|
|
case 231 : key = '{' ; break; //9
|
|
case 224 : key = '}' ; break; //0
|
|
case 36 : key = ']' ; break; //$
|
|
case 61 : key = '~' ; break; //=
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if (menuActive())
|
|
{
|
|
switch (key)
|
|
{
|
|
case 217:
|
|
usbnavpad |= MASK_JOY2_DOWN;
|
|
break;
|
|
case 218:
|
|
usbnavpad |= MASK_JOY2_UP;
|
|
break;
|
|
case 216:
|
|
usbnavpad |= MASK_JOY2_LEFT;
|
|
break;
|
|
case 215:
|
|
usbnavpad |= MASK_JOY2_RIGHT;
|
|
break;
|
|
case 10:
|
|
usbnavpad |= MASK_JOY2_BTN;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
emu_KeyboardOnDown(keymodifier, key);
|
|
}
|
|
}
|
|
|
|
void OnRelease(int key)
|
|
{
|
|
uint8_t keymodifier = keyboard1.getModifiers();
|
|
|
|
if(keymodifier == 0x40){
|
|
// ALTGR Key modifier FR Keyboard
|
|
switch (key) {
|
|
#ifdef LAYOUT_FRENCH
|
|
case 233 : key = '~' ; break;
|
|
case 34 : key = '#' ; break;
|
|
case 39 : key = '{' ; break;
|
|
case 40 : key = '[' ; break;
|
|
case 45 : key = '|' ; break;
|
|
case 232 : key = '`' ; break;
|
|
case 95 : key = 92 ; break;
|
|
case 231 : key = '^' ; break;
|
|
case 224 : key = '@' ; break;
|
|
case 41 : key = ']' ; break;
|
|
case 61 : key = '}' ; break;
|
|
#endif
|
|
#ifdef LAYOUT_FRENCH_BELGIAN
|
|
case 38 : key = '|' ; break; //1
|
|
case 233 : key = '@' ; break; //2
|
|
case 34 : key = '#' ; break; //3
|
|
case 167 : key = '^' ; break; //6
|
|
case 231 : key = '{' ; break; //9
|
|
case 224 : key = '}' ; break; //0
|
|
case 36 : key = ']' ; break; //$
|
|
case 61 : key = '~' ; break; //=
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if (menuActive())
|
|
{
|
|
switch (key)
|
|
{
|
|
case 217:
|
|
usbnavpad &= ~MASK_JOY2_DOWN;
|
|
break;
|
|
case 218:
|
|
usbnavpad &= ~MASK_JOY2_UP;
|
|
break;
|
|
case 216:
|
|
usbnavpad &= ~MASK_JOY2_LEFT;
|
|
break;
|
|
case 215:
|
|
usbnavpad &= ~MASK_JOY2_RIGHT;
|
|
break;
|
|
case 10:
|
|
usbnavpad &= ~MASK_JOY2_BTN;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
emu_KeyboardOnUp(keymodifier, key);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void emu_init(void)
|
|
{
|
|
Serial.begin(115200);
|
|
|
|
#ifdef HAS_USBKEY
|
|
myusb.begin();
|
|
keyboard1.attachPress(OnPress);
|
|
keyboard1.attachRelease(OnRelease);
|
|
#endif
|
|
|
|
#ifdef USE_SDFS
|
|
strcpy(romspath,SDFSDEV);
|
|
strcat(romspath,ROMSDIR);
|
|
FRESULT rc;
|
|
if((rc = f_mount (&fatfs, romspath, 1))) {
|
|
emu_printf("Fail mounting SDFS");
|
|
}
|
|
else {
|
|
rc = f_chdrive(ROMSDIR);
|
|
}
|
|
#else
|
|
#ifdef USE_SDFAT
|
|
while (!SD.begin(SD_CONFIG))
|
|
#else
|
|
while (!SD.begin(SD_CS))
|
|
#endif
|
|
{
|
|
Serial.println("SD begin failed, retrying...");
|
|
delay(1000);
|
|
}
|
|
strcpy(romspath,ROMSDIR);
|
|
#endif
|
|
|
|
nbFiles = readNbFiles();
|
|
|
|
Serial.print("SD initialized, files found: ");
|
|
Serial.println(nbFiles);
|
|
|
|
|
|
emu_InitJoysticks();
|
|
#ifdef SWAP_JOYSTICK
|
|
joySwapped = true;
|
|
#else
|
|
joySwapped = false;
|
|
#endif
|
|
readCallibration();
|
|
|
|
if ((tft.isTouching()) || (emu_ReadKeys() & MASK_JOY2_BTN) ) {
|
|
callibrationInit();
|
|
}
|
|
else
|
|
{
|
|
toggleMenu(true);
|
|
}
|
|
}
|
|
|
|
|
|
void emu_start(void)
|
|
{
|
|
#ifdef HAS_I2CKBD
|
|
byte msg[7]={0,0,0,0,0,0,0};
|
|
Wire.begin(); // join i2c bus SDA2/SCL2
|
|
Wire.requestFrom(8, 7); // request 7 bytes from slave device #8
|
|
int i = 0;
|
|
while (Wire.available() && (i<7) ) { // slave may send less than requested
|
|
byte b = Wire.read(); // receive a byte
|
|
msg[i++] = b;
|
|
}
|
|
/*
|
|
Serial.println(msg[0], BIN);
|
|
Serial.println(msg[1], BIN);
|
|
Serial.println(msg[2], BIN);
|
|
Serial.println(msg[3], BIN);
|
|
Serial.println(msg[4], BIN);
|
|
Serial.println(msg[5], BIN);
|
|
Serial.println(msg[6], BIN);
|
|
*/
|
|
if ( (msg[0] == 0xff) && (msg[1] == 0xff) &&
|
|
(msg[2] == 0xff) && (msg[3] == 0xff) &&
|
|
(msg[4] == 0xff) && (msg[5] == 0xff) && (msg[6] == 0xff)) {
|
|
i2cKeyboardPresent = true;
|
|
Serial.println("i2C keyboard found");
|
|
}
|
|
#endif
|
|
|
|
usbnavpad = 0;
|
|
|
|
keys = key_map1;
|
|
keyMap = 0;
|
|
}
|