Skip to content

Commit

Permalink
Implement Delete & Clone
Browse files Browse the repository at this point in the history
  • Loading branch information
keirf committed Jun 13, 2019
1 parent 01c955c commit 26e0497
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 12 deletions.
1 change: 1 addition & 0 deletions inc/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ typedef uint32_t time_t;
#define time_sysclk(x) stk_sysclk(x)
#define sysclk_time(x) sysclk_stk(x)

void delay_from(time_t t, unsigned int ticks);
time_t time_now(void);

#define time_diff(x,y) ((int32_t)((y)-(x))) /* d = y - x */
Expand Down
134 changes: 122 additions & 12 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1861,10 +1861,8 @@ static void noinline volume_space(void)

}

static uint8_t menu_wait_button(const char *led_msg)
static uint8_t menu_wait_button(bool_t twobutton_eject, const char *led_msg)
{
bool_t twobutton_eject =
(ff_cfg.twobutton_action & TWOBUTTON_mask) == TWOBUTTON_eject;
unsigned int wait = 0;
uint8_t b;

Expand Down Expand Up @@ -1937,7 +1935,7 @@ static uint8_t noinline display_error(FRESULT fres, uint8_t b)
continue;

/* Wait for any button to be pressed. */
b = menu_wait_button(msg);
b = menu_wait_button(twobutton_eject, msg);

while (b & B_SELECT) {
b = buttons;
Expand All @@ -1950,12 +1948,119 @@ static uint8_t noinline display_error(FRESULT fres, uint8_t b)
return b;
}

static void image_clone(void)
{
time_t t;
int i, baselen, todo, idx, max_idx = -1;
char *p, *q;
FIL *nfil;

strcpy(fs->buf, cfg.slot.name);
if ((p = q = strrchr(fs->buf, '_')) != NULL) {
for (i = 0; i < 3; i++) {
char c = *++p;
if ((c < '0') || (c > '9'))
break;
}
p = ((i == 3) && (p[1] == '\0')) ? q : NULL;
}

if (p == NULL)
p = fs->buf + strlen(fs->buf);

baselen = p - fs->buf;
snprintf(p, sizeof(fs->buf) - baselen, "_*.%s", cfg.slot.type);

for (F_findfirst(&fs->dp, &fs->fp, "", fs->buf);
fs->fp.fname[0] != '\0';
F_findnext(&fs->dp, &fs->fp)) {
p = fs->fp.fname + baselen + 1;
/* Parse 3-digit index number. */
idx = 0;
for (i = 0; i < 3; i++) {
if ((*p < '0') || (*p > '9'))
break;
idx *= 10;
idx += *p++ - '0';
}
/* Expect a 3-digit number. */
if ((i != 3) || (*p != '.'))
continue;
max_idx = max_t(int, max_idx, idx);
}
F_closedir(&fs->dp);

t = time_now();
if (max_idx >= 999) {
lcd_write(0, 1, -1, "No spare slots!");
goto out;
}

snprintf(fs->buf, sizeof(fs->buf), "Cloning To %03u", max_idx+1);
lcd_write(0, 1, -1, fs->buf);

volume_cache_destroy();
fatfs_from_slot(&fs->file, &cfg.slot, FA_READ);
nfil = arena_alloc(sizeof(*nfil));
strcpy(fs->buf, cfg.slot.name);
snprintf(fs->buf + baselen, sizeof(fs->buf) - baselen, "_%03u.%s",
max_idx+1, cfg.slot.type);
F_open(nfil, fs->buf, FA_CREATE_NEW|FA_WRITE);
todo = f_size(&fs->file);
while (todo != 0) {
int nr = min_t(int, todo, arena_avail());
void *p = arena_alloc(0);
F_read(&fs->file, p, nr, NULL);
F_write(nfil, p, nr, NULL);
todo -= nr;
}
F_close(nfil);
floppy_arena_setup();
if (!cfg.sorted)
cfg_update(CFG_READ_SLOT_NR);

out:
delay_from(t, time_ms(2000));
}

static bool_t image_delete(void)
{
FRESULT fres;
time_t t = time_now();
bool_t ok = FALSE;

if (cfg.hxc_mode) {
lcd_write(0, 1, -1, "Native Mode Only");
goto out;
}

lcd_write(0, 1, -1, "Deleting...");

snprintf(fs->buf, sizeof(fs->buf), "%s.%s",
cfg.slot.name, cfg.slot.type);
fres = f_unlink(fs->buf);
if (fres != FR_OK) {
snprintf(fs->buf, sizeof(fs->buf), "Failed (%d)", fres);
t = time_now();
}

cfg.slot_nr = min_t(uint16_t, cfg.slot_nr, cfg.max_slot_nr-1);
cfg.sorted = NULL;
cfg_update(CFG_READ_SLOT_NR);
ok = TRUE;

out:
delay_from(t, time_ms(2000));
return ok;
}

static uint8_t noinline eject_menu(uint8_t b)
{
const static char *menu[] = {
"**Eject Menu**",
NULL,
"Clone This Image",
"Clone Image",
"Delete Image",
"Exit to Selector",
"Exit & Re-Insert",
};
Expand All @@ -1964,7 +2069,8 @@ static uint8_t noinline eject_menu(uint8_t b)
unsigned int wait;
int sel = 0;
bool_t twobutton_eject =
(ff_cfg.twobutton_action & TWOBUTTON_mask) == TWOBUTTON_eject;
((ff_cfg.twobutton_action & TWOBUTTON_mask) == TWOBUTTON_eject)
|| (display_mode == DM_LCD_OLED); /* or two buttons can't exit menu */

ima_mark_ejected(TRUE);

Expand Down Expand Up @@ -2013,7 +2119,7 @@ static uint8_t noinline eject_menu(uint8_t b)
}

/* Wait for any button to be pressed. */
b = menu_wait_button("EJE");
b = menu_wait_button(twobutton_eject, "EJE");

if (b & B_LEFT)
sel--;
Expand Down Expand Up @@ -2048,14 +2154,18 @@ static uint8_t noinline eject_menu(uint8_t b)
}
break;
case 2: /* Clone Image */
lcd_write(0, 1, -1, "To Be Implemented");
delay_ms(2000);
image_clone();
break;
case 3: /* Exit & Select */
case 3: /* Delete Image */
if (!image_delete())
break;
b = 0xff; /* selector */
goto out;
case 4: /* Exit & Select */
display_write_slot(TRUE);
b = 0xff;
b = 0xff; /* selector */
goto out;
case 0: case 4: /* Exit & Re-Insert */
case 0: case 5: /* Exit & Re-Insert */
b = 0;
goto out;
}
Expand Down
7 changes: 7 additions & 0 deletions src/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
static volatile time_t time_stamp;
static struct timer time_stamp_timer;

void delay_from(time_t t, unsigned int ticks)
{
int diff = time_diff(time_now(), t + ticks);
if (diff > 0)
delay_ticks(diff);
}

static void time_stamp_update(void *unused)
{
time_t now = time_now();
Expand Down

0 comments on commit 26e0497

Please sign in to comment.