Subversion Repositories svn.mios32

Rev

Rev 1635 | Rev 1866 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
272 tk 1
// $Id: seq_ui_menu.c 1794 2013-05-31 19:25:43Z tk $
2
/*
3
 * Menu page (visible when EXIT button is pressed)
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
8
 *  Licensed for personal non-commercial use only.
9
 *  All other rights reserved.
10
 *
11
 * ==========================================================================
12
 */
13
 
14
/////////////////////////////////////////////////////////////////////////////
15
// Include files
16
/////////////////////////////////////////////////////////////////////////////
17
 
18
#include <mios32.h>
747 tk 19
#include <string.h>
272 tk 20
#include <seq_midi_out.h>
1117 tk 21
#include <seq_bpm.h>
318 tk 22
#include "tasks.h"
272 tk 23
 
1635 tk 24
#include <file.h>
25
#include <ff.h>
26
 
1261 tk 27
#include "seq_file.h"
28
 
272 tk 29
#include "seq_lcd.h"
30
#include "seq_ui.h"
1083 tk 31
#include "seq_cv.h"
32
#include "seq_midi_in.h"
1117 tk 33
#include "seq_core.h"
34
#include "seq_song.h"
35
#include "seq_midply.h"
36
#include "seq_groove.h"
37
#include "seq_mixer.h"
272 tk 38
 
39
 
286 tk 40
/////////////////////////////////////////////////////////////////////////////
747 tk 41
// Local definitions
42
/////////////////////////////////////////////////////////////////////////////
43
 
44
#define ITEM_LIST1             0
45
#define ITEM_LIST2             1
959 tk 46
#define ITEM_OPEN              2
47
#define ITEM_SAVE              3
48
#define ITEM_SAVE_AS           4
49
#define ITEM_NEW               5
1635 tk 50
#define ITEM_DELETE            6
51
#define ITEM_INFO              7
747 tk 52
 
53
 
54
 
959 tk 55
// Session
56
#define MENU_DIALOG_NONE          0
57
#define MENU_DIALOG_OPEN          1
58
#define MENU_DIALOG_SAVE_AS       2
59
#define MENU_DIALOG_SAVE_DEXISTS  3
60
#define MENU_DIALOG_NEW           4
61
#define MENU_DIALOG_NEW_DEXISTS   5
1635 tk 62
#define MENU_DIALOG_DELETE        6
63
#define MENU_DIALOG_DELETE_CONFIRM 7
959 tk 64
 
65
#define MENU_NUM_LIST_DISPLAYED_ITEMS 2
66
#define MENU_LIST_ENTRY_WIDTH 19
67
 
68
#define SESSION_NUM_LIST_DISPLAYED_ITEMS 4
69
#define SESSION_LIST_ENTRY_WIDTH 9
70
 
71
 
747 tk 72
/////////////////////////////////////////////////////////////////////////////
286 tk 73
// Local variables
74
/////////////////////////////////////////////////////////////////////////////
272 tk 75
 
746 tk 76
static u8 menu_view_offset = 0; // only changed once after startup or if menu page outside view
77
static u8 menu_selected_item = 0; // dito
286 tk 78
 
959 tk 79
static u8 menu_dialog;
746 tk 80
 
1261 tk 81
static s32 dir_num_items; // contains FILE error status if < 0
959 tk 82
static u8 dir_view_offset = 0; // only changed once after startup
83
static char dir_name[12]; // directory name of device (first char is 0 if no device selected)
84
 
272 tk 85
/////////////////////////////////////////////////////////////////////////////
746 tk 86
// Local prototypes
87
/////////////////////////////////////////////////////////////////////////////
88
 
89
static s32 SEQ_UI_MENU_UpdatePageList(void);
959 tk 90
static s32 SEQ_UI_MENU_UpdateSessionList(void);
91
static s32 DoSessionSave(u8 force_overwrite);
92
static s32 DoSessionNew(u8 force_overwrite);
1635 tk 93
static s32 DoSessionDelete(u8 check_only);
959 tk 94
static s32 OpenSession(void);
746 tk 95
 
96
/////////////////////////////////////////////////////////////////////////////
272 tk 97
// Local LED handler function
98
/////////////////////////////////////////////////////////////////////////////
99
static s32 LED_Handler(u16 *gp_leds)
100
{
959 tk 101
  *gp_leds = 0x0000;
749 tk 102
 
959 tk 103
  switch( menu_dialog ) {
104
  case MENU_DIALOG_NONE:
105
    if( ui_cursor_flash ) // if flashing flag active: no LED flag set
106
      return 0;
107
    if( menu_selected_item <= ITEM_LIST2 )
108
      *gp_leds = (15 << (4*menu_selected_item));
109
    break;
746 tk 110
 
959 tk 111
  case MENU_DIALOG_OPEN:
1635 tk 112
  case MENU_DIALOG_DELETE:
959 tk 113
    *gp_leds = (3 << (2*ui_selected_item));
114
    break;
115
 
116
  case MENU_DIALOG_SAVE_AS:
117
  case MENU_DIALOG_SAVE_DEXISTS:
118
  case MENU_DIALOG_NEW:
119
  case MENU_DIALOG_NEW_DEXISTS:
1635 tk 120
  case MENU_DIALOG_DELETE_CONFIRM:
959 tk 121
    // no LED functions yet
122
    break;
123
  }
124
 
125
 
272 tk 126
  return 0; // no error
127
}
128
 
129
 
