Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
167 tk 1
// $Id: seq_ui_edit.c 1811 2013-06-25 20:50:00Z tk $
2
/*
3
 * Edit page
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>
19
#include "seq_lcd.h"
20
#include "seq_ui.h"
21
 
22
#include "seq_core.h"
168 tk 23
#include "seq_cc.h"
741 tk 24
#include "seq_cc_labels.h"
176 tk 25
#include "seq_layer.h"
167 tk 26
#include "seq_par.h"
27
#include "seq_trg.h"
690 tk 28
#include "seq_chord.h"
1349 tk 29
#include "seq_record.h"
600 tk 30
#include "seq_hwcfg.h"
167 tk 31
 
32
 
33
/////////////////////////////////////////////////////////////////////////////
1203 tk 34
// Global Variables
1142 tk 35
/////////////////////////////////////////////////////////////////////////////
1203 tk 36
seq_ui_edit_view_t seq_ui_edit_view = SEQ_UI_EDIT_VIEW_STEPS;
1142 tk 37
 
1203 tk 38
 
1142 tk 39
/////////////////////////////////////////////////////////////////////////////
1348 tk 40
// Global Defines
41
/////////////////////////////////////////////////////////////////////////////
42
#define DATAWHEEL_MODE_SCROLL_CURSOR   0
43
#define DATAWHEEL_MODE_SCROLL_VIEW     1
44
#define DATAWHEEL_MODE_CHANGE_VALUE    2
45
#define DATAWHEEL_MODE_CHANGE_PARLAYER 3
46
#define DATAWHEEL_MODE_CHANGE_TRGLAYER 4
47
 
48
#define DATAWHEEL_MODE_NUM             5
49
 
50
 
51
/////////////////////////////////////////////////////////////////////////////
729 tk 52
// Local Variables
53
/////////////////////////////////////////////////////////////////////////////
54
 
1142 tk 55
static u8 show_edit_config_page;
56
 
729 tk 57
static u16 selected_steps = 0xffff; // will only be initialized once after startup
58
 
1348 tk 59
static u8 datawheel_mode = 0; // will only be initialized once after startup
1211 tk 60
 
1350 tk 61
// activated by pressing EDIT button: encoder value will be taken over by releasing EDIT button
62
// mode 0: function not active (EDIT button released)
63
// mode 1: function activated (EDIT button pressed)
64
// mode 2: value has been changed while EDIT button pressed (a message will pop up on screen)
65
static u8 edit_passive_mode;
66
static u8 edit_passive_value;      // the tmp. edited value
67
static u8 edit_passive_track;      // to store the track of the edit value
68
static u8 edit_passive_step;       // to store the step of the edit value
69
static u8 edit_passive_par_layer;  // to store the layer of the edit value
70
static u8 edit_passive_instrument; // to store the instrument of the edit value
1348 tk 71
 
729 tk 72
/////////////////////////////////////////////////////////////////////////////
178 tk 73
// Local prototypes
74
/////////////////////////////////////////////////////////////////////////////
75
 
747 tk 76
static s32 ChangeSingleEncValue(u8 track, u16 par_step, u16 trg_step, s32 incrementer, s32 forced_value, u8 change_gate, u8 dont_change_gate);
1350 tk 77
static s32 PassiveEditEnter(void);
78
static s32 PassiveEditValid(void);
79
static s32 PassiveEditTakeOver(void);
178 tk 80
 
81
 
82
/////////////////////////////////////////////////////////////////////////////
240 tk 83
// LED handler function (globally accessible, since it's re-used by UTIL page)
167 tk 84
/////////////////////////////////////////////////////////////////////////////
240 tk 85
s32 SEQ_UI_EDIT_LED_Handler(u16 *gp_leds)
167 tk 86
{
87
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1142 tk 88
 
89
  if( show_edit_config_page ) {
90
    switch( seq_ui_edit_view ) {
91
    case SEQ_UI_EDIT_VIEW_STEPS: *gp_leds = (1 << 0); break;
92
    case SEQ_UI_EDIT_VIEW_TRG: *gp_leds = (1 << 1); break;
93
    case SEQ_UI_EDIT_VIEW_LAYERS: *gp_leds = (1 << 2); break;
94
    case SEQ_UI_EDIT_VIEW_303: *gp_leds = (1 << 3); break;
95
    case SEQ_UI_EDIT_VIEW_STEPSEL: *gp_leds = (1 << 8); break;
96
    }
97
  } else {
167 tk 98
 
1751 tk 99
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPS && seq_ui_button_state.CHANGE_ALL_STEPS ) {
100
      *gp_leds = ui_cursor_flash ? 0x0000 : selected_steps;
101
    } else if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL ) {
1142 tk 102
      *gp_leds = selected_steps;
103
    } else {
167 tk 104
 
1142 tk 105
      u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
106
 
107
      if( event_mode != SEQ_EVENT_MODE_Drum &&
108
      (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303) ) {
109
 
110
    if( SEQ_TRG_GateGet(visible_track, ui_selected_step, ui_selected_instrument) )
111
      *gp_leds |= (1 << 1);
112
    if( SEQ_TRG_AccentGet(visible_track, ui_selected_step, ui_selected_instrument) )
113
      *gp_leds |= (1 << 2);
114
    if( SEQ_TRG_GlideGet(visible_track, ui_selected_step, ui_selected_instrument) )
115
      *gp_leds |= (1 << 3);
116
 
117
    if( ui_selected_par_layer == 0 )
118
      *gp_leds |= (3 << 4);
119
    else
120
      *gp_leds |= (1 << (ui_selected_par_layer+5));
121
 
122
      } else if( event_mode != SEQ_EVENT_MODE_Drum &&
123
      (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_LAYERS || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG) ) {
124
 
125
    u8 num_t_layers = SEQ_TRG_NumLayersGet(visible_track);
126
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
127
      // maximum 7 parameter layers due to "Step" item!
128
      if( num_t_layers >= 7 )
129
        num_t_layers = 7;
130
    } else {
131
      // single trigger layer (gate)
132
      num_t_layers = 1;
133
    }
134
 
135
    int i;
136
    for(i=0; i<num_t_layers; ++i)
137
      if( SEQ_TRG_Get(visible_track, ui_selected_step, i, ui_selected_instrument) )
138
        *gp_leds |= (1 << (i+1));
139
 
140
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
141
      *gp_leds |= (1 << (ui_selected_par_layer+8));
142
    } else {
143
      *gp_leds |= (1 << (ui_selected_par_layer+2));
144
    }
145
      } else {
146
    *gp_leds =
147
      (SEQ_TRG_Get8(visible_track, 2*ui_selected_step_view+1, ui_selected_trg_layer, ui_selected_instrument) << 8) |
148
      (SEQ_TRG_Get8(visible_track, 2*ui_selected_step_view+0, ui_selected_trg_layer, ui_selected_instrument) << 0);
149
      }
150
    }
151
  }
152
 
167 tk 153
  return 0; // no error
154
}
155
 
156
 
157
/////////////////////////////////////////////////////////////////////////////
168 tk 158
// Local encoder callback function
159
// Should return:
160
//   1 if value has been changed
161
//   0 if value hasn't been changed
162
//  -1 if invalid or unsupported encoder
167 tk 163
/////////////////////////////////////////////////////////////////////////////
168 tk 164
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
167 tk 165
{
1348 tk 166
  u8 visible_track = SEQ_UI_VisibleTrackGet();
167
 
168
  if( encoder == SEQ_UI_ENCODER_Datawheel ) {
169
    u16 num_steps = SEQ_TRG_NumStepsGet(visible_track);
170
 
171
    switch( datawheel_mode ) {
172
    case DATAWHEEL_MODE_SCROLL_CURSOR:
1753 tk 173
      if( SEQ_UI_Var8_Inc(&ui_selected_step, 0, num_steps-1, incrementer) >= 1 ) {
174
    ui_selected_step_view = ui_selected_step / 16;
1348 tk 175
    return 1;
1753 tk 176
      } else
1348 tk 177
    return 0;
178
 
179
    case DATAWHEEL_MODE_SCROLL_VIEW:
180
      if( SEQ_UI_Var8_Inc(&ui_selected_step_view, 0, (num_steps-1)/16, incrementer) >= 1 ) {
1753 tk 181
    if( !seq_ui_button_state.CHANGE_ALL_STEPS ) {
182
      // select step within view
183
      ui_selected_step = (ui_selected_step_view << 4) | (ui_selected_step & 0xf);
184
    }
1348 tk 185
    return 1;
186
      } else {
187
    return 0;
188
      }
189
 
190
    case DATAWHEEL_MODE_CHANGE_VALUE:
191
      break; // drop... continue below with common encoder value change routine
192
 
193
    case DATAWHEEL_MODE_CHANGE_PARLAYER: {
194
      u8 num_layers = SEQ_PAR_NumLayersGet(visible_track);
195
 
196
      if( SEQ_UI_Var8_Inc(&ui_selected_par_layer, 0, num_layers-1, incrementer) >= 1 )
197
    return 1;
198
      else
199
    return 0;
200
    } break;
201
 
202
    case DATAWHEEL_MODE_CHANGE_TRGLAYER: {
203
      u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
204
 
205
      if( event_mode == SEQ_EVENT_MODE_Drum ) {
206
    u8 num_layers = SEQ_TRG_NumInstrumentsGet(visible_track);
207
    if( SEQ_UI_Var8_Inc(&ui_selected_instrument, 0, num_layers-1, incrementer) >= 1 )
208
      return 1;
209
    else
210
      return 0;
211
      } else {
212
    u8 num_layers = SEQ_TRG_NumLayersGet(visible_track);
213
    if( SEQ_UI_Var8_Inc(&ui_selected_trg_layer, 0, num_layers-1, incrementer) >= 1 )
214
      return 1;
215
    else
216
      return 0;
217
      }
218
    } break;
219
    }
220
  }
221
 
168 tk 222
#if 0
223
  // leads to: comparison is always true due to limited range of data type
224
  if( (encoder >= SEQ_UI_ENCODER_GP1 && encoder <= SEQ_UI_ENCODER_GP16) || encoder == SEQ_UI_ENCODER_Datawheel ) {
225
#else
226
  if( encoder <= SEQ_UI_ENCODER_GP16 || encoder == SEQ_UI_ENCODER_Datawheel ) {
227
#endif
1142 tk 228
 
229
    if( show_edit_config_page ) {
230
      switch( encoder ) {
231
      case SEQ_UI_ENCODER_GP1: seq_ui_edit_view = SEQ_UI_EDIT_VIEW_STEPS; break;
232
      case SEQ_UI_ENCODER_GP2: seq_ui_edit_view = SEQ_UI_EDIT_VIEW_TRG; break;
233
      case SEQ_UI_ENCODER_GP3: seq_ui_edit_view = SEQ_UI_EDIT_VIEW_LAYERS; break;
234
      case SEQ_UI_ENCODER_GP4: seq_ui_edit_view = SEQ_UI_EDIT_VIEW_303; break;
1483 tk 235
      case SEQ_UI_ENCODER_GP8: seq_ui_edit_view = SEQ_UI_EDIT_VIEW_STEPSEL; break;
1348 tk 236
 
1483 tk 237
      case SEQ_UI_ENCODER_GP9:
238
      case SEQ_UI_ENCODER_GP10: {
1348 tk 239
    if( incrementer == 0 ) // button
1753 tk 240
      incrementer = (encoder == SEQ_UI_ENCODER_GP9) ? -1 : 1;
1348 tk 241
 
242
    if( SEQ_UI_Var8_Inc(&datawheel_mode, 0, DATAWHEEL_MODE_NUM-1, incrementer) >= 1 )
243
      return 1;
244
    else
245
      return 0;
1142 tk 246
      }
1483 tk 247
 
248
      case SEQ_UI_ENCODER_GP13:
249
      case SEQ_UI_ENCODER_GP14:
250
    SEQ_UI_PageSet(SEQ_UI_PAGE_TRKRND);
251
    break;
252
 
253
      case SEQ_UI_ENCODER_GP15:
254
      case SEQ_UI_ENCODER_GP16:
255
    SEQ_UI_PageSet(SEQ_UI_PAGE_TRKEUCLID);
256
    break;
1348 tk 257
      }
258
 
1142 tk 259
      show_edit_config_page = 0; // switch back to view
260
      return 1; // value changed
261
    }
262
 
263
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL ) {
729 tk 264
      if( incrementer > 0 )
265
    selected_steps |= (1 << encoder);
266
      else
267
    selected_steps &= ~(1 << encoder);
268
      return 1; // value changed
269
    }
270
 
1142 tk 271
    u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
182 tk 272
 
1142 tk 273
    if( event_mode != SEQ_EVENT_MODE_Drum &&
274
    (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303) ) {
275
      u16 num_steps = SEQ_TRG_NumStepsGet(visible_track);
276
 
277
      if( encoder == SEQ_UI_ENCODER_GP1 ) {
1348 tk 278
    if( SEQ_UI_Var8_Inc(&ui_selected_step, 0, num_steps-1, incrementer) >= 1 )
1142 tk 279
      return 1;
280
    else
281
      return 0;
282
      } else if( encoder == SEQ_UI_ENCODER_GP2 ) {
283
    SEQ_TRG_GateSet(visible_track, ui_selected_step, ui_selected_instrument, incrementer > 0 ? 1 : 0);
284
    return 1;
285
      } else if( encoder == SEQ_UI_ENCODER_GP3 ) {
286
    SEQ_TRG_AccentSet(visible_track, ui_selected_step, ui_selected_instrument, incrementer > 0 ? 1 : 0);
287
    return 1;
288
      } else if( encoder == SEQ_UI_ENCODER_GP4 ) {
289
    SEQ_TRG_GlideSet(visible_track, ui_selected_step, ui_selected_instrument, incrementer > 0 ? 1 : 0);
290
    return 1;
291
      } else if( encoder == SEQ_UI_ENCODER_GP5 ) {
292
    ui_selected_par_layer = 0;
293
    u8 note = SEQ_PAR_Get(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument);
294
    u8 note_octave = note / 12;
295
    u8 note_key = note % 12;
296
 
297
    if( SEQ_UI_Var8_Inc(&note_octave, 0, 9, incrementer) >= 1 ) {
298
      SEQ_PAR_Set(visible_track, ui_selected_step, 0, ui_selected_instrument, 12*note_octave + note_key);
299
      return 1;
300
    }
301
    return 0;
302
      } else if( encoder == SEQ_UI_ENCODER_GP6 ) {
303
    ui_selected_par_layer = 0;
304
    u8 note = SEQ_PAR_Get(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument);
305
    u8 note_octave = note / 12;
306
    u8 note_key = note % 12;
307
 
308
    if( SEQ_UI_Var8_Inc(&note_key, 0, 11, incrementer) >= 1 ) {
309
      SEQ_PAR_Set(visible_track, ui_selected_step, 0, ui_selected_instrument, 12*note_octave + note_key);
310
      return 1;
311
    }
312
    return 0;
313
      } else if( encoder <= SEQ_UI_ENCODER_GP16 ) {
314
    u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
315
    if( ((int)encoder-5) >= num_p_layers )
316
        return 0; // ignore
317
      ui_selected_par_layer = encoder-5;
318
      }
319
 
320
      if( !incrementer ) // button selection only...
321
    return 1;
322
    }
323
 
324
    if( event_mode != SEQ_EVENT_MODE_Drum &&
325
      (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_LAYERS || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG) ) {
326
      u16 num_steps = SEQ_TRG_NumStepsGet(visible_track);
327
 
328
      if( encoder == SEQ_UI_ENCODER_GP1 ) {
1348 tk 329
    if( SEQ_UI_Var8_Inc(&ui_selected_step, 0, num_steps-1, incrementer) >= 1 )
1142 tk 330
      return 1;
331
    else
332
      return 0;
333
      } else if( encoder == SEQ_UI_ENCODER_GP2 ||
334
         (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG && encoder <= SEQ_UI_ENCODER_GP8) ) {
335
    u8 sel = (u8)encoder-1;
336
    SEQ_TRG_Set(visible_track, ui_selected_step, sel, ui_selected_instrument, incrementer > 0 ? 1 : 0);
337
    return 1;
338
      } else if( encoder <= SEQ_UI_ENCODER_GP16 ) {
339
 
340
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
341
      if( encoder <= SEQ_UI_ENCODER_GP8 ) {
342
        u8 num_t_layers = SEQ_TRG_NumLayersGet(visible_track);
343
        if( ((int)encoder-2) >= num_t_layers )
344
          return 0; // ignore
345
        ui_selected_trg_layer = encoder-2;
346
      } else {
347
        u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
348
        if( ((int)encoder-8) >= num_p_layers )
349
          return 0; // ignore
350
        ui_selected_par_layer = encoder-8;
351
      }
352
    } else {
353
      u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
354
      if( ((int)encoder-2) >= num_p_layers )
355
        return 0; // ignore
356
      ui_selected_par_layer = encoder-2;
357
    }
358
 
359
    if( !incrementer ) // button selection only...
360
      return 1;
361
      }
362
    }
363
 
1809 tk 364
    u8 changed_step;
365
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPS ) {
366
      changed_step = ((encoder == SEQ_UI_ENCODER_Datawheel) ? (ui_selected_step%16) : encoder) + ui_selected_step_view*16;
367
    } else {
368
      changed_step = ui_selected_step;
369
    }
370
 
1751 tk 371
    u8 edit_ramp = 0;
1350 tk 372
    if( event_mode == SEQ_EVENT_MODE_Drum || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPS ) {
1142 tk 373
 
1350 tk 374
      // in passive edit mode: take over the edit value if step has changed, thereafter switch to new step
1751 tk 375
      if( ui_selected_step != changed_step && edit_passive_mode ) {
1350 tk 376
    PassiveEditTakeOver();
1751 tk 377
    ui_selected_step = changed_step;
1350 tk 378
    PassiveEditEnter();
379
      } else {
1751 tk 380
    // take over new step if "ALL" button not pressed to support "ramp" editing
381
    if( !seq_ui_button_state.CHANGE_ALL_STEPS ) {
382
      ui_selected_step = changed_step;
383
    } else {
384
      if( ui_selected_step != changed_step )
385
        edit_ramp = 1;
386
    }
1350 tk 387
      }
388
 
389
    }
390
 
391
 
392
    // in passive edit mode: change value, but don't take over yet!
393
    if( edit_passive_mode ) {
394
      if( SEQ_UI_Var8_Inc(&edit_passive_value, 0, 127, incrementer) >= 1 ) {
395
    edit_passive_mode = 2; // value has been changed
396
    return 1;
397
      } else
398
    return 0;
399
    }
400
 
401
    // normal edit mode
178 tk 402
    s32 value_changed = 0;
403
    s32 forced_value = -1;
404
    u8  change_gate = 1;
168 tk 405
 
182 tk 406
    // due to historical reasons (from old times where MBSEQ CS was stuffed with pots): 
407
    // in arp mode, we increment in steps of 4
1143 tk 408
    u8 par_type = SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer);
182 tk 409
    if( SEQ_CC_Get(visible_track, SEQ_CC_MODE) == SEQ_CORE_TRKMODE_Arpeggiator &&
1143 tk 410
    par_type == SEQ_PAR_Type_Note )
182 tk 411
      incrementer *= 4;
412
 
178 tk 413
    // first change the selected value
1751 tk 414
    if( seq_ui_button_state.CHANGE_ALL_STEPS && (edit_ramp || seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE) ) {
652 tk 415
      u16 num_steps = SEQ_PAR_NumStepsGet(visible_track);
1751 tk 416
      u16 par_step = changed_step;
417
      u16 trg_step = changed_step;
652 tk 418
 
419
      // mirrored layer in drum mode?
420
      u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
421
      if( event_mode == SEQ_EVENT_MODE_Drum && par_step >= num_steps )
422
    par_step %= num_steps;
423
 
747 tk 424
      forced_value = ChangeSingleEncValue(visible_track, par_step, trg_step, incrementer, forced_value, change_gate, 0);
178 tk 425
      if( forced_value < 0 )
426
    return 0; // no change
427
      value_changed |= 1;
168 tk 428
    }
429
 
1751 tk 430
    int value_selected_step = SEQ_PAR_Get(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument);
431
    int value_changed_step = SEQ_PAR_Get(visible_track, changed_step, ui_selected_par_layer, ui_selected_instrument);
432
 
178 tk 433
    // change value of all selected steps
434
    u8 track;
435
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
436
      if( SEQ_UI_IsSelectedTrack(track) ) {
318 tk 437
    u16 num_steps = SEQ_PAR_NumStepsGet(track);
1751 tk 438
    u16 trg_step = (changed_step & ~(num_steps-1));
439
 
652 tk 440
    u16 par_step;
441
    for(par_step=0; par_step<num_steps; ++par_step, ++trg_step) {
1751 tk 442
      if( !seq_ui_button_state.CHANGE_ALL_STEPS || (!edit_ramp && par_step == changed_step) || (selected_steps & (1 << (par_step % 16))) ) {
443
        change_gate = trg_step == changed_step;
444
        u8 dont_change_gate = par_step != changed_step;
729 tk 445
        if( change_gate || seq_ui_button_state.CHANGE_ALL_STEPS ) {
1751 tk 446
          s32 local_forced_value = edit_ramp ? -1 : forced_value;
447
 
448
          s32 edit_ramp_num_steps = 0;
449
          if( edit_ramp ) {
450
        if( changed_step > ui_selected_step && par_step > ui_selected_step && par_step < changed_step ) {
451
          edit_ramp_num_steps = changed_step - ui_selected_step;
452
        } else if( changed_step < ui_selected_step && par_step < ui_selected_step && par_step > changed_step ) {
453
          edit_ramp_num_steps = ui_selected_step - changed_step;
454
        }
455
 
456
        if( edit_ramp_num_steps ) {
457
          if( par_step == changed_step ) {
458
            local_forced_value = value_changed_step;
459
          } else {
460
            int diff = value_changed_step - value_selected_step;
461
            if( diff == 0 ) {
462
              local_forced_value = value_changed_step;
463
            } else {
464
              if( changed_step > ui_selected_step ) {
465
            local_forced_value = value_selected_step + (((par_step - ui_selected_step) * diff) / edit_ramp_num_steps);
466
              } else {
467
            local_forced_value = value_selected_step + (((ui_selected_step - par_step) * diff) / edit_ramp_num_steps);
468
              }
469
            }
470
          }
471
        }
472
          }
473
 
474
          if( !edit_ramp || edit_ramp_num_steps ) {
475
        if( ChangeSingleEncValue(track, par_step, trg_step, incrementer, local_forced_value, change_gate, dont_change_gate) >= 0 )
476
          value_changed |= 1;
477
          }
729 tk 478
        }
178 tk 479
      }
480
    }
481
      }
176 tk 482
    }
1142 tk 483
 
178 tk 484
    return value_changed;
168 tk 485
  }
486
 
487
  return -1; // invalid or unsupported encoder
167 tk 488
}
489
 
490
 
491
/////////////////////////////////////////////////////////////////////////////
168 tk 492
// Local button callback function
493
// Should return:
494
//   1 if value has been changed
495
//   0 if value hasn't been changed
496
//  -1 if invalid or unsupported button
167 tk 497
/////////////////////////////////////////////////////////////////////////////
758 tk 498
s32 SEQ_UI_EDIT_Button_Handler(seq_ui_button_t button, s32 depressed)
167 tk 499
{
306 tk 500
  u8 visible_track = SEQ_UI_VisibleTrackGet();
501
 
168 tk 502
#if 0
503
  // leads to: comparison is always true due to limited range of data type
504
  if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) {
505
#else
506
  if( button <= SEQ_UI_BUTTON_GP16 ) {
507
#endif
729 tk 508
    if( depressed ) return 0; // ignore when button depressed
509
 
1142 tk 510
    if( show_edit_config_page )
511
      return Encoder_Handler(button, 0);
512
 
1751 tk 513
    if( (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPS && seq_ui_button_state.CHANGE_ALL_STEPS) ||
514
    seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL ) {
729 tk 515
      selected_steps ^= (1 << button);
516
      return 1; // value changed
517
    }
518
 
1142 tk 519
    u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
520
 
521
    if( event_mode != SEQ_EVENT_MODE_Drum &&
522
    (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303) ) {
523
 
524
      if( button == SEQ_UI_BUTTON_GP1 ) {
525
    int next_step = ui_selected_step + 1; // (required, since ui_selected_step is only u8, but we could have up to 256 steps)
526
    if( next_step >= (SEQ_CC_Get(visible_track, SEQ_CC_LENGTH)+1) )
527
      next_step = 0;
528
    ui_selected_step = next_step;
529
    ui_selected_step_view = ui_selected_step / 16;
530
    return 1; // value always changed
531
      } else if( button == SEQ_UI_BUTTON_GP2 ) {
532
    u8 trg = SEQ_TRG_GateGet(visible_track, ui_selected_step, ui_selected_instrument);
533
    return Encoder_Handler(button, trg ? -1 : 1);
534
      } else if( button == SEQ_UI_BUTTON_GP3 ) {
535
    u8 trg = SEQ_TRG_AccentGet(visible_track, ui_selected_step, ui_selected_instrument);
536
    return Encoder_Handler(button, trg ? -1 : 1);
537
      } else if( button == SEQ_UI_BUTTON_GP4 ) {
538
    u8 trg = SEQ_TRG_GlideGet(visible_track, ui_selected_step, ui_selected_instrument);
539
    return Encoder_Handler(button, trg ? -1 : 1);
540
      } else if( button <= SEQ_UI_BUTTON_GP16 ) {
541
    return Encoder_Handler(button, 0);
542
      }
543
    }
544
 
545
 
546
    if( event_mode != SEQ_EVENT_MODE_Drum &&
547
      (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_LAYERS || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG) ) {
548
 
549
      if( button == SEQ_UI_BUTTON_GP1 ) {
550
    int next_step = ui_selected_step + 1; // (required, since ui_selected_step is only u8, but we could have up to 256 steps)
551
    if( next_step >= (SEQ_CC_Get(visible_track, SEQ_CC_LENGTH)+1) )
552
      next_step = 0;
553
    ui_selected_step = next_step;
554
    ui_selected_step_view = ui_selected_step / 16;
555
    return 1; // value always changed
556
      } else if( button == SEQ_UI_BUTTON_GP2 ||
557
         (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG && button <= SEQ_UI_BUTTON_GP8) ) {
558
    u8 trg = SEQ_TRG_Get(visible_track, ui_selected_step, (u8)button-1, ui_selected_instrument);
559
    return Encoder_Handler(button, trg ? -1 : 1);
560
      } else if( button <= SEQ_UI_BUTTON_GP16 ) {
561
    return Encoder_Handler(button, 0);
562
      }
563
    }
564
 
180 tk 565
    ui_selected_step = button + ui_selected_step_view*16;
1142 tk 566
 
168 tk 567
    // toggle trigger layer
600 tk 568
    // if seq_hwcfg_button_beh.all_with_triggers set, we've three cases:
178 tk 569
    // a) ALL function active, but ALL button not pressed: invert complete trigger layer
570
    // b) ALL function active and ALL button pressed: toggle step, set remaining steps to same new value
571
    // c) ALL function not active: toggle step
600 tk 572
    if( seq_hwcfg_button_beh.all_with_triggers && seq_ui_button_state.CHANGE_ALL_STEPS ) {
178 tk 573
      if( seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
574
    // b) ALL function active and ALL button pressed: toggle step, set remaining steps to same new value
303 tk 575
    u16 step = ui_selected_step;
328 tk 576
    u8 new_value = SEQ_TRG_Get(visible_track, step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
1142 tk 577
 
178 tk 578
    u8 track;
579
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track)
318 tk 580
      if( SEQ_UI_IsSelectedTrack(track) ) {
581
        u16 num_steps = SEQ_TRG_NumStepsGet(track);
582
        for(step=0; step<num_steps; ++step)
328 tk 583
          SEQ_TRG_Set(track, step, ui_selected_trg_layer, ui_selected_instrument, new_value);
318 tk 584
      }
178 tk 585
      } else {
586
    // a) ALL function active, but ALL button not pressed: invert complete trigger layer
303 tk 587
    u8 track;
588
    u16 step;
178 tk 589
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
590
      if( SEQ_UI_IsSelectedTrack(track) ) {
318 tk 591
        u16 num_steps = SEQ_TRG_NumStepsGet(track);
592
        for(step=0; step<num_steps; ++step) {
328 tk 593
          u8 new_value = SEQ_TRG_Get(track, step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
594
          SEQ_TRG_Set(track, step, ui_selected_trg_layer, ui_selected_instrument, new_value);
178 tk 595
        }
596
      }
597
    }
598
      }
599
    } else {
600
      // c) ALL function not active: toggle step
601
      u8 track;
1142 tk 602
 
484 tk 603
      u8 new_value = SEQ_TRG_Get(visible_track, ui_selected_step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
178 tk 604
      for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
605
    if( SEQ_UI_IsSelectedTrack(track) ) {
328 tk 606
      SEQ_TRG_Set(track, ui_selected_step, ui_selected_trg_layer, ui_selected_instrument, new_value);
178 tk 607
    }
608
      }
609
    }
1142 tk 610
 
168 tk 611
    return 1; // value always changed
178 tk 612
 
168 tk 613
  } else {
614
    switch( button ) {
615
      case SEQ_UI_BUTTON_Select:
1142 tk 616
    show_edit_config_page = depressed ? 0 : 1;
729 tk 617
    return 1; // value always changed
618
 
303 tk 619
      case SEQ_UI_BUTTON_Right: {
729 tk 620
    if( depressed ) return 0; // ignore when button depressed
621
 
303 tk 622
    int next_step = ui_selected_step + 1; // (required, since ui_selected_step is only u8, but we could have up to 256 steps)
306 tk 623
    if( next_step >= (SEQ_CC_Get(visible_track, SEQ_CC_LENGTH)+1) )
303 tk 624
      next_step = 0;
625
    ui_selected_step = next_step;
168 tk 626
    ui_selected_step_view = ui_selected_step / 16;
627
    return 1; // value always changed
303 tk 628
      } break;
167 tk 629
 
168 tk 630
      case SEQ_UI_BUTTON_Left:
729 tk 631
    if( depressed ) return 0; // ignore when button depressed
632
 
168 tk 633
    if( ui_selected_step == 0 )
306 tk 634
      ui_selected_step = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
1142 tk 635
    else
636
      --ui_selected_step;
637
 
168 tk 638
    ui_selected_step_view = ui_selected_step / 16;
639
    return 1; // value always changed
167 tk 640
 
168 tk 641
      case SEQ_UI_BUTTON_Up:
729 tk 642
    if( depressed ) return 0; // ignore when button depressed
168 tk 643
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1);
644
 
645
      case SEQ_UI_BUTTON_Down:
729 tk 646
    if( depressed ) return 0; // ignore when button depressed
168 tk 647
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1);
1350 tk 648
 
649
      // this button is currently only notified to EDIT page
650
      case SEQ_UI_BUTTON_Edit:
651
    if( !depressed )
652
      PassiveEditEnter();
1351 tk 653
    else {
1350 tk 654
      PassiveEditTakeOver();
1351 tk 655
      edit_passive_mode = 0;
656
    }
1350 tk 657
    return 1;
168 tk 658
    }
167 tk 659
  }
660
 
168 tk 661
  return -1; // invalid or unsupported button
167 tk 662
}
663
 
664
 
665
/////////////////////////////////////////////////////////////////////////////
240 tk 666
// Global Display Handler function
167 tk 667
// IN: <high_prio>: if set, a high-priority LCD update is requested
240 tk 668
//     <edit_page>: selects the normal, or copy/paste/move/scroll view
167 tk 669
/////////////////////////////////////////////////////////////////////////////
240 tk 670
s32 SEQ_UI_EDIT_LCD_Handler(u8 high_prio, seq_ui_edit_mode_t edit_mode)
167 tk 671
{
672
  if( high_prio )
673
    return 0; // there are no high-priority updates
674
 
326 tk 675
 
676
  // layout common track:
677
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
678
  // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
679
  // G1T1 xxxxxxxxxxxxxxx  PC:Length TA:Gate Step  1   G#1_ Vel:127_Len: 75%    xxxxx
680
  // ....
681
 
682
  // layout drum track:
683
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
684
  // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
685
  // G1T1 xxxxxxxxxxxxxxx  PA:Vel.   TA:Gate Step  1   G#1_ Vel:127_Len: 75%    xxxxx
686
  // ....
687
 
1142 tk 688
  // layout edit config
689
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
1483 tk 690
  // Step Trg  Layer 303                Step Datawheel:           Random    Euclid   
691
  // View View View View               Select Scroll             Generator Generator 
1142 tk 692
 
693
  // layout trigger view
694
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
695
  // Step Gate Acc. Roll Glide Skip R.G  R.V Note Vel. Len. Roll Note Note Note Note 
696
  //   1    *    o    o    o    o    o    o  C-3  100   75% ---- E-3  G-3  ---- ---- 
697
 
698
  // layout layer view
699
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
700
  // Step Gate Note Vel. Len. Roll Note Note Note Note Note Note Note Note Note Note 
701
  //   1    *  C-3  100   75% ---- E-3  G-3  ---- ---- ---- ---- ---- ---- ---- ---- 
702
 
703
  // layout 303 view
704
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
705
  // Step Gate Acc. Glide Oct, Key Vel. Prob  CC   CC   CC   CC   CC   CC   CC   CC  
706
  //   1    *   o     o    3    C  100  100%  64   64   64   64   64   64   64   64  
707
 
729 tk 708
  // layout step selection:
709
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
710
  //        Select the steps which should be  controlled by the ALL function:        
711
  //   *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *  
326 tk 712
 
1142 tk 713
  if( show_edit_config_page ) {
1348 tk 714
    const char datawheel_mode_str[DATAWHEEL_MODE_NUM][11] = {
715
      " Cursor   ",
716
      " StepView ",
717
      " Value    ",
718
      " ParLayer ",
719
      " TrgLayer ",
720
    };
721
 
1142 tk 722
    SEQ_LCD_CursorSet(0, 0);
1483 tk 723
    SEQ_LCD_PrintString("Step Trg  Layer 303                Step Datawheel:           Random    Euclid   ");
1142 tk 724
    SEQ_LCD_CursorSet(0, 1);
1483 tk 725
    SEQ_LCD_PrintString("View View View View               Select");
1348 tk 726
    SEQ_LCD_PrintString((char *)datawheel_mode_str[datawheel_mode]);
1483 tk 727
    SEQ_LCD_PrintString("          Generator Generator ");
1142 tk 728
    return 0; // no error
729
  }
730
 
731
  if( !edit_mode && seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL ) {
729 tk 732
    int step;
733
 
734
    SEQ_LCD_CursorSet(0, 0);
735
    SEQ_LCD_PrintString("       Select the steps which should be  controlled by the ALL function:        ");
736
    SEQ_LCD_CursorSet(0, 1);
737
    for(step=0; step<16; ++step)
738
      SEQ_LCD_PrintFormattedString("  %c  ", (selected_steps & (1 << step)) ? '*' : 'o');
739
    return 0; // no error
740
  }
741
 
742
 
167 tk 743
  u8 visible_track = SEQ_UI_VisibleTrackGet();
323 tk 744
  u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
167 tk 745
 
1142 tk 746
 
1316 tk 747
  if( !edit_mode && event_mode != SEQ_EVENT_MODE_Drum &&
1142 tk 748
      (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303) ) {
749
    // we want to show vertical bars
750
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
751
 
752
    u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
753
    // maximum 10 parameter layers
754
    if( num_p_layers >= 11 )
755
      num_p_layers = 11;
756
 
757
    ///////////////////////////////////////////////////////////////////////////
758
    SEQ_LCD_CursorSet(0, 0);
759
    SEQ_LCD_PrintString("Step Gate Acc. Glide Oct. Key ");
760
    int i;
761
    for(i=1; i<num_p_layers; ++i)
762
    SEQ_LCD_PrintString((char *)SEQ_PAR_AssignedTypeStr(visible_track, i));
763
 
764
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
765
 
766
    ///////////////////////////////////////////////////////////////////////////
767
    SEQ_LCD_CursorSet(0, 1);
768
    SEQ_LCD_PrintFormattedString("%3d  ", ui_selected_step+1);
769
    SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_GateGet(visible_track, ui_selected_step, ui_selected_instrument) ? '*' : 'o');
770
    SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_AccentGet(visible_track, ui_selected_step, ui_selected_instrument) ? '*' : 'o');
771
    SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_GlideGet(visible_track, ui_selected_step, ui_selected_instrument) ? '*' : 'o');
772
 
1351 tk 773
    u8 note = SEQ_PAR_Get(visible_track, ui_selected_step, 0, ui_selected_instrument);
1142 tk 774
    u8 note_octave = note / 12;
775
    u8 note_key = note % 12;
776
 
777
    SEQ_LCD_PrintFormattedString(" %2d  ", (int)note_octave-2);
778
    const char note_tab[12][2] = { "C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B " };
779
    SEQ_LCD_PrintFormattedString("  %c%c ", note_tab[note_key][0], note_tab[note_key][1]);
780
 
781
    for(i=1; i<num_p_layers; ++i)
782
      if( i == ui_selected_par_layer && ui_cursor_flash )
783
    SEQ_LCD_PrintSpaces(5);
784
      else {
1351 tk 785
    int print_edit_value = PassiveEditValid() ? edit_passive_value : -1;
786
    SEQ_LCD_PrintLayerEvent(visible_track, ui_selected_step, i, ui_selected_instrument, 0, print_edit_value);
1142 tk 787
    SEQ_LCD_PrintChar(' ');
788
      }
789
 
790
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
791
 
792
    return 0;
793
  }
794
 
1316 tk 795
  if( !edit_mode && event_mode != SEQ_EVENT_MODE_Drum &&
1142 tk 796
      (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_LAYERS || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG) ) {
797
 
798
    // we want to show vertical bars
799
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
800
 
801
    u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
802
    u8 num_t_layers = SEQ_TRG_NumLayersGet(visible_track);
803
 
804
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
805
      // maximum 7 parameter layers due to "Step" item!
806
      if( num_t_layers >= 7 )
807
    num_t_layers = 7;
808
 
809
      // maximum 8 parameter layers
810
      if( num_p_layers >= 8 )
811
    num_p_layers = 8;
812
    } else {
813
      // single trigger layer (gate)
814
      num_t_layers = 1;
815
 
816
      // maximum 14 parameter layers due to "Step" and "Gate" item!
817
      if( num_p_layers >= 14 )
818
    num_p_layers = 14;
819
    }
820
 
821
    ///////////////////////////////////////////////////////////////////////////
822
    SEQ_LCD_CursorSet(0, 0);
823
    SEQ_LCD_PrintString("Step ");
824
    int i;
825
    for(i=0; i<num_t_layers; ++i)
826
    SEQ_LCD_PrintString(SEQ_TRG_AssignedTypeStr(visible_track, i));
827
    for(i=0; i<num_p_layers; ++i)
828
    SEQ_LCD_PrintString((char *)SEQ_PAR_AssignedTypeStr(visible_track, i));
829
 
830
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
831
 
832
    ///////////////////////////////////////////////////////////////////////////
833
    SEQ_LCD_CursorSet(0, 1);
834
    SEQ_LCD_PrintFormattedString("%3d  ", ui_selected_step+1);
835
    for(i=0; i<num_t_layers; ++i)
836
      SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_Get(visible_track, ui_selected_step, i, ui_selected_instrument) ? '*' : 'o');
837
    for(i=0; i<num_p_layers; ++i)
838
      if( i == ui_selected_par_layer && ui_cursor_flash )
839
    SEQ_LCD_PrintSpaces(5);
840
      else {
1351 tk 841
    int print_edit_value = PassiveEditValid() ? edit_passive_value : -1;
842
    SEQ_LCD_PrintLayerEvent(visible_track, ui_selected_step, i, ui_selected_instrument, 0, print_edit_value);
1142 tk 843
    SEQ_LCD_PrintChar(' ');
844
      }
845
 
846
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
847
 
848
    return 0;
849
  }
850
 
176 tk 851
  seq_layer_evnt_t layer_event;
336 tk 852
  SEQ_LAYER_GetEvntOfLayer(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
168 tk 853
 
333 tk 854
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer);
176 tk 855
 
333 tk 856
  // TODO: tmp. solution to print chord velocity correctly
857
  if( layer_type == SEQ_PAR_Type_Velocity && (seq_cc_trk[visible_track].link_par_layer_chord == 0) )
858
    layer_type = SEQ_PAR_Type_Chord;
326 tk 859
 
333 tk 860
 
167 tk 861
  ///////////////////////////////////////////////////////////////////////////
278 tk 862
  SEQ_LCD_CursorSet(0, 0);
167 tk 863
 
326 tk 864
  SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks);
865
  SEQ_LCD_PrintSpaces(1);
866
 
1349 tk 867
 
1350 tk 868
  if( ui_page == SEQ_UI_PAGE_EDIT && edit_passive_mode == 2 ) {
1349 tk 869
    if( ui_cursor_flash ) {
870
      SEQ_LCD_PrintSpaces(15);
871
    } else {
1350 tk 872
      SEQ_LCD_PrintString("PASSIVE EDITING");
873
    }
874
  } else if( seq_record_state.ENABLED || edit_mode == SEQ_UI_EDIT_MODE_RECORD ) {
875
    if( ui_cursor_flash ) {
876
      SEQ_LCD_PrintSpaces(15);
877
    } else {
1349 tk 878
      SEQ_LCD_PrintString("RECORDING      ");
879
    }
880
  } else {
881
    switch( edit_mode ) {
240 tk 882
    case SEQ_UI_EDIT_MODE_COPY: {
883
      if( ui_cursor_flash ) {
884
    SEQ_LCD_PrintSpaces(15);
885
      } else {
886
    char str_buffer[10];
887
    sprintf(str_buffer, "%d-%d", SEQ_UI_UTIL_CopyPasteBeginGet()+1, SEQ_UI_UTIL_CopyPasteEndGet()+1);
278 tk 888
    SEQ_LCD_PrintFormattedString("COPY S%-9s", str_buffer);
240 tk 889
      }
890
    } break;
167 tk 891
 
240 tk 892
    case SEQ_UI_EDIT_MODE_PASTE: {
893
      if( ui_cursor_flash ) {
894
    SEQ_LCD_PrintSpaces(15);
895
      } else {
278 tk 896
    SEQ_LCD_PrintFormattedString("PASTE OFFS.%3d ", ui_selected_step+1);
240 tk 897
      }
898
    } break;
167 tk 899
 
240 tk 900
    case SEQ_UI_EDIT_MODE_MOVE: {
901
      if( ui_cursor_flash ) {
902
    SEQ_LCD_PrintSpaces(15);
903
      } else {
278 tk 904
    SEQ_LCD_PrintString("MOVE STEPS     ");
240 tk 905
      }
906
    } break;
176 tk 907
 
240 tk 908
    case SEQ_UI_EDIT_MODE_SCROLL: {
909
      if( ui_cursor_flash ) {
910
    SEQ_LCD_PrintSpaces(15);
911
      } else {
278 tk 912
    SEQ_LCD_PrintString("SCROLL TRACK   ");
240 tk 913
      }
914
    } break;
176 tk 915
 
240 tk 916
    case SEQ_UI_EDIT_MODE_RANDOM: {
917
      if( ui_cursor_flash ) {
918
    SEQ_LCD_PrintSpaces(15);
919
      } else {
278 tk 920
    SEQ_LCD_PrintString("RANDOMIZED     ");
240 tk 921
      }
922
    } break;
176 tk 923
 
600 tk 924
    case SEQ_UI_EDIT_MODE_MANUAL: {
925
      if( ui_cursor_flash ) {
926
    SEQ_LCD_PrintSpaces(15);
927
      } else {
928
    SEQ_LCD_PrintString("MANUAL TRIGGER ");
929
      }
930
    } break;
931
 
240 tk 932
    default: {
326 tk 933
      if( event_mode == SEQ_EVENT_MODE_Drum ) {
934
    SEQ_LCD_PrintChar(' ');
935
    SEQ_LCD_PrintChar(' ');
936
    SEQ_LCD_PrintMIDIOutPort(SEQ_CC_Get(visible_track, SEQ_CC_MIDI_PORT));
937
    SEQ_LCD_PrintChar(' ');
938
    SEQ_LCD_PrintFormattedString("Chn.%2d  ", SEQ_CC_Get(visible_track, SEQ_CC_MIDI_CHANNEL)+1);
939
      } else {
940
    SEQ_LCD_PrintTrackLabel(visible_track, (char *)seq_core_trk[visible_track].name);
941
      }
942
    }
1349 tk 943
    }
326 tk 944
  }
176 tk 945
 
326 tk 946
  SEQ_LCD_PrintSpaces(2);
176 tk 947
 
326 tk 948
  SEQ_LCD_PrintChar('P');
949
  SEQ_LCD_PrintChar('A' + ui_selected_par_layer);
950
  SEQ_LCD_PrintChar(':');
240 tk 951
 
1316 tk 952
  if( layer_type == SEQ_PAR_Type_CC ) {
1811 tk 953
    if( layer_event.midi_package.cc_number >= 0x80 ) {
954
      SEQ_LCD_PrintFormattedString("CC#off ");
955
    } else {
956
      SEQ_LCD_PrintFormattedString("CC#%3d ", layer_event.midi_package.cc_number);
957
    }
333 tk 958
  } else {
959
    SEQ_LCD_PrintString(SEQ_PAR_AssignedTypeStr(visible_track, ui_selected_par_layer));
960
    SEQ_LCD_PrintSpaces(2);
176 tk 961
  }
167 tk 962
 
328 tk 963
  SEQ_LCD_PrintFormattedString("T%c:%s", 'A' + ui_selected_trg_layer, SEQ_TRG_AssignedTypeStr(visible_track, ui_selected_trg_layer));
327 tk 964
 
965
 
167 tk 966
  ///////////////////////////////////////////////////////////////////////////
278 tk 967
  SEQ_LCD_CursorSet(40, 0);
167 tk 968
 
1316 tk 969
  SEQ_LCD_PrintFormattedString("Step%3d ", ui_selected_step+1);
167 tk 970
 
1316 tk 971
  if( layer_event.midi_package.event == CC ) {
972
    mios32_midi_port_t port = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_PORT);
973
    u8 loopback = port == 0xf0;
741 tk 974
 
1316 tk 975
    if( loopback )
976
      SEQ_LCD_PrintString((char *)SEQ_CC_LABELS_Get(port, layer_event.midi_package.cc_number));
1811 tk 977
    else {
978
      if( layer_event.midi_package.cc_number >= 0x80 ) {
979
    SEQ_LCD_PrintFormattedString("  CC#off");
980
      } else {
981
    SEQ_LCD_PrintFormattedString("  CC#%3d", layer_event.midi_package.cc_number);
982
      }
983
    }
1351 tk 984
    SEQ_LCD_PrintFormattedString(" %3d ", layer_event.midi_package.value);
985
    SEQ_LCD_PrintVBar(layer_event.midi_package.value >> 4);
1316 tk 986
  } else {
987
    SEQ_LCD_PrintSpaces(2);
741 tk 988
 
1316 tk 989
    if( layer_event.midi_package.note && layer_event.midi_package.velocity && (layer_event.len >= 0) ) {
990
      if( SEQ_CC_Get(visible_track, SEQ_CC_MODE) == SEQ_CORE_TRKMODE_Arpeggiator ) {
1350 tk 991
    u8 par_value = PassiveEditValid() ? edit_passive_value : layer_event.midi_package.note;
992
    SEQ_LCD_PrintArp(par_value);
1316 tk 993
      } else if( layer_type == SEQ_PAR_Type_Chord ) {
1350 tk 994
    u8 par_value = PassiveEditValid()
995
      ? edit_passive_value
996
      : SEQ_PAR_Get(visible_track, ui_selected_step, 0, ui_selected_instrument);
997
 
1316 tk 998
    u8 chord_ix = par_value & 0x1f;
999
    u8 chord_oct = par_value >> 5;
1000
    SEQ_LCD_PrintString(SEQ_CHORD_NameGet(chord_ix));
1001
    SEQ_LCD_PrintFormattedString("/%d", chord_oct);
1002
      } else {
1350 tk 1003
    u8 par_value = PassiveEditValid() ? edit_passive_value : layer_event.midi_package.note;
1004
    SEQ_LCD_PrintNote(par_value);
288 tk 1005
      }
1351 tk 1006
      SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
176 tk 1007
    }
1316 tk 1008
    else {
1009
      SEQ_LCD_PrintString("....");
1010
    }
1011
    SEQ_LCD_PrintFormattedString(" Vel:%3d", layer_event.midi_package.velocity);
176 tk 1012
  }
167 tk 1013
 
1316 tk 1014
  SEQ_LCD_PrintString(" Len:");
1015
  SEQ_LCD_PrintGatelength(layer_event.len);
167 tk 1016
 
1316 tk 1017
 
740 tk 1018
  // print flashing *LOOPED* at right corner if loop mode activated to remind that steps will be played differntly
1019
  if( (ui_cursor_flash_overrun_ctr & 1) && seq_core_state.LOOP ) {
1020
    SEQ_LCD_PrintString(" *LOOPED*");
828 tk 1021
  } else if( (ui_cursor_flash_overrun_ctr & 1) && seq_core_trk[visible_track].play_section > 0 ) {
1022
    SEQ_LCD_PrintFormattedString(" *Sect.%c*", 'A'+seq_core_trk[visible_track].play_section);
326 tk 1023
  } else {
740 tk 1024
    SEQ_LCD_PrintSpaces(4);
1025
    if( event_mode == SEQ_EVENT_MODE_Drum ) {
1026
      SEQ_LCD_PrintTrackDrum(visible_track, ui_selected_instrument, (char *)seq_core_trk[visible_track].name);
1027
    } else {
1028
      SEQ_LCD_PrintTrackCategory(visible_track, (char *)seq_core_trk[visible_track].name);
1029
    }
180 tk 1030
  }
167 tk 1031
 
1032
  ///////////////////////////////////////////////////////////////////////////
1211 tk 1033
  // Second Line
1034
  ///////////////////////////////////////////////////////////////////////////
167 tk 1035
 
336 tk 1036
  u8 show_drum_triggers = (event_mode == SEQ_EVENT_MODE_Drum && (edit_mode || !ui_hold_msg_ctr));
335 tk 1037
 
176 tk 1038
  // extra handling for gatelength (shows vertical bars)
335 tk 1039
  if( !show_drum_triggers && layer_type == SEQ_PAR_Type_Length ) {
167 tk 1040
 
176 tk 1041
    // we want to show horizontal bars
1042
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_HBars);
167 tk 1043
 
176 tk 1044
    // initial cursor position
278 tk 1045
    SEQ_LCD_CursorSet(0, 1);
167 tk 1046
 
176 tk 1047
    // determine length of previous step (depends on selected view and track length)
1048
    int previous_step = 16*ui_selected_step_view - 1;
1049
    if( previous_step < 0 )
1050
      previous_step = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
1051
 
1052
    seq_layer_evnt_t layer_event;
336 tk 1053
    SEQ_LAYER_GetEvntOfLayer(visible_track, previous_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
176 tk 1054
    u16 previous_length = layer_event.len;
330 tk 1055
 
1056
    // show length of 16 steps
336 tk 1057
    u16 step;
330 tk 1058
    for(step=0; step<16; ++step) {
336 tk 1059
      u16 visible_step = step + 16*ui_selected_step_view;
1060
      SEQ_LAYER_GetEvntOfLayer(visible_track, visible_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
330 tk 1061
 
1143 tk 1062
      u8 gate = SEQ_TRG_GateGet(visible_track, visible_step, ui_selected_instrument);
1063
 
338 tk 1064
      // muted step? if previous gatelength <= 96, print spaces
1143 tk 1065
      if( (!gate || !layer_event.midi_package.velocity) && previous_length < 96 ) {
338 tk 1066
    SEQ_LCD_PrintSpaces(5);
1067
      } else {
1068
    if( layer_event.len >= 96 )
1069
      SEQ_LCD_PrintHBar(15); // glide or stretched event
330 tk 1070
    else
338 tk 1071
      SEQ_LCD_PrintHBar(((layer_event.len-1)*16)/100);
330 tk 1072
      }
1143 tk 1073
      previous_length = ((gate && layer_event.midi_package.velocity) || (previous_length >= 96 && layer_event.len >= 96)) ? layer_event.len : 0;
330 tk 1074
    }
1075
 
176 tk 1076
  } else {
1077
 
335 tk 1078
    if( show_drum_triggers ) {
323 tk 1079
      // we want to show triggers
325 tk 1080
      SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_DrumSymbolsBig);
323 tk 1081
    } else {
1082
      // we want to show vertical bars
1083
      SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
1084
    }
176 tk 1085
 
1086
    // initial cursor position
278 tk 1087
    SEQ_LCD_CursorSet(0, 1);
176 tk 1088
 
323 tk 1089
    int step_region_begin;
1090
    int step_region_end;
240 tk 1091
    switch( edit_mode ) {
1092
      case SEQ_UI_EDIT_MODE_COPY:
1093
    step_region_begin = SEQ_UI_UTIL_CopyPasteBeginGet();
1094
    step_region_end = SEQ_UI_UTIL_CopyPasteEndGet();
1095
    break;
1096
      case SEQ_UI_EDIT_MODE_PASTE:
1097
    step_region_begin = ui_selected_step;
1098
    step_region_end = ui_selected_step + SEQ_UI_UTIL_CopyPasteEndGet() - SEQ_UI_UTIL_CopyPasteBeginGet();
1099
    break;
1100
      case SEQ_UI_EDIT_MODE_SCROLL:
1101
    step_region_begin = ui_selected_step;
1102
    step_region_end = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
1103
    break;
1104
      default:
336 tk 1105
    step_region_begin = ui_selected_step;
1106
    step_region_end = ui_selected_step;
240 tk 1107
    }
1108
 
336 tk 1109
    u16 step;
176 tk 1110
    for(step=0; step<16; ++step) {
336 tk 1111
      u16 visible_step = step + 16*ui_selected_step_view;
240 tk 1112
 
1113
      if( ui_cursor_flash &&
1114
      edit_mode != SEQ_UI_EDIT_MODE_NORMAL &&
1115
      visible_step >= step_region_begin && visible_step <= step_region_end ) {
1116
    SEQ_LCD_PrintSpaces(5);
1117
    continue;
1118
      }
1119
 
335 tk 1120
      if( show_drum_triggers ) {
336 tk 1121
    u8 gate_accent = SEQ_TRG_Get(visible_track, visible_step, 0, ui_selected_instrument);
328 tk 1122
    if( SEQ_TRG_NumLayersGet(visible_track) >= 2 )
336 tk 1123
      gate_accent |= SEQ_TRG_Get(visible_track, visible_step, 1, ui_selected_instrument) << 1;
335 tk 1124
 
323 tk 1125
    SEQ_LCD_PrintChar(' ');
1126
    SEQ_LCD_PrintChar(' ');
327 tk 1127
    SEQ_LCD_PrintChar(gate_accent);
323 tk 1128
    SEQ_LCD_PrintChar(' ');
1129
    SEQ_LCD_PrintChar(' ');
1130
      } else {
1351 tk 1131
    int print_edit_value = (visible_step == edit_passive_step && PassiveEditValid()) ? edit_passive_value : -1;
1132
    SEQ_LCD_PrintLayerEvent(visible_track, visible_step, ui_selected_par_layer, ui_selected_instrument, 1, print_edit_value);
176 tk 1133
      }
1134
 
336 tk 1135
      if( !show_drum_triggers ) {
323 tk 1136
    SEQ_LCD_PrintChar((visible_step == step_region_end) ? '<'
1137
              : ((visible_step == (step_region_begin-1)) ? '>' : ' '));
1138
      }
240 tk 1139
 
176 tk 1140
    }
167 tk 1141
  }
1142
 
1143
  return 0; // no error
1144
}
1145
 
1146
 
1147
/////////////////////////////////////////////////////////////////////////////
240 tk 1148
// Local Display Handler function
1149
// IN: <high_prio>: if set, a high-priority LCD update is requested
1150
/////////////////////////////////////////////////////////////////////////////
1151
static s32 LCD_Handler(u8 high_prio)
1152
{
1153
  return SEQ_UI_EDIT_LCD_Handler(high_prio, SEQ_UI_EDIT_MODE_NORMAL);
1154
}
1155
 
1156
 
1157
/////////////////////////////////////////////////////////////////////////////
167 tk 1158
// Initialisation
1159
/////////////////////////////////////////////////////////////////////////////
1160
s32 SEQ_UI_EDIT_Init(u32 mode)
1161
{
1162
  // install callback routines
758 tk 1163
  SEQ_UI_InstallButtonCallback(SEQ_UI_EDIT_Button_Handler);
168 tk 1164
  SEQ_UI_InstallEncoderCallback(Encoder_Handler);
240 tk 1165
  SEQ_UI_InstallLEDCallback(SEQ_UI_EDIT_LED_Handler);
168 tk 1166
  SEQ_UI_InstallLCDCallback(LCD_Handler);
167 tk 1167
 
1142 tk 1168
  show_edit_config_page = 0;
1350 tk 1169
  edit_passive_mode = 0;
729 tk 1170
 
1142 tk 1171
  if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL )
1172
    seq_ui_edit_view = SEQ_UI_EDIT_VIEW_STEPS;
1173
 
167 tk 1174
  return 0; // no error
1175
}
178 tk 1176
 
1177
 
1178
 
1179
/////////////////////////////////////////////////////////////////////////////
1180
// help function to change/set a single encoder value
1181
// if forced_value >= 0: new value will be set to the given value
1182
// if forced_value < 0: new value will be changed via incrementer
1183
// returns >= 0 if new value has been set (value change)
1184
// returns < 0 if no change
1185
/////////////////////////////////////////////////////////////////////////////
1052 tk 1186
static s32 ChangeSingleEncValue(u8 track, u16 par_step, u16 trg_step, s32 incrementer, s32 forced_value, u8 change_gate, u8 dont_change_gate)
178 tk 1187
{
333 tk 1188
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(track, ui_selected_par_layer);
335 tk 1189
  u8 visible_track = SEQ_UI_VisibleTrackGet();
178 tk 1190
 
828 tk 1191
#if 0
1192
  // disabled in MBSEQ V4.0beta15 due to issue reported by Gridracer:
1193
  // http://midibox.org/forums/index.php?/topic/13137-midibox-seq-v4-beta-release-feedback/page__st__100
1194
 
333 tk 1195
  // if note/chord/velocity parameter: only change gate if requested
1196
  if( (layer_type == SEQ_PAR_Type_Note || layer_type == SEQ_PAR_Type_Chord || layer_type == SEQ_PAR_Type_Velocity) &&
178 tk 1197
      !change_gate &&
652 tk 1198
      !SEQ_TRG_GateGet(track, trg_step, ui_selected_instrument) )
178 tk 1199
    return -1;
828 tk 1200
#endif
178 tk 1201
 
1052 tk 1202
  if( layer_type == SEQ_PAR_Type_Probability ) {
1203
    // due to another issue reported by Gridracer:
1204
    // invert incrementer so that clockwise move increases probability
1205
    incrementer = -incrementer;
1206
  }
1207
 
1208
 
335 tk 1209
  u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
652 tk 1210
  if( event_mode == SEQ_EVENT_MODE_Drum ) {
335 tk 1211
    ui_hold_msg_ctr = 1000; // show value for 1 second
652 tk 1212
  }
335 tk 1213
 
652 tk 1214
  s32 old_value = SEQ_PAR_Get(track, par_step, ui_selected_par_layer, ui_selected_instrument);
178 tk 1215
  s32 new_value = (forced_value >= 0) ? forced_value : (old_value + incrementer);
1216
  if( new_value < 0 )
1217
    new_value = 0;
1218
  else if( new_value >= 128 )
1219
    new_value = 127;
1220
 
1143 tk 1221
  // extra for more comfortable editing of multi-note tracks:
1222
  // if assigned parameter layer is Note or Chord, and currently 0, re-start at C-3 resp. A/2
1223
  // when value is incremented
1224
  if( incrementer > 0 && forced_value < 0 && old_value == 0x00 && (layer_type == SEQ_PAR_Type_Note || layer_type == SEQ_PAR_Type_Chord) )
1225
    new_value = (layer_type == SEQ_PAR_Type_Note && SEQ_CC_Get(track, SEQ_CC_MODE) != SEQ_CORE_TRKMODE_Arpeggiator) ? 0x3c : 0x40;
1226
 
1345 tk 1227
  if( !dont_change_gate ) {
1228
    u8 event_mode = SEQ_CC_Get(track, SEQ_CC_MIDI_EVENT_MODE);
1229
 
1230
    // we do this always regardless if value has been changed or not (e.g. increment if value already 127)
1231
    if( event_mode == SEQ_EVENT_MODE_CC && layer_type == SEQ_PAR_Type_CC ) {
1232
      // in this mode gates are used to disable CC
1233
      // if a CC value has been changed, set gate
1234
      SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 1);
1235
    }
1236
  }
1237
 
178 tk 1238
  // take over if changed
1239
  if( new_value == old_value )
1240
    return -1;
1241
 
652 tk 1242
  SEQ_PAR_Set(track, par_step, ui_selected_par_layer, ui_selected_instrument, (u8)new_value);
178 tk 1243
 
747 tk 1244
  if( !dont_change_gate &&
1245
      (layer_type == SEQ_PAR_Type_Note || layer_type == SEQ_PAR_Type_Chord || layer_type == SEQ_PAR_Type_Velocity) ) {
178 tk 1246
    // (de)activate gate depending on value
1247
    if( new_value )
652 tk 1248
      SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 1);
1053 tk 1249
    else {
1250
      // due to another issue reported by Gridracer:
1251
      // if the track plays multiple notes, only clear gate if all notes are 0
1142 tk 1252
      u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
1053 tk 1253
      u8 allNotesZero = 1;
1254
      int i;
1142 tk 1255
      for(i=0; i<num_p_layers; ++i) {
1053 tk 1256
    seq_par_layer_type_t localLayerType = SEQ_PAR_AssignmentGet(track, i);
1257
    if( (localLayerType == SEQ_PAR_Type_Note || localLayerType == SEQ_PAR_Type_Chord) &&
1258
        SEQ_PAR_Get(track, par_step, i, ui_selected_instrument) > 0 ) {
1259
      allNotesZero = 0;
1260
      break;
1261
    }
1262
      }
1263
 
1264
      if( allNotesZero )
1265
    SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 0);
1266
    }
178 tk 1267
  }
1268
 
1269
  return new_value;
1270
}
1350 tk 1271
 
1272
 
1273
/////////////////////////////////////////////////////////////////////////////
1274
// help functions for "passive edit mode"
1275
/////////////////////////////////////////////////////////////////////////////
1276
static s32 PassiveEditEnter(void)
1277
{
1278
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1351 tk 1279
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer);
1350 tk 1280
 
1351 tk 1281
  // passive edit mode currently only supported for notes/chords
1350 tk 1282
 
1351 tk 1283
  if( layer_type == SEQ_PAR_Type_Note || layer_type == SEQ_PAR_Type_Chord ) {
1284
    // enter passive edit mode and store track/step/layer/instrument for later checks
1285
    edit_passive_mode = 1;
1286
    edit_passive_track = visible_track;
1287
    edit_passive_step = ui_selected_step;
1288
    edit_passive_par_layer = ui_selected_par_layer;
1289
    edit_passive_instrument = ui_selected_instrument;
1290
    edit_passive_value = SEQ_PAR_Get(edit_passive_track, edit_passive_step, edit_passive_par_layer, edit_passive_instrument);
1291
  } else {
1292
    edit_passive_mode = 0;
1293
  }
1294
 
1350 tk 1295
  return 0; // no error
1296
}
1297
 
1298
static s32 PassiveEditValid(void)
1299
{
1300
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1301
 
1302
  return (edit_passive_mode == 2 && // if mode is 2, the value has been changed!
1303
      edit_passive_track == visible_track &&
1304
      edit_passive_step == ui_selected_step &&
1305
      edit_passive_par_layer == ui_selected_par_layer &&
1306
      edit_passive_instrument == ui_selected_instrument) ? 1 : 0;
1307
}
1308
 
1309
static s32 PassiveEditTakeOver(void)
1310
{
1311
 
1312
  // only take over changed value if track/step/layer/instrument still passing
1313
  if( PassiveEditValid() ) {
1314
    // take over change
1315
    // handle it like a single increment/decrement so that no code needs to be duplicated
1316
    int current_value = SEQ_PAR_Get(edit_passive_track, edit_passive_step, edit_passive_par_layer, edit_passive_instrument);
1317
    int incrementer = (int)edit_passive_value - current_value;
1318
 
1319
    show_edit_config_page = 0; // just to avoid any overlay...
1320
    edit_passive_mode = 0; // to avoid recursion in encoder handler
1321
    Encoder_Handler(edit_passive_step % 16, incrementer);
1322
  } else {
1323
    edit_passive_mode = 1;
1324
  }
1325
 
1326
  return 0; // no error
1327
}