1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-25 17:25:13 +03:00

Merge pull request #2036 from opentx/bsongis/issue1924_file_copy_rename_in_sdmanager

Bsongis/issue1924 file copy rename in sdmanager
This commit is contained in:
Bertrand Songis 2015-01-22 22:41:45 +01:00
commit 90e7264a40
14 changed files with 252 additions and 109 deletions

View file

@ -36,6 +36,8 @@
#include "../../opentx.h"
#define REFRESH_FILES() reusableBuffer.sdmanager.offset = 65535
void menuGeneralSdManagerInfo(uint8_t event)
{
SIMPLE_SUBMENU(STR_SD_INFO_TITLE, 1);
@ -116,60 +118,85 @@ void onSdManagerMenu(const char *result)
{
TCHAR lfn[_MAX_LFN+1];
// TODO possible buffer overflows here!
uint8_t index = m_posVert-1-s_pgOfs;
char *line = reusableBuffer.sdmanager.lines[index];
if (result == STR_SD_INFO) {
pushMenu(menuGeneralSdManagerInfo);
}
else if (result == STR_SD_FORMAT) {
POPUP_CONFIRMATION(STR_CONFIRM_FORMAT);
}
else if (result == STR_COPY_FILE) {
clipboard.type = CLIPBOARD_TYPE_SD_FILE;
f_getcwd(clipboard.data.sd.directory, CLIPBOARD_PATH_LEN);
strncpy(clipboard.data.sd.filename, line, CLIPBOARD_PATH_LEN-1);
}
else if (result == STR_PASTE) {
f_getcwd(lfn, _MAX_LFN);
POPUP_WARNING(fileCopy(clipboard.data.sd.filename, clipboard.data.sd.directory, lfn));
REFRESH_FILES();
}
else if (result == STR_RENAME_FILE) {
char *ext = getFileExtension(line, SD_SCREEN_FILE_LENGTH+1);
if (ext) {
memcpy(reusableBuffer.sdmanager.originalName, line, sizeof(reusableBuffer.sdmanager.originalName));
// write spaces to allow a longer filename
memset(ext, ' ', SD_SCREEN_FILE_LENGTH-LEN_FILE_EXTENSION-(ext-line));
line[SD_SCREEN_FILE_LENGTH-LEN_FILE_EXTENSION] = '\0';
s_editMode = EDIT_MODIFY_STRING;
editNameCursorPos = 0;
}
}
else if (result == STR_DELETE_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat_P(lfn, PSTR("/"));
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
strcat(lfn, PSTR("/"));
strcat(lfn, line);
f_unlink(lfn);
strncpy(statusLineMsg, reusableBuffer.sdmanager.lines[index], 13);
strncpy(statusLineMsg, line, 13);
strcpy_P(statusLineMsg+min((uint8_t)strlen(statusLineMsg), (uint8_t)13), STR_REMOVED);
showStatusLine();
if ((uint16_t)m_posVert == reusableBuffer.sdmanager.count) m_posVert--;
reusableBuffer.sdmanager.offset = s_pgOfs-1;
REFRESH_FILES();
if (m_posVert == reusableBuffer.sdmanager.count)
m_posVert--;
}
/* TODO else if (result == STR_LOAD_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
strcat(lfn, line);
POPUP_WARNING(eeLoadModelSD(lfn));
} */
else if (result == STR_PLAY_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
strcat(lfn, line);
audioQueue.stopAll();
audioQueue.playFile(lfn, 0, ID_PLAY_FROM_SD_MANAGER);
}
else if (result == STR_ASSIGN_BITMAP) {
strAppendFilename(g_model.header.bitmap, reusableBuffer.sdmanager.lines[index], sizeof(g_model.header.bitmap));
LOAD_MODEL_BITMAP();
strAppendFilename(g_model.header.bitmap, line, sizeof(g_model.header.bitmap));
memcpy(modelHeaders[g_eeGeneral.currModel].bitmap, g_model.header.bitmap, sizeof(g_model.header.bitmap));
eeDirty(EE_MODEL);
}
else if (result == STR_VIEW_TEXT) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
strcat(lfn, line);
pushMenuTextView(lfn);
}
else if (result == STR_FLASH_BOOTLOADER) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
strcat(lfn, line);
flashBootloader(lfn);
}
#if defined(LUA)
else if (result == STR_EXECUTE_FILE) {
f_getcwd(lfn, _MAX_LFN);
strcat(lfn, "/");
strcat(lfn, reusableBuffer.sdmanager.lines[index]);
strcat(lfn, line);
luaExec(lfn);
}
#endif
@ -191,27 +218,28 @@ void menuGeneralSdManager(uint8_t _event)
audioQueue.stopSD();
if (f_mkfs(0, 1, 0) == FR_OK) {
f_chdir("/");
reusableBuffer.sdmanager.offset = -1;
REFRESH_FILES();
}
else {
POPUP_WARNING(STR_SDCARD_ERROR);
}
}
uint8_t event = ((READ_ONLY() && EVT_KEY_MASK(_event) == KEY_ENTER) ? 0 : _event);
int lastPos = m_posVert;
uint8_t event = (EVT_KEY_MASK(_event) == KEY_ENTER ? 0 : _event);
SIMPLE_MENU(SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD, menuTabGeneral, e_Sd, 1+reusableBuffer.sdmanager.count);
if (s_editMode > 0)
s_editMode = 0;
int index = m_posVert-1-s_pgOfs;
switch(_event) {
case EVT_ENTRY:
f_chdir(ROOT_PATH);
reusableBuffer.sdmanager.offset = 65535;
REFRESH_FILES();
break;
case EVT_KEY_LONG(KEY_MENU):
if (!READ_ONLY()) {
if (!READ_ONLY() && s_editMode == 0) {
killEvents(_event);
// MENU_ADD_ITEM(STR_SD_INFO); TODO: Implement
MENU_ADD_ITEM(STR_SD_FORMAT);
@ -219,32 +247,35 @@ void menuGeneralSdManager(uint8_t _event)
}
break;
case EVT_KEY_BREAK(KEY_EXIT):
REFRESH_FILES();
break;
case EVT_KEY_BREAK(KEY_ENTER):
{
if (m_posVert > 0) {
vertpos_t index = m_posVert-1-s_pgOfs;
if (!reusableBuffer.sdmanager.lines[index][SD_SCREEN_FILE_LENGTH+1]) {
f_chdir(reusableBuffer.sdmanager.lines[index]);
s_pgOfs = 0;
m_posVert = 1;
reusableBuffer.sdmanager.offset = 65535;
killEvents(_event);
break;
if (s_editMode > 0) {
break;
}
else {
if (m_posVert > 0) {
if (!reusableBuffer.sdmanager.lines[index][SD_SCREEN_FILE_LENGTH+1]) {
f_chdir(reusableBuffer.sdmanager.lines[index]);
s_pgOfs = 0;
m_posVert = 1;
index = 1;
REFRESH_FILES();
killEvents(_event);
return;
}
}
}
if (!IS_ROTARY_BREAK(_event) || m_posVert==0)
break;
// no break;
}
// no break
case EVT_KEY_LONG(KEY_ENTER):
killEvents(_event);
{
uint8_t index = m_posVert-1-s_pgOfs;
// TODO duplicated code for finding extension
char * ext = reusableBuffer.sdmanager.lines[index];
int len = strlen(ext) - 4;
ext += len;
if (s_editMode == 0) {
char *line = reusableBuffer.sdmanager.lines[index];
char *ext = getFileExtension(line, SD_SCREEN_FILE_LENGTH+1);
int len = ext - line;
/* TODO if (!strcasecmp(ext, MODELS_EXT)) {
s_menu[s_menu_count++] = STR_LOAD_FILE;
}
@ -266,9 +297,12 @@ void menuGeneralSdManager(uint8_t _event)
}
#endif
if (!READ_ONLY()) {
if (line[SD_SCREEN_FILE_LENGTH+1]) // it's a file
MENU_ADD_ITEM(STR_COPY_FILE);
if (clipboard.type == CLIPBOARD_TYPE_SD_FILE)
MENU_ADD_ITEM(STR_PASTE);
MENU_ADD_ITEM(STR_RENAME_FILE);
MENU_ADD_ITEM(STR_DELETE_FILE);
// MENU_ADD_ITEM(STR_RENAME_FILE); TODO: Implement
// MENU_ADD_ITEM(STR_COPY_FILE); TODO: Implement
}
}
menuHandler = onSdManagerMenu;
@ -360,29 +394,32 @@ void menuGeneralSdManager(uint8_t _event)
for (uint8_t i=0; i<LCD_LINES-1; i++) {
coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH;
lcdNextPos = 0;
uint8_t attr = (m_posVert-1-s_pgOfs == i ? BSS|INVERS : BSS);
uint8_t attr = (index == i ? BSS|INVERS : BSS);
if (reusableBuffer.sdmanager.lines[i][0]) {
if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(0, y, '[', attr); }
lcd_putsAtt(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], attr);
if (s_editMode == EDIT_MODIFY_STRING && attr) {
editName(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH-4, _event, attr, 0);
if (s_editMode == 0) {
unsigned int len = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH-LEN_FILE_EXTENSION);
strAppend(&reusableBuffer.sdmanager.lines[i][len], getFileExtension(reusableBuffer.sdmanager.originalName, sizeof(reusableBuffer.sdmanager.originalName)));
f_rename(reusableBuffer.sdmanager.originalName, reusableBuffer.sdmanager.lines[i]);
REFRESH_FILES();
}
}
else {
lcd_putsAtt(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], attr);
}
if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(lcdNextPos, y, ']', attr); }
}
}
static vertpos_t sdBitmapIdx = 0xFFFF;
static uint8_t sdBitmap[MODEL_BITMAP_SIZE];
vertpos_t index = m_posVert-1-s_pgOfs;
if (m_posVert > 0) {
char * ext = reusableBuffer.sdmanager.lines[index];
ext += strlen(ext) - 4;
if (!strcasecmp(ext, BITMAPS_EXT)) {
if (sdBitmapIdx != m_posVert) {
sdBitmapIdx = m_posVert;
uint8_t *dest = sdBitmap;
if (bmpLoad(dest, reusableBuffer.sdmanager.lines[index], MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)) {
memcpy(sdBitmap, logo_taranis, MODEL_BITMAP_SIZE);
}
char *ext = getFileExtension(reusableBuffer.sdmanager.lines[index], SD_SCREEN_FILE_LENGTH+1);
if (ext && !strcasecmp(ext, BITMAPS_EXT)) {
if (lastPos != m_posVert) {
if (bmpLoad(modelBitmap, reusableBuffer.sdmanager.lines[index], MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)) {
memcpy(modelBitmap, logo_taranis, MODEL_BITMAP_SIZE);
}
lcd_bmp(22*FW+2, 2*FH+FH/2, sdBitmap);
}
lcd_bmp(22*FW+2, 2*FH+FH/2, modelBitmap);
}
}

View file

@ -138,7 +138,7 @@ static int8_t s_copyTgtOfs;
static uint8_t editNameCursorPos = 0;
void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active)
void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active, uint8_t attr)
{
uint8_t mode = 0;
if (active) {
@ -148,7 +148,7 @@ void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uin
mode = FIXEDWIDTH;
}
lcd_putsnAtt(x, y, name, size, ZCHAR | mode);
lcd_putsnAtt(x, y, name, size, attr | mode);
if (active) {
uint8_t cur = editNameCursorPos;
@ -158,8 +158,14 @@ void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uin
if (IS_ROTARY_RIGHT(event) || IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_FIRST(KEY_UP)
|| event==EVT_KEY_REPT(KEY_DOWN) || event==EVT_KEY_REPT(KEY_UP)) {
v = checkIncDec(event, abs(v), 0, ZCHAR_MAX, 0);
if (c <= 0) v = -v;
if (attr == ZCHAR) {
v = checkIncDec(event, abs(v), 0, ZCHAR_MAX, 0);
if (c <= 0) v = -v;
}
else {
v = checkIncDec(event, abs(v), '0', 'z', 0);
}
}
switch (event) {
@ -175,7 +181,7 @@ void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uin
break;
case EVT_ROTARY_LONG:
if (v==0) {
if ((attr == ZCHAR && v==0) || (attr == 0 && v==' ')) {
s_editMode = 0;
killEvents(event);
break;
@ -193,7 +199,12 @@ void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uin
eeDirty(g_menuPos[0] == 0 ? EE_MODEL : EE_GENERAL);
}
lcd_putcAtt(x+editNameCursorPos*FW, y, idx2char(v), ERASEBG|INVERS|FIXEDWIDTH);
if (attr == ZCHAR) {
lcd_putcAtt(x+editNameCursorPos*FW, y, idx2char(v), ERASEBG|INVERS|FIXEDWIDTH);
}
else {
lcd_putcAtt(x+editNameCursorPos*FW, y, v, ERASEBG|INVERS|FIXEDWIDTH);
}
}
else {
cur = 0;

View file

@ -73,22 +73,6 @@ void putsEdgeDelayParam(coord_t x, coord_t y, LogicalSwitchData *cs, uint8_t lat
lcd_putc(lcdLastPos, y, ']');
}
enum ClipboardType {
CLIPBOARD_TYPE_NONE,
CLIPBOARD_TYPE_CUSTOM_SWITCH,
CLIPBOARD_TYPE_CUSTOM_FUNCTION,
};
struct Clipboard {
ClipboardType type;
union {
LogicalSwitchData csw;
CustomFunctionData cfn;
} data;
};
Clipboard clipboard;
void onLogicalSwitchesMenu(const char *result)
{
int8_t sub = m_posVert-1;

View file

@ -37,10 +37,7 @@
#define MODELSIZE_POS_X 170
static int8_t modelselBitmapIdx;
static uint8_t modelselBitmap[MODEL_BITMAP_SIZE];
#define MODELSEL_W 133
#define BMP_DIRTY() modelselBitmapIdx = -1
void onModelSelectMenu(const char *result)
{
@ -76,7 +73,6 @@ void onModelSelectMenu(const char *result)
else {
// The user choosed a file on SD to restore
POPUP_WARNING(eeRestoreModel(sub, (char *)result));
BMP_DIRTY();
if (!s_warning && g_eeGeneral.currModel == sub)
eeLoadModel(sub);
}
@ -89,7 +85,6 @@ void menuModelSelect(uint8_t event)
eeDeleteModel(m_posVert); // delete file
s_copyMode = 0;
event = EVT_ENTRY_UP;
BMP_DIRTY();
}
uint8_t _event_ = (IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event) ? 0 : event);
@ -112,9 +107,9 @@ void menuModelSelect(uint8_t event)
if (sub >= NUM_BODY_LINES) s_pgOfs = sub-(NUM_BODY_LINES-1);
s_copyMode = 0;
s_editMode = EDIT_MODE_INIT;
BMP_DIRTY();
eeCheck(true);
break;
case EVT_KEY_LONG(KEY_EXIT):
if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && eeModelExists(sub)) {
POPUP_CONFIRMATION(STR_DELETEMODEL);
@ -130,7 +125,7 @@ void menuModelSelect(uint8_t event)
}
else {
if (m_posVert != g_eeGeneral.currModel) {
m_posVert = g_eeGeneral.currModel;
sub = m_posVert = g_eeGeneral.currModel;
s_pgOfs = 0;
}
else if (event != EVT_KEY_LONG(KEY_EXIT)) {
@ -153,9 +148,7 @@ void menuModelSelect(uint8_t event)
uint8_t cur = (MAX_MODELS + sub + s_copyTgtOfs) % MAX_MODELS;
if (s_copyMode == COPY_MODE) {
if (eeCopyModel(cur, s_copySrcRow))
BMP_DIRTY();
else
if (!eeCopyModel(cur, s_copySrcRow))
cur = sub;
}
@ -164,7 +157,6 @@ void menuModelSelect(uint8_t event)
uint8_t src = cur;
cur = (s_copyTgtOfs > 0 ? cur+MAX_MODELS-1 : cur+1) % MAX_MODELS;
eeSwapModels(src, cur);
BMP_DIRTY();
if (src == s_copySrcRow)
s_copySrcRow = cur;
else if (cur == s_copySrcRow)
@ -289,12 +281,9 @@ void menuModelSelect(uint8_t event)
}
}
if (modelselBitmapIdx != m_posVert) {
modelselBitmapIdx = m_posVert;
if (modelselBitmapIdx == g_eeGeneral.currModel)
memcpy(modelselBitmap, modelBitmap, MODEL_BITMAP_SIZE);
else
loadModelBitmap(modelHeaders[sub].bitmap, modelselBitmap);
if (event == EVT_ENTRY || sub != oldSub) {
loadModelBitmap(modelHeaders[sub].bitmap, modelBitmap);
}
lcd_bmp(22*FW+2, 2*FH+FH/2, modelselBitmap);
lcd_bmp(22*FW+2, 2*FH+FH/2, modelBitmap);
}

View file

@ -115,7 +115,6 @@ void onModelSetupBitmapMenu(const char *result)
else {
// The user choosed a bmp file in the list
copySelection(g_model.header.bitmap, result, sizeof(g_model.header.bitmap));
LOAD_MODEL_BITMAP();
memcpy(modelHeaders[g_eeGeneral.currModel].bitmap, g_model.header.bitmap, sizeof(g_model.header.bitmap));
eeDirty(EE_MODEL);
}

View file

@ -290,7 +290,7 @@ int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, uint8_t
#define displayGVar(x, y, v, min, max) lcd_outdez8(x, y, v)
#endif
void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active);
void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active, uint8_t attr=ZCHAR);
#define WARNING_TYPE_ASTERISK 0
#define WARNING_TYPE_CONFIRM 1

View file

@ -441,6 +441,10 @@ void menuMainView(uint8_t event)
killEvents(KEY_EXIT);
killEvents(KEY_UP);
killEvents(KEY_DOWN);
// no break
case EVT_ENTRY_UP:
LOAD_MODEL_BITMAP();
break;
case EVT_KEY_CONTEXT_MENU:

View file

@ -50,6 +50,10 @@
EEGeneral g_eeGeneral;
ModelData g_model;
#if defined(SDCARD)
Clipboard clipboard;
#endif
#if defined(PCBTARANIS) && defined(SDCARD)
uint8_t modelBitmap[MODEL_BITMAP_SIZE];
void loadModelBitmap(char *name, uint8_t *bitmap)

View file

@ -1513,6 +1513,7 @@ extern uint8_t requiredSpeakerVolume;
#define SD_SCREEN_FILE_LENGTH (32)
union ReusableBuffer
{
// 275 bytes
struct
{
char listnames[LCD_LINES-1][LEN_MODEL_NAME];
@ -1526,6 +1527,7 @@ union ReusableBuffer
} modelsel;
// 103 bytes
struct
{
int16_t midVals[NUM_STICKS+NUM_POTS];
@ -1543,12 +1545,14 @@ union ReusableBuffer
} calib;
#if defined(SDCARD)
// 274 bytes
struct
{
char lines[LCD_LINES-1][SD_SCREEN_FILE_LENGTH+1+1]; // the last char is used to store the flags (directory) of the line
uint32_t available;
uint16_t offset;
uint16_t count;
char originalName[SD_SCREEN_FILE_LENGTH+1];
} sdmanager;
#endif
};
@ -1721,4 +1725,33 @@ void varioWakeup();
#include "lua_api.h"
#if defined(SDCARD)
enum ClipboardType {
CLIPBOARD_TYPE_NONE,
CLIPBOARD_TYPE_CUSTOM_SWITCH,
CLIPBOARD_TYPE_CUSTOM_FUNCTION,
CLIPBOARD_TYPE_SD_FILE,
};
#if defined(SIMU)
#define CLIPBOARD_PATH_LEN 1024
#else
#define CLIPBOARD_PATH_LEN 32
#endif
struct Clipboard {
ClipboardType type;
union {
LogicalSwitchData csw;
CustomFunctionData cfn;
struct {
char directory[CLIPBOARD_PATH_LEN];
char filename[CLIPBOARD_PATH_LEN];
} sd;
} data;
};
extern Clipboard clipboard;
#endif
#endif

View file

@ -141,3 +141,48 @@ bool listSdFiles(const char *path, const char *extension, const uint8_t maxlen,
return s_menu_count;
}
const char *fileCopy(const char *filename, const char *srcDir, const char *destDir)
{
FIL srcFile;
FIL dstFile;
char buf[256];
UINT read = sizeof(buf);
UINT written = sizeof(buf);
char path[2*CLIPBOARD_PATH_LEN+1];
char *tmp = strAppend(path, srcDir, CLIPBOARD_PATH_LEN);
*tmp++ = '/';
strAppend(tmp, filename, CLIPBOARD_PATH_LEN);
FRESULT result = f_open(&srcFile, path, FA_OPEN_EXISTING | FA_READ);
if (result != FR_OK) {
return SDCARD_ERROR(result);
}
tmp = strAppend(path, destDir, CLIPBOARD_PATH_LEN);
*tmp++ = '/';
strAppend(tmp, filename, CLIPBOARD_PATH_LEN);
result = f_open(&dstFile, path, FA_CREATE_ALWAYS | FA_WRITE);
if (result != FR_OK) {
f_close(&srcFile);
return SDCARD_ERROR(result);
}
while (result==FR_OK && read==sizeof(buf) && written==sizeof(buf)) {
result = f_read(&srcFile, buf, sizeof(buf), &read);
if (result == FR_OK) {
result = f_write(&dstFile, buf, read, &written);
}
}
f_close(&dstFile);
f_close(&srcFile);
if (result != FR_OK) {
return SDCARD_ERROR(result);
}
return NULL;
}

View file

@ -34,8 +34,8 @@
*
*/
#ifndef sdcard_h
#define sdcard_h
#ifndef _SDCARD_H_
#define _SDCARD_H_
#include "FatFs/ff.h"
@ -68,10 +68,10 @@
extern FATFS g_FATFS_Obj;
extern uint8_t logDelay;
extern const pm_char * openLogs();
const pm_char *openLogs();
void writeHeader();
extern void closeLogs();
extern void writeLogs();
void closeLogs();
void writeLogs();
#if !defined(BOOT)
inline const pm_char *SDCARD_ERROR(FRESULT result)
@ -91,5 +91,7 @@ inline const pm_char *SDCARD_ERROR(FRESULT result)
#define O9X_FOURCC 0x3178396F // o9x for gruvin9x/MEGA2560
#endif
const char *fileCopy(const char *filename, const char *srcDir, const char *destDir);
#endif

View file

@ -97,6 +97,16 @@ int zchar2str(char *dest, const char *src, int size)
#endif
#if defined(CPUARM)
unsigned int effectiveLen(const char *str, unsigned int size)
{
while (size > 0) {
if (str[size-1] != ' ')
return size;
size--;
}
return 0;
}
bool zexist(const char *str, uint8_t size)
{
for (int i=0; i<size; i++) {
@ -113,7 +123,7 @@ uint8_t zlen(const char *str, uint8_t size)
return size;
size--;
}
return size;
return 0;
}
char *strcat_zchar(char * dest, const char * name, uint8_t size, const char *defaultName, uint8_t defaultNameSize, uint8_t defaultIdx)
@ -167,7 +177,8 @@ char *strAppend(char *dest, const char *source, int len)
{
while ((*dest++ = *source++)) {
if (--len == 0) {
*dest++ = '\0';
*dest = '\0';
return dest;
}
}
return dest - 1;
@ -181,7 +192,7 @@ char *strSetCursor(char *dest, int position)
return dest;
}
char * strAppendFilename(char * dest, const char * filename, const int size)
char *strAppendFilename(char *dest, const char *filename, const int size)
{
memset(dest, 0, size);
for (int i=0; i<size; i++) {
@ -193,6 +204,21 @@ char * strAppendFilename(char * dest, const char * filename, const int size)
return dest;
}
#define LEN_FILE_EXTENSION 4
char *getFileExtension(char *filename, int size)
{
for (int i=0; i<size-LEN_FILE_EXTENSION; ++i) {
if (filename[i] == '.') {
for (int j=i+1; j<size; ++j) {
if (filename[j] == '\0') {
return &filename[i];
}
}
}
}
return NULL;
}
#if defined(RTCLOCK)
#include "rtc.h"

View file

@ -552,7 +552,10 @@ FRESULT f_read (FIL* fil, void* data, UINT size, UINT* read)
FRESULT f_write (FIL* fil, const void* data, UINT size, UINT* written)
{
if (fil && fil->fs) *written = fwrite(data, 1, size, (FILE*)fil->fs);
if (fil && fil->fs) {
*written = fwrite(data, 1, size, (FILE*)fil->fs);
// TRACE("fwrite(%p) %u, %u", fil->fs, size, *written);
}
return FR_OK;
}
@ -637,6 +640,11 @@ FRESULT f_unlink (const TCHAR*)
return FR_OK;
}
FRESULT f_rename(const TCHAR*, const TCHAR*)
{
return FR_OK;
}
int f_putc (TCHAR c, FIL * fil)
{
if (fil && fil->fs) fwrite(&c, 1, 1, (FILE*)fil->fs);

View file

@ -37,9 +37,10 @@ def createFontBitmap(filename, foreground, background):
if i == 0:
rect.setWidth(4)
elif i == 14:
rect.setLeft(rect.left()+1)
rect.setWidth(1)
painter.drawText(width*i-rect.left(), size+1, c)
painter.drawPoint(width*i, size);
else:
painter.drawText(width*i-rect.left(), size+1, c)
for j in range(rect.width(), width):
painter.drawLine(width*i+j, 0, width*i+j, size+4)
painter.end()