130
/////////////////////////////////////////////////////////////////////////////
131
// Local encoder callback function
132
// Should return:
133
//   1 if value has been changed
134
//   0 if value hasn't been changed
135
//  -1 if invalid or unsupported encoder
136
/////////////////////////////////////////////////////////////////////////////
137
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
138
{
959 tk 139
  switch( menu_dialog ) {
140
  case MENU_DIALOG_NONE:
141
    // datawheel and GP1-8 change the menu view
142
    if( encoder <= SEQ_UI_ENCODER_GP8 || encoder == SEQ_UI_ENCODER_Datawheel ) {
143
      if( SEQ_UI_SelectListItem(incrementer, SEQ_UI_NUM_MENU_PAGES, MENU_NUM_LIST_DISPLAYED_ITEMS, &menu_selected_item, &menu_view_offset) )
144
    SEQ_UI_MENU_UpdatePageList();
272 tk 145
 
959 tk 146
      return 1;      
147
    }
148
 
149
    // (GP9..GP16 ignored)
150
    break;
151
 
152
 
153
  ///////////////////////////////////////////////////////////////////////////
154
  case MENU_DIALOG_OPEN:
155
    switch( encoder ) {
156
    case SEQ_UI_ENCODER_GP9:
157
    case SEQ_UI_ENCODER_GP10:
158
    case SEQ_UI_ENCODER_GP11:
159
    case SEQ_UI_ENCODER_GP12:
160
    case SEQ_UI_ENCODER_GP13:
161
    case SEQ_UI_ENCODER_GP14:
162
    case SEQ_UI_ENCODER_GP15:
163
      return -1; // not mapped
164
 
165
    case SEQ_UI_ENCODER_GP16:
166
      // EXIT only via button
167
      if( incrementer == 0 ) {
168
    SEQ_UI_MENU_UpdatePageList();
169
    menu_dialog = MENU_DIALOG_NONE;
170
      }
171
      return 1;
172
 
173
    default:
174
      if( SEQ_UI_SelectListItem(incrementer, dir_num_items, SESSION_NUM_LIST_DISPLAYED_ITEMS, &ui_selected_item, &dir_view_offset) )
175
    SEQ_UI_MENU_UpdateSessionList();
176
    }
177
    break;
178
 
179
 
180
  ///////////////////////////////////////////////////////////////////////////
181
  case MENU_DIALOG_SAVE_AS: {
182
    switch( encoder ) {
183
    case SEQ_UI_ENCODER_GP15: {
184
      // SAVE only via button
185
      if( incrementer != 0 )
186
    return 0;
187
 
188
      if( DoSessionSave(0) == 0 ) { // don't force overwrite
189
    // exit keypad editor
190
    SEQ_UI_MENU_UpdatePageList();
191
    menu_dialog = MENU_DIALOG_NONE;
192
      }
193
 
194
      return 1;
195
    } break;
196
 
197
    case SEQ_UI_ENCODER_GP16: {
198
      // EXIT only via button
199
      if( incrementer == 0 ) {
200
    SEQ_UI_MENU_UpdatePageList();
201
    menu_dialog = MENU_DIALOG_NONE;
202
      }
203
      return 1;
204
    } break;
205
    }
206
 
207
    return SEQ_UI_KeyPad_Handler(encoder, incrementer, (char *)&dir_name[0], 8);
208
  }
209
 
210
 
211
  ///////////////////////////////////////////////////////////////////////////
1635 tk 212
  case MENU_DIALOG_SAVE_DEXISTS: {
213
    switch( encoder ) {
214
    case SEQ_UI_ENCODER_GP11: {
215
      // YES only via button
216
      if( incrementer != 0 )
217
    return 0;
218
 
219
      // YES: overwrite session
220
      if( DoSessionSave(1) == 0 ) { // force overwrite
221
    // exit keypad editor
222
    SEQ_UI_MENU_UpdatePageList();
223
    menu_dialog = MENU_DIALOG_NONE;
224
      }
225
      return 1;
226
    } break;
227
 
228
    case SEQ_UI_ENCODER_GP12: {
229
      // NO only via button
230
      if( incrementer != 0 )
231
    return 0;
232
 
233
      // NO: don't overwrite session - back to dirname entry
234
 
235
      ui_selected_item = 0;
236
      menu_dialog = MENU_DIALOG_SAVE_AS;
237
      return 1;
238
    } break;
239
 
240
    case SEQ_UI_ENCODER_GP16: {
241
      // EXIT only via button
242
      if( incrementer == 0 ) {
243
    SEQ_UI_MENU_UpdatePageList();
244
    menu_dialog = MENU_DIALOG_NONE;
245
      }
246
      return 1;
247
    } break;
248
    }
249
 
250
    return -1; // not mapped
251
  }
252
 
253
 
254
  ///////////////////////////////////////////////////////////////////////////
959 tk 255
  case MENU_DIALOG_NEW: {
256
    switch( encoder ) {
257
    case SEQ_UI_ENCODER_GP15: {
258
      // NEW only via button
259
      if( incrementer != 0 )
260
    return 0;
261
 
262
      if( DoSessionNew(0) == 0 ) { // don't force overwrite
263
    // exit keypad editor
264
    SEQ_UI_MENU_UpdatePageList();
265
    menu_dialog = MENU_DIALOG_NONE;
266
      }
267
 
268
      return 1;
269
    } break;
270
 
271
    case SEQ_UI_ENCODER_GP16: {
272
      // EXIT only via button
273
      if( incrementer == 0 ) {
274
    SEQ_UI_MENU_UpdatePageList();
275
    menu_dialog = MENU_DIALOG_NONE;
276
      }
277
      return 1;
278
    } break;
279
    }
280
 
281
    return SEQ_UI_KeyPad_Handler(encoder, incrementer, (char *)&dir_name[0], 8);
282
  }
283
 
284
 
285
  ///////////////////////////////////////////////////////////////////////////
1635 tk 286
  case MENU_DIALOG_NEW_DEXISTS: {
959 tk 287
    switch( encoder ) {
288
    case SEQ_UI_ENCODER_GP11: {
289
      // YES only via button
290
      if( incrementer != 0 )
291
    return 0;
292
 
293
      // YES: overwrite session
1635 tk 294
      if( DoSessionNew(1) == 0 ) { // force overwrite
959 tk 295
    // exit keypad editor
296
    SEQ_UI_MENU_UpdatePageList();
297
    menu_dialog = MENU_DIALOG_NONE;
298
      }
299
      return 1;
300
    } break;
301
 
302
    case SEQ_UI_ENCODER_GP12: {
303
      // NO only via button
304
      if( incrementer != 0 )
305
    return 0;
306
 
307
      // NO: don't overwrite session - back to dirname entry
308
 
309
      ui_selected_item = 0;
1635 tk 310
      menu_dialog = MENU_DIALOG_NEW;
959 tk 311
      return 1;
312
    } break;
313
 
314
    case SEQ_UI_ENCODER_GP16: {
315
      // EXIT only via button
316
      if( incrementer == 0 ) {
317
    SEQ_UI_MENU_UpdatePageList();
318
    menu_dialog = MENU_DIALOG_NONE;
319
      }
320
      return 1;
321
    } break;
322
    }
323
 
324
    return -1; // not mapped
325
  }
326
 
327
 
328
  ///////////////////////////////////////////////////////////////////////////
1635 tk 329
  case MENU_DIALOG_DELETE:
959 tk 330
    switch( encoder ) {
1635 tk 331
    case SEQ_UI_ENCODER_GP9:
332
    case SEQ_UI_ENCODER_GP10:
333
    case SEQ_UI_ENCODER_GP11:
334
    case SEQ_UI_ENCODER_GP12:
335
    case SEQ_UI_ENCODER_GP13:
336
    case SEQ_UI_ENCODER_GP14:
337
    case SEQ_UI_ENCODER_GP15:
338
      return -1; // not mapped
959 tk 339
 
1635 tk 340
    case SEQ_UI_ENCODER_GP16:
341
      // EXIT only via button
342
      if( incrementer == 0 ) {
959 tk 343
    SEQ_UI_MENU_UpdatePageList();
344
    menu_dialog = MENU_DIALOG_NONE;
345
      }
346
      return 1;
1635 tk 347
 
348
    default:
349
      if( SEQ_UI_SelectListItem(incrementer, dir_num_items, SESSION_NUM_LIST_DISPLAYED_ITEMS, &ui_selected_item, &dir_view_offset) )
350
    SEQ_UI_MENU_UpdateSessionList();
351
    }
352
    break;
353
 
354
 
355
  ///////////////////////////////////////////////////////////////////////////
356
  case MENU_DIALOG_DELETE_CONFIRM: {
357
    switch( encoder ) {
358
    case SEQ_UI_ENCODER_GP12: {
359
      // YES only via button
360
      if( incrementer != 0 )
361
    return 0;
362
 
363
      // YES: delete session
364
      DoSessionDelete(0);
365
 
366
      // exit keypad editor
367
      SEQ_UI_MENU_UpdatePageList();
368
      menu_dialog = MENU_DIALOG_NONE;
369
      return 1;
959 tk 370
    } break;
371
 
1635 tk 372
    case SEQ_UI_ENCODER_GP13: {
959 tk 373
      // NO only via button
374
      if( incrementer != 0 )
375
    return 0;
376
 
1635 tk 377
      // NO: don't delete session - back to dirname entry
959 tk 378
 
379
      ui_selected_item = 0;
1635 tk 380
      menu_dialog = MENU_DIALOG_DELETE;
959 tk 381
      return 1;
382
    } break;
383
 
384
    case SEQ_UI_ENCODER_GP16: {
385
      // EXIT only via button
386
      if( incrementer == 0 ) {
387
    SEQ_UI_MENU_UpdatePageList();
388
    menu_dialog = MENU_DIALOG_NONE;
389
      }
390
      return 1;
391
    } break;
392
    }
393
 
394
    return -1; // not mapped
395
  }
396
 
397
  }
398
 
399
 
400
  // all other encoders
401
  return -1;
272 tk 402
}
403
 
