Subversion Repositories svn.mios32

Rev

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