404
 
405
/////////////////////////////////////////////////////////////////////////////
406
// Local button callback function
407
// Should return:
408
//   1 if value has been changed
409
//   0 if value hasn't been changed
410
//  -1 if invalid or unsupported button
411
/////////////////////////////////////////////////////////////////////////////
412
static s32 Button_Handler(seq_ui_button_t button, s32 depressed)
413
{
959 tk 414
  switch( menu_dialog ) {
415
  case MENU_DIALOG_NONE:
416
    if( depressed ) return 0; // ignore when button depressed
417
    if( button <= SEQ_UI_BUTTON_GP8 || button == SEQ_UI_BUTTON_Select ) {
418
      if( button != SEQ_UI_BUTTON_Select )
419
    menu_selected_item = button / 4;
272 tk 420
 
959 tk 421
      SEQ_UI_PageSet(SEQ_UI_FIRST_MENU_SELECTION_PAGE + menu_view_offset + menu_selected_item);
422
      return 1;
423
    }
735 tk 424
 
959 tk 425
    switch( button ) {
426
    case SEQ_UI_BUTTON_GP9:
427
      ui_selected_item = 0;
428
      menu_dialog = MENU_DIALOG_OPEN;
429
      SEQ_UI_MENU_UpdateSessionList();
430
      return 1;
431
 
432
    case SEQ_UI_BUTTON_GP10:
433
      if( SEQ_FILE_FormattingRequired() )
434
    SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, "No valid session!", "Create NEW one!");
435
      else {
974 tk 436
    // "save all" done in app.c as background task
437
    seq_ui_saveall_req = 1;
438
 
439
    // print message immediately for better "look&feel"
440
    // otherwise we could think that the button isn't working
1531 tk 441
    SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, "Complete session", "stored!");
959 tk 442
      }
443
      return 1;
444
 
445
    case SEQ_UI_BUTTON_GP11: {
446
      if( SEQ_FILE_FormattingRequired() )
447
    SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, "No valid session!", "Create NEW one!");
448
      else {
974 tk 449
    // "save all" done in app.c as background task
450
    seq_ui_saveall_req = 1;
451
 
452
    // enter keypad editor anyhow
453
    // initialize keypad editor
454
    SEQ_UI_KeyPad_Init();
1123 tk 455
 
456
    // copy current session name into dir_name
974 tk 457
    int i;
1123 tk 458
    for(i=0; i<8 && seq_file_session_name[i] != 0; ++i)
459
      dir_name[i] = seq_file_session_name[i];
460
    ui_edit_name_cursor = i;
461
    for(; i<8; ++i)
974 tk 462
      dir_name[i] = ' ';
1123 tk 463
 
974 tk 464
    ui_selected_item = 0;
465
    menu_dialog = MENU_DIALOG_SAVE_AS;
959 tk 466
      }
467
      return 1;
468
    }
469
 
470
    case SEQ_UI_BUTTON_GP12: {
471
      // initialize keypad editor
472
      SEQ_UI_KeyPad_Init();
473
      int i;
474
      for(i=0; i<8; ++i)
475
    dir_name[i] = ' ';
476
      ui_selected_item = 0;
477
      menu_dialog = MENU_DIALOG_NEW;
1635 tk 478
      return 1;
479
    }
959 tk 480
 
1635 tk 481
    case SEQ_UI_BUTTON_GP13: {
482
      ui_selected_item = 0;
483
      menu_dialog = MENU_DIALOG_DELETE;
484
      SEQ_UI_MENU_UpdateSessionList();
485
    }
486
 
959 tk 487
    case SEQ_UI_BUTTON_GP14:
488
      return 1;
489
 
490
    case SEQ_UI_BUTTON_GP15:
491
    case SEQ_UI_BUTTON_GP16:
492
      SEQ_UI_PageSet(SEQ_UI_PAGE_INFO);
493
      return 1;
494
    }
495
    break;
496
 
497
  ///////////////////////////////////////////////////////////////////////////
498
  case MENU_DIALOG_OPEN:
499
    if( depressed ) return 0; // ignore when button depressed
500
 
501
    if( button >= SEQ_UI_BUTTON_GP9 && button <= SEQ_UI_BUTTON_GP16 )
502
      return Encoder_Handler(button, 0); // re-use encoder handler
503
 
504
    if( button <= SEQ_UI_BUTTON_GP8 || button == SEQ_UI_BUTTON_Select ) {
505
      if( button != SEQ_UI_BUTTON_Select )
506
    ui_selected_item = button / 2;
507
 
508
      if( dir_num_items >= 1 && (ui_selected_item+dir_view_offset) < dir_num_items ) {
509
    // get filename
510
    int i;
511
    char *p = (char *)&dir_name[0];
512
    for(i=0; i<8; ++i) {
513
      char c = ui_global_dir_list[SESSION_LIST_ENTRY_WIDTH*ui_selected_item + i];
514
      if( c != ' ' )
515
        *p++ = c;
516
    }
517
    *p++ = 0;
518
 
1083 tk 519
    // reset CV channels (makes sense here to have a proper start)
520
    SEQ_CV_ResetAllChannels();
521
 
522
    // reset MIDI IN stacks as well
523
    SEQ_MIDI_IN_ResetAllStacks();
524
 
959 tk 525
    // try to open session
526
    OpenSession();
527
 
960 tk 528
    // stay in menu...
529
#if 0
959 tk 530
    // switch to main page
531
    SEQ_UI_MENU_UpdatePageList();
532
    menu_dialog = MENU_DIALOG_NONE;
960 tk 533
#endif
959 tk 534
    return 1;
535
      }
536
    }
537
    break;
538
 
539
  ///////////////////////////////////////////////////////////////////////////
1635 tk 540
  case MENU_DIALOG_DELETE:
541
    if( depressed ) return 0; // ignore when button depressed
542
 
543
    if( button >= SEQ_UI_BUTTON_GP9 && button <= SEQ_UI_BUTTON_GP16 )
544
      return Encoder_Handler(button, 0); // re-use encoder handler
545
 
546
    if( button <= SEQ_UI_BUTTON_GP8 || button == SEQ_UI_BUTTON_Select ) {
547
      if( button != SEQ_UI_BUTTON_Select )
548
    ui_selected_item = button / 2;
549
 
550
      if( dir_num_items >= 1 && (ui_selected_item+dir_view_offset) < dir_num_items ) {
551
    // get filename
552
    int i;
553
    char *p = (char *)&dir_name[0];
554
    for(i=0; i<8; ++i) {
555
      char c = ui_global_dir_list[SESSION_LIST_ENTRY_WIDTH*ui_selected_item + i];
556
      if( c != ' ' )
557
        *p++ = c;
558
    }
559
    *p++ = 0;
560
 
561
    // change to confirmation page if delete is possible
562
    if( DoSessionDelete(1) >= 0 ) // check only
563
      menu_dialog = MENU_DIALOG_DELETE_CONFIRM;
564
    return 1;
565
      }
566
    }
567
    break;
568
 
569
  ///////////////////////////////////////////////////////////////////////////
959 tk 570
  case MENU_DIALOG_SAVE_AS:
571
  case MENU_DIALOG_SAVE_DEXISTS:
572
  case MENU_DIALOG_NEW:
573
  case MENU_DIALOG_NEW_DEXISTS:
1635 tk 574
  case MENU_DIALOG_DELETE_CONFIRM:
959 tk 575
    if( depressed ) return 0; // ignore when button depressed
1123 tk 576
    if( button <= SEQ_UI_BUTTON_GP16 )
577
      return Encoder_Handler((seq_ui_encoder_t)button, 0);
747 tk 578
  }
746 tk 579
 
747 tk 580
  switch( button ) {
581
    case SEQ_UI_BUTTON_Right:
582
    case SEQ_UI_BUTTON_Up:
583
      return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1);
584
 
585
    case SEQ_UI_BUTTON_Left:
586
    case SEQ_UI_BUTTON_Down:
587
      return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1);
588
 
589
    case SEQ_UI_BUTTON_Exit:
959 tk 590
      if( menu_dialog == MENU_DIALOG_NONE )
591
    SEQ_UI_PageSet(SEQ_UI_FIRST_MENU_SELECTION_PAGE + menu_view_offset + menu_selected_item);
592
      else {
593
    SEQ_UI_MENU_UpdatePageList();
594
    menu_dialog = MENU_DIALOG_NONE;
595
      }
746 tk 596
      return 1;
272 tk 597
  }
598
 
599
  return -1; // invalid or unsupported button
600
}
601
 
602
 
603
/////////////////////////////////////////////////////////////////////////////
604
// Local Display Handler function
605
// IN: <high_prio>: if set, a high-priority LCD update is requested
606
/////////////////////////////////////////////////////////////////////////////
607
static s32 LCD_Handler(u8 high_prio)
608
{
959 tk 609
  switch( menu_dialog ) {
610
  case MENU_DIALOG_NONE: {
611
    // layout:
612
    // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
613
    // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
614
    // <--------------------------------------><-------------------------------------->
1421 tk 615
    // MIDIbox SEQ V4.0Beta17         1.  1.  0/SESSION/20100309              140.0 BPM
1635 tk 616
    //        Edit             Mute Tracks     Open Save SaveAs New Delete        Info 
959 tk 617
 
618
    if( high_prio ) {
619
      ///////////////////////////////////////////////////////////////////////////
620
      // Print Sequencer Position
621
      SEQ_LCD_CursorSet(24, 0);
622
 
623
      u32 tick = SEQ_BPM_TickGet();
624
      u32 ticks_per_step = SEQ_BPM_PPQN_Get() / 4;
625
      u32 ticks_per_measure = ticks_per_step * (seq_core_steps_per_measure+1);
626
      u32 measure = (tick / ticks_per_measure) + 1;
627
      u32 step = ((tick % ticks_per_measure) / ticks_per_step) + 1;
628
      u32 microstep = tick % ticks_per_step;
629
      SEQ_LCD_PrintFormattedString("%8u.%3d.%3d", measure, step, microstep);
1421 tk 630
 
631
      SEQ_LCD_CursorSet(40+31, 0);
632
      float bpm = SEQ_BPM_EffectiveGet();
633
      SEQ_LCD_PrintFormattedString("%3d.%d BPM", (int)bpm, (int)(10*bpm)%10);
959 tk 634
      return 0;
635
    }
636
 
749 tk 637
    ///////////////////////////////////////////////////////////////////////////
959 tk 638
    SEQ_LCD_CursorSet(0, 0);
639
    SEQ_LCD_PrintString(MIOS32_LCD_BOOT_MSG_LINE1);
640
    int fill_spaces = 25 - strlen(MIOS32_LCD_BOOT_MSG_LINE1);
641
    if( fill_spaces > 0 )
642
      SEQ_LCD_PrintSpaces(fill_spaces);
749 tk 643
 
959 tk 644
    SEQ_LCD_CursorSet(40, 0);
645
    SEQ_LCD_PrintFormattedString("%s/%s", SEQ_FILE_SESSION_PATH, seq_file_session_name);
646
    SEQ_LCD_PrintSpaces(40);
272 tk 647
 
1421 tk 648
    SEQ_LCD_CursorSet(40+31, 0);
649
    float bpm = SEQ_BPM_EffectiveGet();
650
    SEQ_LCD_PrintFormattedString("%3d.%d BPM", (int)bpm, (int)(10*bpm)%10);
272 tk 651
 
1421 tk 652
 
959 tk 653
    ///////////////////////////////////////////////////////////////////////////
654
    SEQ_LCD_CursorSet(0, 1);
272 tk 655
 
959 tk 656
    SEQ_LCD_PrintList((char *)ui_global_dir_list, MENU_LIST_ENTRY_WIDTH, SEQ_UI_NUM_MENU_PAGES, MENU_NUM_LIST_DISPLAYED_ITEMS, menu_selected_item, menu_view_offset);
286 tk 657
 
959 tk 658
    SEQ_LCD_CursorSet(40, 1);
1635 tk 659
    SEQ_LCD_PrintString("Open Save SaveAs New Delete        Info ");
959 tk 660
  } break;
286 tk 661
 
1635 tk 662
  case MENU_DIALOG_OPEN:
663
  case MENU_DIALOG_DELETE: {
959 tk 664
    // layout:
665
    // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
666
    // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
667
    // <--------------------------------------><-------------------------------------->
961 tk 668
    // Open Session (10 found)                 Current Session: /SESSION/xxxxxxxx      
959 tk 669
    //  xxxxxxxx  xxxxxxxx  xxxxxxxx  xxxxxxxx                                     EXIT
670
 
1635 tk 671
    // layout:
672
    // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
673
    // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
674
    // <--------------------------------------><-------------------------------------->
675
    // Delete Session (10 found)               Current Session: /SESSION/xxxxxxxx      
676
    //  xxxxxxxx  xxxxxxxx  xxxxxxxx  xxxxxxxx                                     EXIT
677
 
959 tk 678
    SEQ_LCD_CursorSet(0, 0);
679
    SEQ_LCD_PrintSpaces(40);
680
    SEQ_LCD_CursorSet(0, 0);
681
    if( dir_num_items < 0 ) {
1261 tk 682
      if( dir_num_items == FILE_ERR_NO_DIR )
959 tk 683
    SEQ_LCD_PrintFormattedString("%s directory not found on SD Card!", SEQ_FILE_SESSION_PATH);
684
      else
685
    SEQ_LCD_PrintFormattedString("SD Card Access Error: %d", dir_num_items);
686
    } else if( dir_num_items == 0 ) {
687
      SEQ_LCD_PrintFormattedString("No directories found under %s!", SEQ_FILE_SESSION_PATH);
688
    } else {
1635 tk 689
      if( menu_dialog == MENU_DIALOG_DELETE )
690
    SEQ_LCD_PrintFormattedString("Delete Session (%d found)", dir_num_items);
691
      else
692
    SEQ_LCD_PrintFormattedString("Open Session (%d found)", dir_num_items);
959 tk 693
    }
694
 
695
    ///////////////////////////////////////////////////////////////////////////
696
    SEQ_LCD_CursorSet(40, 0);
697
    SEQ_LCD_PrintSpaces(40);
698
    SEQ_LCD_CursorSet(40, 0);
699
    SEQ_LCD_PrintFormattedString("Current Session: %s/%s", SEQ_FILE_SESSION_PATH, seq_file_session_name);
700
 
701
    ///////////////////////////////////////////////////////////////////////////
702
    SEQ_LCD_CursorSet(0, 1);
703
 
704
    SEQ_LCD_PrintList((char *)ui_global_dir_list, SESSION_LIST_ENTRY_WIDTH, dir_num_items, SESSION_NUM_LIST_DISPLAYED_ITEMS, ui_selected_item, dir_view_offset);
705
 
706
    SEQ_LCD_PrintSpaces(36);
707
    SEQ_LCD_PrintString("EXIT");
708
  } break;
709
 
710
  case MENU_DIALOG_SAVE_AS:
711
  case MENU_DIALOG_NEW: {
712
    // layout:
713
    // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
714
    // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
715
    // <--------------------------------------><-------------------------------------->
716
    // "SaveAs":
717
    // >SAVE AS< Please enter session name:    /SESSIONS/<xxxxxxxx>                    
718
    // .,!1 ABC2 DEF3 GHI4 JKL5 MNO6 PQRS7 TUV8WXYZ9 -_ 0  Char <>  Del Ins   SAVE EXIT
719
 
720
    // "New":
721
    // >NEW< Please enter name of new session: /SESSIONS/<xxxxxxxx>                    
722
    // .,!1 ABC2 DEF3 GHI4 JKL5 MNO6 PQRS7 TUV8WXYZ9 -_ 0  Char <>  Del Ins   SAVE EXIT
723
 
724
    int i;
725
 
726
    SEQ_LCD_CursorSet(0, 0);
727
    if( menu_dialog == MENU_DIALOG_SAVE_AS )
728
      SEQ_LCD_PrintString(">SAVE AS< Please enter session name:    ");
729
    else
730
      SEQ_LCD_PrintString(">NEW< Please enter name of new session: ");
731
 
732
    SEQ_LCD_PrintFormattedString("%s/<", SEQ_FILE_SESSION_PATH);
733
    for(i=0; i<8; ++i)
734
      SEQ_LCD_PrintChar(dir_name[i]);
735
    SEQ_LCD_PrintString(">");
736
    SEQ_LCD_PrintSpaces(20);
737
 
738
    // insert flashing cursor
739
    if( ui_cursor_flash ) {
740
      SEQ_LCD_CursorSet(51 + ui_edit_name_cursor, 0);
741
      SEQ_LCD_PrintChar('*');
742
    }
743
 
744
    SEQ_UI_KeyPad_LCD_Msg();
745
    if( menu_dialog == MENU_DIALOG_SAVE_AS )
746
      SEQ_LCD_PrintString("  SAVE EXIT");
747
    else
748
      SEQ_LCD_PrintString("CREATE EXIT");
749
  } break;
750
 
751
  case MENU_DIALOG_SAVE_DEXISTS:
752
  case MENU_DIALOG_NEW_DEXISTS: {
753
    // layout:
754
    // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
755
    // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
756
    // <--------------------------------------><-------------------------------------->
757
    //                                         '/SESSIONS/xxxxxxxx' already exists     
758
    //                                         Overwrite? YES  NO                  EXIT
759
    SEQ_LCD_CursorSet(0, 0);
760
    SEQ_LCD_PrintSpaces(40);
761
 
762
    SEQ_LCD_PrintFormattedString("%s/%s already exists!", SEQ_FILE_SESSION_PATH, dir_name);
763
    SEQ_LCD_PrintSpaces(5+13);
764
 
765
    SEQ_LCD_CursorSet(0, 1);
766
    SEQ_LCD_PrintSpaces(40);
767
 
768
    SEQ_LCD_PrintString("Overwrite? YES  NO");
769
    SEQ_LCD_PrintSpaces(18);
770
    SEQ_LCD_PrintString("EXIT");
771
  } break;
1635 tk 772
 
773
  case MENU_DIALOG_DELETE_CONFIRM: {
774
    // layout:
775
    // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
776
    // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
777
    // <--------------------------------------><-------------------------------------->
778
    //                                         '/SESSIONS/xxxxxxxx' should be deleted! 
779
    //                                         Really DELETE? YES  NO              EXIT
780
    SEQ_LCD_CursorSet(0, 0);
781
    SEQ_LCD_PrintSpaces(40);
782
 
783
    SEQ_LCD_PrintFormattedString("%s/%s should be deleted!", SEQ_FILE_SESSION_PATH, dir_name);
784
    SEQ_LCD_PrintSpaces(5+13);
785
 
786
    SEQ_LCD_CursorSet(0, 1);
787
    SEQ_LCD_PrintSpaces(40);
788
 
789
    SEQ_LCD_PrintString("Really DELETE? YES  NO");
790
    SEQ_LCD_PrintSpaces(14);
791
    SEQ_LCD_PrintString("EXIT");
792
  } break;
959 tk 793
  }
794
 
272 tk 795
  return 0; // no error
796
}
797
 
798
 
799
/////////////////////////////////////////////////////////////////////////////
800
// Initialisation
801
/////////////////////////////////////////////////////////////////////////////
802
s32 SEQ_UI_MENU_Init(u32 mode)
803
{
804
  // install callback routines
805
  SEQ_UI_InstallButtonCallback(Button_Handler);
806
  SEQ_UI_InstallEncoderCallback(Encoder_Handler);
807
  SEQ_UI_InstallLEDCallback(LED_Handler);
808
  SEQ_UI_InstallLCDCallback(LCD_Handler);
809
 
744 tk 810
  // load charset (if this hasn't been done yet)
811
  SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_Menu);
812
 
959 tk 813
  menu_dialog = 0;
814
  dir_name[0] = 0;
815
 
746 tk 816
  int selected_page = SEQ_UI_FIRST_MENU_SELECTION_PAGE + menu_view_offset + menu_selected_item;
817
  if( selected_page != ui_selected_page ) {
818
    int page = ui_selected_page;
819
    if( page < SEQ_UI_FIRST_MENU_SELECTION_PAGE )
820
      page = SEQ_UI_FIRST_MENU_SELECTION_PAGE;
959 tk 821
 
746 tk 822
    menu_view_offset = page - SEQ_UI_FIRST_MENU_SELECTION_PAGE;
959 tk 823
    int max_offset = SEQ_UI_NUM_MENU_PAGES - MENU_NUM_LIST_DISPLAYED_ITEMS;
824
    if( menu_view_offset >= max_offset ) {
825
      menu_view_offset = max_offset;
826
      menu_selected_item = MENU_NUM_LIST_DISPLAYED_ITEMS-1;
827
    } else {
828
      menu_selected_item = 0;
829
    }
746 tk 830
  }
831
 
832
  SEQ_UI_MENU_UpdatePageList();
833
 
959 tk 834
 
272 tk 835
  return 0; // no error
836
}
286 tk 837
 
838
 
839
 
840
/////////////////////////////////////////////////////////////////////////////
746 tk 841
// Updates list based on selected menu page
842
/////////////////////////////////////////////////////////////////////////////
843
static s32 SEQ_UI_MENU_UpdatePageList(void)
844
{
845
  int item;
846
 
959 tk 847
  for(item=0; item<MENU_NUM_LIST_DISPLAYED_ITEMS && (item+menu_view_offset)<SEQ_UI_NUM_MENU_PAGES; ++item) {
746 tk 848
    int i;
849
 
959 tk 850
    char *list_item = (char *)&ui_global_dir_list[MENU_LIST_ENTRY_WIDTH*item];
746 tk 851
    strcpy(list_item, SEQ_UI_PageNameGet(SEQ_UI_FIRST_MENU_SELECTION_PAGE + item + menu_view_offset));
852
    for(i=strlen(list_item)-1; i>=0; --i)
853
      if( list_item[i] == ' ' )
854
    list_item[i] = 0;
855
      else
856
    break;
857
  }
858
 
959 tk 859
  while( item < MENU_NUM_LIST_DISPLAYED_ITEMS ) {
860
    ui_global_dir_list[MENU_LIST_ENTRY_WIDTH*item] = 0;
746 tk 861
    ++item;
862
  }
863
 
864
  return 0; // no error
865
}
959 tk 866
 
867
 
868
/////////////////////////////////////////////////////////////////////////////
869
// Updates list based on available sessions
870
/////////////////////////////////////////////////////////////////////////////
871
static s32 SEQ_UI_MENU_UpdateSessionList(void)
872
{
873
  int item;
874
 
875
  MUTEX_SDCARD_TAKE;
1261 tk 876
  dir_num_items = FILE_GetDirs(SEQ_FILE_SESSION_PATH, (char *)&ui_global_dir_list[0], SESSION_NUM_LIST_DISPLAYED_ITEMS, dir_view_offset);
959 tk 877
  MUTEX_SDCARD_GIVE;
878
 
879
  if( dir_num_items < 0 )
880
    item = 0;
881
  else if( dir_num_items < SESSION_NUM_LIST_DISPLAYED_ITEMS )
882
    item = dir_num_items;
883
  else
884
    item = SESSION_NUM_LIST_DISPLAYED_ITEMS;
885
 
886
  while( item < SESSION_NUM_LIST_DISPLAYED_ITEMS ) {
887
    ui_global_dir_list[SESSION_LIST_ENTRY_WIDTH*item] = 0;
888
    ++item;
889
  }
890
 
891
  return 0; // no error
892
}
893
 
894
 
895
/////////////////////////////////////////////////////////////////////////////
896
// Stores a session into new directory
897
/////////////////////////////////////////////////////////////////////////////
898
static s32 DoSessionSaveOrNew(u8 new_session, u8 force_overwrite)
899
{
900
  s32 status;
901
  int i;
902
  char path[30];
903
 
904
  // if an error is detected, we jump back to original page
905
  ui_selected_item = 0;
906
  menu_dialog = new_session ? MENU_DIALOG_NEW : MENU_DIALOG_SAVE_AS;
907
 
908
  u8 dirname_valid = 1;
909
  for(i=0; i<8; ++i)
910
    if( dir_name[i] == '.' || dir_name[i] == '?' || dir_name[i] == ',' || dir_name[i] == '!' )
911
      dirname_valid = 0;
912
 
913
  if( !dirname_valid ) {
914
    SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, "Name not valid!", "(remove . ? , !)");
915
    return -1;
916
  }
917
 
918
  if( dir_name[0] == ' ') {
919
    SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, "Please enter", "Session Name!");
920
    return -2;
921
  }
922
 
1123 tk 923
  // if dir_name is identical to current session name, we are done!
1130 tk 924
  // note: dir_name is padded with spaces, whereas for seq_file_session_name the last spaces have been removed
925
  // we should also always compare the upper-case (as stored in FAT)
926
  u8 dirname_equal = 1;
927
  for(i=0; i<8; ++i) {
928
    char dir_name_c = dir_name[i];
929
    if( dir_name_c >= 'a' && dir_name_c <= 'z' )
930
      dir_name_c -= 'a'-'A';
1123 tk 931
 
1130 tk 932
    if( dir_name_c == ' ' )
933
      break; // end of dir_name reached
934
 
935
    char session_name_c = seq_file_session_name[i];
936
    if( session_name_c >= 'a' && session_name_c <= 'z' )
937
      session_name_c -= 'a'-'A';
938
 
939
    if( session_name_c == 0 ||
940
    dir_name_c != session_name_c ) {
941
      dirname_equal = 0; // names not equal
942
      break;
943
    }
944
  }
945
 
946
  if( dirname_equal ) {
947
    SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, "Same Name - all", "4 patterns stored!");
1123 tk 948
    return 0;
949
  }
950
 
959 tk 951
  strcpy(path, SEQ_FILE_SESSION_PATH);
952
  MUTEX_SDCARD_TAKE;
1261 tk 953
  FILE_MakeDir(path); // create directory if it doesn't exist
954
  status = FILE_DirExists(path);
959 tk 955
  MUTEX_SDCARD_GIVE;
956
 
957
  if( status < 0 ) {
958
    SEQ_UI_SDCardErrMsg(2000, status);
959
    return -3;
960
  }
961
 
962
  if( status == 0 ) {
963
    SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, "/SESSIONS directory", "cannot be created!");
964
    return -4;
965
  }
966
 
967
  char session_dir[20];
968
  char *p = (char *)&session_dir[0];
969
  for(i=0; i<8; ++i) {
970
    char c = dir_name[i];
971
    if( c != ' ' )
972
      *p++ = c;
973
  }
974
  *p++ = 0;
975
 
976
  sprintf(path, "%s/%s", SEQ_FILE_SESSION_PATH, session_dir);
977
 
978
  MUTEX_SDCARD_TAKE;
1261 tk 979
  status = FILE_DirExists(path);
959 tk 980
  MUTEX_SDCARD_GIVE;
981
 
982
  if( status < 0 ) {
983
    SEQ_UI_SDCardErrMsg(2000, status);
984
    return -5;
985
  }
986
 
987
  if( !force_overwrite && status == 1) {
988
    // file exists - ask if it should be overwritten in a special dialog page
989
    menu_dialog = new_session ? MENU_DIALOG_NEW_DEXISTS : MENU_DIALOG_SAVE_DEXISTS;
990
    return 1;
991
  }
992
 
993
  MUTEX_SDCARD_TAKE;
1261 tk 994
  FILE_MakeDir(path); // create directory
995
  status = FILE_DirExists(path);
959 tk 996
  MUTEX_SDCARD_GIVE;
997
 
998
  if( status < 0 ) {
999
    SEQ_UI_SDCardErrMsg(2000, status);
1000
    return -6;
1001
  }
1002
 
1003
  // take over session name
1004
  strcpy(seq_file_new_session_name, session_dir);
1005
  seq_file_backup_percentage = 0;
1261 tk 1006
  file_copy_percentage = 0; // for percentage display
959 tk 1007
 
1008
  if( new_session ) {
965 tk 1009
    // stop sequencer if it is still running
1010
    if( SEQ_BPM_IsRunning() )
1011
      SEQ_BPM_Stop();
1145 tk 1012
    SEQ_SONG_Reset(0);
1013
    SEQ_CORE_Reset(0);
965 tk 1014
    SEQ_MIDPLY_Reset();
1015
 
1016
    // clear all patterns/etc.. to have a clean start
1794 tk 1017
    SEQ_CORE_Init(1); // except for global parameters
1117 tk 1018
    SEQ_GROOVE_Init(0);
1019
    SEQ_SONG_Init(0);
1020
    SEQ_MIXER_Init(0);
965 tk 1021
 
959 tk 1022
    // formatting handled by low-priority task in app.c
1044 tk 1023
    // messages print in seq_ui.c as long as request is active
959 tk 1024
    seq_ui_format_req = 1;
1025
  } else {
1026
    // Copy operation handled by low-priority task in app.c
1044 tk 1027
    // messages print in seq_ui.c as long as request is active
959 tk 1028
    seq_ui_backup_req = 1;
1029
  }
1030
 
1031
  return 0; // no error
1032
}
1033
 
1034
 
1035
/////////////////////////////////////////////////////////////////////////////
1036
// Stores a session into new directory
1037
/////////////////////////////////////////////////////////////////////////////
1038
static s32 DoSessionSave(u8 force_overwrite)
1039
{
1040
  return DoSessionSaveOrNew(0, force_overwrite);
1041
}
1042
 
1043
/////////////////////////////////////////////////////////////////////////////
1044
// Creates a new session
1045
/////////////////////////////////////////////////////////////////////////////
1046
static s32 DoSessionNew(u8 force_overwrite)
1047
{
1048
  return DoSessionSaveOrNew(1, force_overwrite);
1049
}
1050
 
1051
 
1052
/////////////////////////////////////////////////////////////////////////////
1635 tk 1053
// Deletes a session
1054
/////////////////////////////////////////////////////////////////////////////
1055
static s32 DoSessionDelete(u8 check_only)
1056
{
1057
  // get directory name
1058
  char session_dir[20];
1059
  int i;
1060
  char *p = (char *)&session_dir[0];
1061
  for(i=0; i<8; ++i) {
1062
    char c = ui_global_dir_list[SESSION_LIST_ENTRY_WIDTH*ui_selected_item + i];
1063
    if( c != ' ' )
1064
      *p++ = c;
1065
  }
1066
  *p++ = 0;
1067
 
1068
  // check if this is the active session
1069
  if( strcasecmp(session_dir, seq_file_session_name) == 0 ) {
1070
    SEQ_UI_Msg(SEQ_UI_MSG_USER, 2000, "This is the active Session!", "It can't be deleted!");
1071
    return -1;
1072
  }
1073
 
1074
  // we also don't allow to delete the default session
1075
  if( strcasecmp(session_dir, "default") == 0 ) {
1076
    SEQ_UI_Msg(SEQ_UI_MSG_USER, 2000, "The DEFAULT session", "can't be deleted!");
1077
    return -2;
1078
  }
1079
 
1080
  if( check_only )
1081
    return 0; // ok - delete will be allowed
1082
 
1083
  // complete path
1084
  char path[30];
1085
  sprintf(path, "%s/%s", SEQ_FILE_SESSION_PATH, session_dir);
1086
 
1087
  // remove all files of this path (the debug message are intented - could also be helpful for the user)
1088
  s32 status = 0;
1089
 
1090
  {
1091
    DIR di;
1092
    FILINFO de;
1093
 
1094
    DEBUG_MSG("Deleting %s\n", path);
1095
 
1096
    if( f_opendir(&di, path) != FR_OK ) {
1097
      DEBUG_MSG("Failed to open directory!");
1098
      status = FILE_ERR_NO_DIR;
1099
    } else {
1100
      while( f_readdir(&di, &de) == FR_OK && de.fname[0] != 0 ) {
1101
    if( de.fname[0] && de.fname[0] != '.' ) {
1102
      char filepath[30];
1103
      sprintf(filepath, "%s/%s", path, de.fname);
1104
 
1105
      s32 del_status;
1106
      if( (del_status=FILE_Remove(filepath)) < 0 ) {
1107
        DEBUG_MSG("FAILED to delete %s (status: %d)", filepath, del_status);
1108
      } else {
1109
        DEBUG_MSG("%s deleted", filepath);
1110
      }
1111
    }
1112
      }
1113
    }
1114
  }
1115
 
1116
 
1117
  // try to remove session directory
1118
  if( status < 0 || (status=FILE_Remove(path)) < 0 ) {
1119
    char buffer[40];
1120
    sprintf(buffer, "FAILED status %d", status);
1121
    SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, path, buffer);
1122
    DEBUG_MSG("FAILED to delete %s (status: %d)", path, status);
1123
    return -3; // delete failed
1124
  } else {
1125
    SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, path, "has been deleted!");
1126
    DEBUG_MSG("%s has been successfully deleted!", path);
1127
  }
1128
 
1129
  return 0; // no error
1130
}
1131
 
1132
/////////////////////////////////////////////////////////////////////////////
959 tk 1133
// Open a session
1134
/////////////////////////////////////////////////////////////////////////////
1135
static s32 OpenSession(void)
1136
{
1137
  s32 status = 0;
1138
 
1139
  // get directory name
1140
  char session_dir[20];
1141
  int i;
1142
  char *p = (char *)&session_dir[0];
1143
  for(i=0; i<8; ++i) {
1144
    char c = ui_global_dir_list[SESSION_LIST_ENTRY_WIDTH*ui_selected_item + i];
1145
    if( c != ' ' )
1146
      *p++ = c;
1147
  }
1148
  *p++ = 0;
1149
 
1150
  // check if directory still exists
1151
  char path[30];
1152
  sprintf(path, "%s/%s", SEQ_FILE_SESSION_PATH, session_dir);
1153
 
1154
  MUTEX_SDCARD_TAKE;
1261 tk 1155
  status = FILE_DirExists(path);
959 tk 1156
  MUTEX_SDCARD_GIVE;
1157
 
1158
  if( status < 0 ) {
1159
    SEQ_UI_SDCardErrMsg(2000, status);
1160
    return -1;
1161
  }
1162
 
1163
  if( status == 0 ) {
1164
    SEQ_UI_Msg(SEQ_UI_MSG_USER, 2000, "Session doesn't", "exist anymore?!?");
1165
    return -2;
1166
  }
1167
 
1168
  // remember previous session and switch to new name
1169
  char prev_session_name[13];
1170
  strcpy(prev_session_name, seq_file_session_name);
1171
  strcpy(seq_file_session_name, session_dir);
1172
 
1173
  // try to load files
1174
  MUTEX_SDCARD_TAKE;
1175
  status = SEQ_FILE_LoadAllFiles(0); // excluding HW config
1176
  MUTEX_SDCARD_GIVE;
1177
 
1178
  if( status < 0 ) {
1179
    // session invalid - switch back to previous one!
1180
    SEQ_UI_Msg(SEQ_UI_MSG_USER, 2000, "Session is invalid:", seq_file_session_name);
1181
    strcpy(seq_file_session_name, prev_session_name);
1182
    return -3;
1183
  }
1184
 
961 tk 1185
  SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, "Changed to Session:", seq_file_session_name);
1186
 
1187
  // store session name
1188
  MUTEX_SDCARD_TAKE;
1189
  status |= SEQ_FILE_StoreSessionName();
1190
  MUTEX_SDCARD_GIVE;
1191
 
959 tk 1192
  return 0; // no error
1193
}