Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
134 tk 1
// $Id: seq_ui.c 173 2008-12-09 22:45:19Z tk $
2
/*
3
 * User Interface Routines
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
 
20
#if DEFAULT_SRM_ENABLED
21
#include <blm8x8.h>
22
#endif
23
 
24
#include "seq_ui.h"
25
#include "seq_lcd.h"
26
#include "seq_led.h"
27
#include "seq_midi.h"
159 tk 28
#include "seq_bpm.h"
134 tk 29
#include "seq_core.h"
30
#include "seq_par.h"
31
#include "seq_trg.h"
32
 
33
 
34
/////////////////////////////////////////////////////////////////////////////
35
// Local types
36
/////////////////////////////////////////////////////////////////////////////
37
 
38
 
39
/////////////////////////////////////////////////////////////////////////////
40
// Local prototypes
41
/////////////////////////////////////////////////////////////////////////////
42
 
43
 
44
/////////////////////////////////////////////////////////////////////////////
45
// Global variables
46
/////////////////////////////////////////////////////////////////////////////
47
 
159 tk 48
u8 seq_ui_display_update_req;
49
u8 seq_ui_display_init_req;
134 tk 50
 
167 tk 51
seq_ui_button_state_t seq_ui_button_state;
52
 
134 tk 53
u8 ui_selected_group;
54
u8 ui_selected_tracks;
55
u8 ui_selected_par_layer;
56
u8 ui_selected_trg_layer;
57
u8 ui_selected_step_view;
58
u8 ui_selected_step;
168 tk 59
u8 ui_selected_item;
134 tk 60
 
168 tk 61
u8 ui_selected_item;
134 tk 62
 
173 tk 63
volatile u8 ui_cursor_flash;
64
u16 ui_cursor_flash_ctr;
134 tk 65
 
66
/////////////////////////////////////////////////////////////////////////////
67
// Local variables
68
/////////////////////////////////////////////////////////////////////////////
69
 
167 tk 70
// Note: must be kept in sync with SEQ_UI_PAGE_xxx definitions in seq_ui.h!
71
static const s32 (*ui_init_callback[SEQ_UI_PAGES])(u32 mode) = {
72
  (void *)&SEQ_UI_TODO_Init,    // 0
73
  (void *)&SEQ_UI_EDIT_Init,    // 1
173 tk 74
  (void *)&SEQ_UI_TRKDIR_Init,  // 2
75
  (void *)&SEQ_UI_TRKDIV_Init,  // 3
76
  (void *)&SEQ_UI_TRKLEN_Init   // 4
167 tk 77
};
134 tk 78
 
168 tk 79
static s32 (*ui_button_callback)(seq_ui_button_t button, s32 depressed);
80
static s32 (*ui_encoder_callback)(seq_ui_encoder_t encoder, s32 incrementer);
173 tk 81
static s32 (*ui_led_callback)(u16 *gp_leds);
167 tk 82
static s32 (*ui_lcd_callback)(u8 high_prio);
83
 
84
static seq_ui_page_t ui_page;
85
 
86
 
87
// following pages are directly accessible with the GP buttons when MENU button is pressed
88
static const seq_ui_page_t ui_direct_access_menu_pages[16] = {
89
  SEQ_UI_PAGE_NONE,        // GP1
90
  SEQ_UI_PAGE_NONE,        // GP2
91
  SEQ_UI_PAGE_NONE,        // GP3
92
  SEQ_UI_PAGE_TRKDIR,      // GP4
173 tk 93
  SEQ_UI_PAGE_TRKDIV,      // GP5
94
  SEQ_UI_PAGE_TRKLEN,      // GP6
167 tk 95
  SEQ_UI_PAGE_NONE,        // GP7
96
  SEQ_UI_PAGE_NONE,        // GP8
97
  SEQ_UI_PAGE_NONE,        // GP9
98
  SEQ_UI_PAGE_NONE,        // GP10
99
  SEQ_UI_PAGE_NONE,        // GP11
100
  SEQ_UI_PAGE_NONE,        // GP12
101
  SEQ_UI_PAGE_NONE,        // GP13
102
  SEQ_UI_PAGE_NONE,        // GP14
103
  SEQ_UI_PAGE_NONE,        // GP15
104
  SEQ_UI_PAGE_NONE         // GP16
105
};
106
 
168 tk 107
static u16 ui_gp_leds;
167 tk 108
 
168 tk 109
 
134 tk 110
/////////////////////////////////////////////////////////////////////////////
111
// Initialisation
112
/////////////////////////////////////////////////////////////////////////////
113
s32 SEQ_UI_Init(u32 mode)
114
{
115
  // init selection variables
116
  ui_selected_group = 0;
117
  ui_selected_tracks = (1 << 0);
118
  ui_selected_par_layer = 0;
119
  ui_selected_trg_layer = 0;
120
  ui_selected_step_view = 0;
121
  ui_selected_step = 0;
168 tk 122
  ui_selected_item = 0;
134 tk 123
 
168 tk 124
  ui_cursor_flash_ctr = 0;
173 tk 125
  ui_cursor_flash = 0;
168 tk 126
 
167 tk 127
  seq_ui_button_state.ALL = 0;
128
 
134 tk 129
  // visible GP pattern
130
  ui_gp_leds = 0x0000;
131
 
167 tk 132
  // change to edit page
133
  ui_page = SEQ_UI_PAGE_NONE;
134
  SEQ_UI_PageSet(SEQ_UI_PAGE_EDIT);
134 tk 135
 
136
  return 0; // no error
137
}
138
 
139
 
140
/////////////////////////////////////////////////////////////////////////////
167 tk 141
// Various installation routines for menu page LCD handlers
142
/////////////////////////////////////////////////////////////////////////////
168 tk 143
s32 SEQ_UI_InstallButtonCallback(void *callback)
167 tk 144
{
168 tk 145
  ui_button_callback = callback;
167 tk 146
  return 0; // no error
147
}
148
 
168 tk 149
s32 SEQ_UI_InstallEncoderCallback(void *callback)
167 tk 150
{
168 tk 151
  ui_encoder_callback = callback;
167 tk 152
  return 0; // no error
153
}
154
 
168 tk 155
s32 SEQ_UI_InstallLEDCallback(void *callback)
167 tk 156
{
168 tk 157
  ui_led_callback = callback;
167 tk 158
  return 0; // no error
159
}
160
 
168 tk 161
s32 SEQ_UI_InstallLCDCallback(void *callback)
167 tk 162
{
163
  ui_lcd_callback = callback;
164
  return 0; // no error
165
}
166
 
167
 
168
/////////////////////////////////////////////////////////////////////////////
169
// Change the menu page
170
/////////////////////////////////////////////////////////////////////////////
171
s32 SEQ_UI_PageSet(seq_ui_page_t page)
172
{
173
  if( page != ui_page ) {
174
    // disable hooks of previous page and request re-initialisation
175
    MIOS32_IRQ_Disable();
176
    ui_page = page;
168 tk 177
    ui_button_callback = NULL;
178
    ui_encoder_callback = NULL;
179
    ui_led_callback = NULL;
167 tk 180
    ui_lcd_callback = NULL;
181
    MIOS32_IRQ_Enable();
182
 
183
  // TODO: define generic #define for this button behaviour
184
#if defined(MIOS32_FAMILY_EMULATION)
168 tk 185
    seq_ui_button_state.MENU_PRESSED = 0; // MENU page selection finished
167 tk 186
#endif
187
 
188
    // request display initialisation
189
    seq_ui_display_init_req = 1;
190
  }
173 tk 191
 
192
  // don't display menu page anymore (only first time when menu button has been pressed)
193
  seq_ui_button_state.MENU_PAGE_DISPLAYED = 0;
167 tk 194
}
195
 
196
 
197
/////////////////////////////////////////////////////////////////////////////
134 tk 198
// Dedicated button functions
199
// Mapped to physical buttons in SEQ_UI_Button_Handler()
200
// Will also be mapped to MIDI keys later (for MIDI remote function)
201
/////////////////////////////////////////////////////////////////////////////
202
static s32 SEQ_UI_Button_GP(s32 depressed, u32 gp)
203
{
204
  if( depressed ) return -1; // ignore when button depressed
205
 
167 tk 206
  if( seq_ui_button_state.MENU_PRESSED ) {
207
    // MENU button overruling - select menu page
208
    SEQ_UI_PageSet(ui_direct_access_menu_pages[gp]);
209
  } else {
210
    // forward to menu page
168 tk 211
    if( ui_button_callback != NULL )
212
      ui_button_callback(gp, depressed);
173 tk 213
    ui_cursor_flash_ctr = 0;
167 tk 214
  }
134 tk 215
 
216
  return 0; // no error
217
}
218
 
219
static s32 SEQ_UI_Button_Left(s32 depressed)
220
{
168 tk 221
  // forward to menu page
222
  if( ui_button_callback != NULL )
223
    ui_button_callback(SEQ_UI_BUTTON_Left, depressed);
173 tk 224
  ui_cursor_flash_ctr = 0;
134 tk 225
 
226
  return 0; // no error
227
}
228
 
229
static s32 SEQ_UI_Button_Right(s32 depressed)
230
{
168 tk 231
  // forward to menu page
232
  if( ui_button_callback != NULL )
233
    ui_button_callback(SEQ_UI_BUTTON_Right, depressed);
173 tk 234
  ui_cursor_flash_ctr = 0;
134 tk 235
 
236
  return 0; // no error
237
}
238
 
168 tk 239
static s32 SEQ_UI_Button_Down(s32 depressed)
240
{
241
  // forward to menu page
242
  if( ui_button_callback != NULL )
243
    ui_button_callback(SEQ_UI_BUTTON_Down, depressed);
173 tk 244
  ui_cursor_flash_ctr = 0;
168 tk 245
 
246
  return 0; // no error
247
}
248
 
249
static s32 SEQ_UI_Button_Up(s32 depressed)
250
{
251
  // forward to menu page
252
  if( ui_button_callback != NULL )
253
    ui_button_callback(SEQ_UI_BUTTON_Up, depressed);
173 tk 254
  ui_cursor_flash_ctr = 0;
168 tk 255
 
256
  return 0; // no error
257
}
258
 
134 tk 259
static s32 SEQ_UI_Button_Scrub(s32 depressed)
260
{
137 tk 261
#if 0
134 tk 262
  if( depressed ) return -1; // ignore when button depressed
137 tk 263
#else
264
  // Sending SysEx Stream test
265
  u8 buffer[7] = { 0xf0, 0x11, 0x22, 0x33, 0x44, depressed ? 0x00 : 0x55, 0xf7 };
134 tk 266
 
137 tk 267
  MIOS32_MIDI_SendSysEx(DEFAULT, buffer, 7);
268
#endif
269
 
134 tk 270
  return 0; // no error
271
}
272
 
273
static s32 SEQ_UI_Button_Metronome(s32 depressed)
274
{
137 tk 275
#if 0
134 tk 276
  if( depressed ) return -1; // ignore when button depressed
137 tk 277
#else
278
  // Sending MIDI Note test
279
  if( depressed )
280
    MIOS32_MIDI_SendNoteOff(DEFAULT, 0x90, 0x3c, 0x00);
281
  else
282
    MIOS32_MIDI_SendNoteOn(DEFAULT, 0x90, 0x3c, 0x7f);
283
#endif
134 tk 284
 
285
  return 0; // no error
286
}
287
 
288
static s32 SEQ_UI_Button_Stop(s32 depressed)
289
{
290
  if( depressed ) return -1; // ignore when button depressed
291
 
159 tk 292
  // if sequencer running: stop it
293
  // if sequencer already stopped: reset song position
166 tk 294
  if( seq_core_state.RUN )
159 tk 295
    SEQ_CORE_Stop(0);
296
  else
297
    SEQ_CORE_Reset();
298
 
134 tk 299
  return 0; // no error
300
}
301
 
302
static s32 SEQ_UI_Button_Pause(s32 depressed)
303
{
304
  if( depressed ) return -1; // ignore when button depressed
305
 
159 tk 306
  // pause sequencer
307
  SEQ_CORE_Pause(0);
308
 
134 tk 309
  return 0; // no error
310
}
311
 
312
static s32 SEQ_UI_Button_Play(s32 depressed)
313
{
314
  if( depressed ) return -1; // ignore when button depressed
315
 
159 tk 316
  // start sequencer
317
  SEQ_CORE_Start(0);
318
 
134 tk 319
  return 0; // no error
320
}
321
 
322
static s32 SEQ_UI_Button_Rew(s32 depressed)
323
{
324
  if( depressed ) return -1; // ignore when button depressed
325
 
326
  return 0; // no error
327
}
328
 
329
static s32 SEQ_UI_Button_Fwd(s32 depressed)
330
{
331
  if( depressed ) return -1; // ignore when button depressed
332
 
333
  return 0; // no error
334
}
335
 
336
static s32 SEQ_UI_Button_F1(s32 depressed)
337
{
338
  if( depressed ) return -1; // ignore when button depressed
339
 
340
  return 0; // no error
341
}
342
 
343
static s32 SEQ_UI_Button_F2(s32 depressed)
344
{
345
  if( depressed ) return -1; // ignore when button depressed
346
 
347
  return 0; // no error
348
}
349
 
350
static s32 SEQ_UI_Button_F3(s32 depressed)
351
{
352
  if( depressed ) return -1; // ignore when button depressed
353
 
354
  return 0; // no error
355
}
356
 
357
static s32 SEQ_UI_Button_F4(s32 depressed)
358
{
359
  if( depressed ) return -1; // ignore when button depressed
360
 
361
  return 0; // no error
362
}
363
 
364
static s32 SEQ_UI_Button_Utility(s32 depressed)
365
{
366
  if( depressed ) return -1; // ignore when button depressed
367
 
368
  return 0; // no error
369
}
370
 
371
static s32 SEQ_UI_Button_Copy(s32 depressed)
372
{
373
  if( depressed ) return -1; // ignore when button depressed
374
 
375
  return 0; // no error
376
}
377
 
378
static s32 SEQ_UI_Button_Paste(s32 depressed)
379
{
380
  if( depressed ) return -1; // ignore when button depressed
381
 
382
  return 0; // no error
383
}
384
 
385
static s32 SEQ_UI_Button_Clear(s32 depressed)
386
{
387
  if( depressed ) return -1; // ignore when button depressed
388
 
389
  return 0; // no error
390
}
391
 
392
static s32 SEQ_UI_Button_Menu(s32 depressed)
393
{
167 tk 394
  // TODO: define generic #define for this button behaviour
395
#if defined(MIOS32_FAMILY_EMULATION)
134 tk 396
  if( depressed ) return -1; // ignore when button depressed
167 tk 397
  seq_ui_button_state.MENU_PRESSED ^= 1; // toggle MENU pressed (will also be released once GP button has been pressed)
398
#else
399
  seq_ui_button_state.MENU_PRESSED = depressed ? 0 : 1;
400
#endif
134 tk 401
 
168 tk 402
  seq_ui_button_state.MENU_PAGE_DISPLAYED = seq_ui_button_state.MENU_PRESSED;
403
 
134 tk 404
  return 0; // no error
405
}
406
 
407
static s32 SEQ_UI_Button_Select(s32 depressed)
408
{
168 tk 409
  // forward to menu page
410
  if( ui_button_callback != NULL )
411
    ui_button_callback(SEQ_UI_BUTTON_Select, depressed);
173 tk 412
  ui_cursor_flash_ctr = 0;
134 tk 413
 
414
  return 0; // no error
415
}
416
 
417
static s32 SEQ_UI_Button_Exit(s32 depressed)
418
{
168 tk 419
  // forward to menu page
420
  if( ui_button_callback != NULL )
421
    ui_button_callback(SEQ_UI_BUTTON_Exit, depressed);
173 tk 422
  ui_cursor_flash_ctr = 0;
134 tk 423
 
167 tk 424
  // release all button states
425
  seq_ui_button_state.ALL = 0;
426
 
134 tk 427
  return 0; // no error
428
}
429
 
430
static s32 SEQ_UI_Button_Edit(s32 depressed)
431
{
432
  if( depressed ) return -1; // ignore when button depressed
433
 
167 tk 434
  // change to edit page
435
  SEQ_UI_PageSet(SEQ_UI_PAGE_EDIT);
436
 
134 tk 437
  return 0; // no error
438
}
439
 
440
static s32 SEQ_UI_Button_Mute(s32 depressed)
441
{
442
  if( depressed ) return -1; // ignore when button depressed
443
 
444
  return 0; // no error
445
}
446
 
447
static s32 SEQ_UI_Button_Pattern(s32 depressed)
448
{
449
  if( depressed ) return -1; // ignore when button depressed
450
 
451
  return 0; // no error
452
}
453
 
454
static s32 SEQ_UI_Button_Song(s32 depressed)
455
{
456
  if( depressed ) return -1; // ignore when button depressed
457
 
458
  return 0; // no error
459
}
460
 
461
static s32 SEQ_UI_Button_Solo(s32 depressed)
462
{
463
  if( depressed ) return -1; // ignore when button depressed
464
 
465
  return 0; // no error
466
}
467
 
468
static s32 SEQ_UI_Button_Fast(s32 depressed)
469
{
470
  if( depressed ) return -1; // ignore when button depressed
471
 
472
  return 0; // no error
473
}
474
 
475
static s32 SEQ_UI_Button_All(s32 depressed)
476
{
477
  if( depressed ) return -1; // ignore when button depressed
478
 
479
  return 0; // no error
480
}
481
 
482
static s32 SEQ_UI_Button_StepView(s32 depressed)
483
{
484
  if( depressed ) return -1; // ignore when button depressed
485
 
486
  ui_selected_step_view = ui_selected_step_view ? 0 : 1;
487
 
488
  return 0; // no error
489
}
490
 
491
static s32 SEQ_UI_Button_TapTempo(s32 depressed)
492
{
493
  if( depressed ) return -1; // ignore when button depressed
494
 
495
  return 0; // no error
496
}
497
 
498
static s32 SEQ_UI_Button_Track(s32 depressed, u32 track)
499
{
500
  if( depressed ) return -1; // ignore when button depressed
501
 
502
  if( track >= 4 ) return -2; // max. 4 track buttons
503
 
504
  ui_selected_tracks = (1 << track); // TODO: multi-selections!
505
 
506
  return 0; // no error
507
}
508
 
509
static s32 SEQ_UI_Button_Group(s32 depressed, u32 group)
510
{
511
  if( depressed ) return -1; // ignore when button depressed
512
 
513
  if( group >= 4 ) return -2; // max. 4 group buttons
514
 
515
  ui_selected_group = group;
516
 
517
  return 0; // no error
518
}
519
 
520
static s32 SEQ_UI_Button_ParLayer(s32 depressed, u32 par_layer)
521
{
522
  if( depressed ) return -1; // ignore when button depressed
523
 
524
  if( par_layer >= 3 ) return -2; // max. 3 parlayer buttons
525
 
526
  ui_selected_par_layer = par_layer;
527
 
528
  return 0; // no error
529
}
530
 
531
static s32 SEQ_UI_Button_TrgLayer(s32 depressed, u32 trg_layer)
532
{
533
  if( depressed ) return -1; // ignore when button depressed
534
 
535
  if( trg_layer >= 3 ) return -2; // max. 3 trglayer buttons
536
 
537
  ui_selected_trg_layer = trg_layer;
538
 
539
  return 0; // no error
540
}
541
 
542
 
543
 
544
/////////////////////////////////////////////////////////////////////////////
545
// Button handler
546
/////////////////////////////////////////////////////////////////////////////
547
s32 SEQ_UI_Button_Handler(u32 pin, u32 pin_value)
548
{
549
  switch( pin ) {
168 tk 550
#if BUTTON_GP1 != BUTTON_DISABLED
134 tk 551
    case BUTTON_GP1:   SEQ_UI_Button_GP(pin_value, 0); break;
552
#endif
168 tk 553
#if BUTTON_GP2 != BUTTON_DISABLED
134 tk 554
    case BUTTON_GP2:   SEQ_UI_Button_GP(pin_value, 1); break;
555
#endif
168 tk 556
#if BUTTON_GP3 != BUTTON_DISABLED
134 tk 557
    case BUTTON_GP3:   SEQ_UI_Button_GP(pin_value, 2); break;
558
#endif
168 tk 559
#if BUTTON_GP4 != BUTTON_DISABLED
134 tk 560
    case BUTTON_GP4:   SEQ_UI_Button_GP(pin_value, 3); break;
561
#endif
168 tk 562
#if BUTTON_GP5 != BUTTON_DISABLED
134 tk 563
    case BUTTON_GP5:   SEQ_UI_Button_GP(pin_value, 4); break;
564
#endif
168 tk 565
#if BUTTON_GP6 != BUTTON_DISABLED
134 tk 566
    case BUTTON_GP6:   SEQ_UI_Button_GP(pin_value, 5); break;
567
#endif
168 tk 568
#if BUTTON_GP7 != BUTTON_DISABLED
134 tk 569
    case BUTTON_GP7:   SEQ_UI_Button_GP(pin_value, 6); break;
570
#endif
168 tk 571
#if BUTTON_GP8 != BUTTON_DISABLED
134 tk 572
    case BUTTON_GP8:   SEQ_UI_Button_GP(pin_value, 7); break;
573
#endif
168 tk 574
#if BUTTON_GP9 != BUTTON_DISABLED
134 tk 575
    case BUTTON_GP9:   SEQ_UI_Button_GP(pin_value, 8); break;
576
#endif
168 tk 577
#if BUTTON_GP10 != BUTTON_DISABLED
134 tk 578
    case BUTTON_GP10:  SEQ_UI_Button_GP(pin_value, 9); break;
579
#endif
168 tk 580
#if BUTTON_GP11 != BUTTON_DISABLED
134 tk 581
    case BUTTON_GP11:  SEQ_UI_Button_GP(pin_value, 10); break;
582
#endif
168 tk 583
#if BUTTON_GP12 != BUTTON_DISABLED
134 tk 584
    case BUTTON_GP12:  SEQ_UI_Button_GP(pin_value, 11); break;
585
#endif
168 tk 586
#if BUTTON_GP13 != BUTTON_DISABLED
134 tk 587
    case BUTTON_GP13:  SEQ_UI_Button_GP(pin_value, 12); break;
588
#endif
168 tk 589
#if BUTTON_GP14 != BUTTON_DISABLED
134 tk 590
    case BUTTON_GP14:  SEQ_UI_Button_GP(pin_value, 13); break;
591
#endif
168 tk 592
#if BUTTON_GP15 != BUTTON_DISABLED
134 tk 593
    case BUTTON_GP15:  SEQ_UI_Button_GP(pin_value, 14); break;
594
#endif
168 tk 595
#if BUTTON_GP16 != BUTTON_DISABLED
134 tk 596
    case BUTTON_GP16:  SEQ_UI_Button_GP(pin_value, 15); break;
597
#endif
598
 
168 tk 599
#if BUTTON_LEFT != BUTTON_DISABLED
134 tk 600
    case BUTTON_LEFT:  SEQ_UI_Button_Left(pin_value); break;
601
#endif
168 tk 602
#if BUTTON_RIGHT != BUTTON_DISABLED
134 tk 603
    case BUTTON_RIGHT: SEQ_UI_Button_Right(pin_value); break;
604
#endif
605
 
168 tk 606
#if BUTTON_DOWN != BUTTON_DISABLED
607
    case BUTTON_DOWN:  SEQ_UI_Button_Down(pin_value); break;
608
#endif
609
#if BUTTON_UP != BUTTON_DISABLED
610
    case BUTTON_UP:    SEQ_UI_Button_Up(pin_value); break;
611
#endif
612
 
613
#if BUTTON_SCRUB != BUTTON_DISABLED
134 tk 614
    case BUTTON_SCRUB: SEQ_UI_Button_Scrub(pin_value); break;
615
#endif
168 tk 616
#if BUTTON_METRONOME != BUTTON_DISABLED
134 tk 617
    case BUTTON_METRONOME: SEQ_UI_Button_Metronome(pin_value); break;
618
#endif
619
 
168 tk 620
#if BUTTON_STOP != BUTTON_DISABLED
134 tk 621
    case BUTTON_STOP:  SEQ_UI_Button_Stop(pin_value); break;
622
#endif
168 tk 623
#if BUTTON_PAUSE != BUTTON_DISABLED
134 tk 624
    case BUTTON_PAUSE: SEQ_UI_Button_Pause(pin_value); break;
625
#endif
168 tk 626
#if BUTTON_PLAY != BUTTON_DISABLED
134 tk 627
    case BUTTON_PLAY:  SEQ_UI_Button_Play(pin_value); break;
628
#endif
168 tk 629
#if BUTTON_REW != BUTTON_DISABLED
134 tk 630
    case BUTTON_REW:   SEQ_UI_Button_Rew(pin_value); break;
631
#endif
168 tk 632
#if BUTTON_FWD != BUTTON_DISABLED
134 tk 633
    case BUTTON_FWD:   SEQ_UI_Button_Fwd(pin_value); break;
634
#endif
635
 
168 tk 636
#if BUTTON_F1 != BUTTON_DISABLED
134 tk 637
    case BUTTON_F1:    SEQ_UI_Button_F1(pin_value); break;
638
#endif
168 tk 639
#if BUTTON_F2 != BUTTON_DISABLED
134 tk 640
    case BUTTON_F2:    SEQ_UI_Button_F2(pin_value); break;
641
#endif
168 tk 642
#if BUTTON_F3 != BUTTON_DISABLED
134 tk 643
    case BUTTON_F3:    SEQ_UI_Button_F3(pin_value); break;
644
#endif
168 tk 645
#if BUTTON_F4 != BUTTON_DISABLED
134 tk 646
    case BUTTON_F4:    SEQ_UI_Button_F4(pin_value); break;
647
#endif
648
 
168 tk 649
#if BUTTON_UTILITY != BUTTON_DISABLED
134 tk 650
    case BUTTON_UTILITY: SEQ_UI_Button_Utility(pin_value); break;
651
#endif
168 tk 652
#if BUTTON_COPY != BUTTON_DISABLED
134 tk 653
    case BUTTON_COPY:  SEQ_UI_Button_Copy(pin_value); break;
654
#endif
168 tk 655
#if BUTTON_PASTE != BUTTON_DISABLED
134 tk 656
    case BUTTON_PASTE: SEQ_UI_Button_Paste(pin_value); break;
657
#endif
168 tk 658
#if BUTTON_CLEAR != BUTTON_DISABLED
134 tk 659
    case BUTTON_CLEAR: SEQ_UI_Button_Clear(pin_value); break;
660
#endif
661
 
168 tk 662
#if BUTTON_MENU != BUTTON_DISABLED
134 tk 663
    case BUTTON_MENU:  SEQ_UI_Button_Menu(pin_value); break;
664
#endif
168 tk 665
#if BUTTON_SELECT != BUTTON_DISABLED
134 tk 666
    case BUTTON_SELECT:SEQ_UI_Button_Select(pin_value); break;
667
#endif
168 tk 668
#if BUTTON_EXIT != BUTTON_DISABLED
134 tk 669
    case BUTTON_EXIT:  SEQ_UI_Button_Exit(pin_value); break;
670
#endif
671
 
168 tk 672
#if BUTTON_TRACK1 != BUTTON_DISABLED
134 tk 673
    case BUTTON_TRACK1: SEQ_UI_Button_Track(pin_value, 0); break;
674
#endif
168 tk 675
#if BUTTON_TRACK2 != BUTTON_DISABLED
134 tk 676
    case BUTTON_TRACK2: SEQ_UI_Button_Track(pin_value, 1); break;
677
#endif
168 tk 678
#if BUTTON_TRACK3 != BUTTON_DISABLED
134 tk 679
    case BUTTON_TRACK3: SEQ_UI_Button_Track(pin_value, 2); break;
680
#endif
168 tk 681
#if BUTTON_TRACK4 != BUTTON_DISABLED
134 tk 682
    case BUTTON_TRACK4: SEQ_UI_Button_Track(pin_value, 3); break;
683
#endif
684
 
168 tk 685
#if BUTTON_PAR_LAYER_A != BUTTON_DISABLED
134 tk 686
    case BUTTON_PAR_LAYER_A: SEQ_UI_Button_ParLayer(pin_value, 0); break;
687
#endif
168 tk 688
#if BUTTON_PAR_LAYER_B != BUTTON_DISABLED
134 tk 689
    case BUTTON_PAR_LAYER_B: SEQ_UI_Button_ParLayer(pin_value, 1); break;
690
#endif
168 tk 691
#if BUTTON_PAR_LAYER_C != BUTTON_DISABLED
134 tk 692
    case BUTTON_PAR_LAYER_C: SEQ_UI_Button_ParLayer(pin_value, 2); break;
693
#endif
694
 
168 tk 695
#if BUTTON_EDIT != BUTTON_DISABLED
134 tk 696
    case BUTTON_EDIT:   SEQ_UI_Button_Edit(pin_value); break;
697
#endif
168 tk 698
#if BUTTON_MUTE != BUTTON_DISABLED
134 tk 699
    case BUTTON_MUTE:   SEQ_UI_Button_Mute(pin_value); break;
700
#endif
168 tk 701
#if BUTTON_PATTERN != BUTTON_DISABLED
134 tk 702
    case BUTTON_PATTERN:SEQ_UI_Button_Pattern(pin_value); break;
703
#endif
168 tk 704
#if BUTTON_SONG != BUTTON_DISABLED
134 tk 705
    case BUTTON_SONG:   SEQ_UI_Button_Song(pin_value); break;
706
#endif
707
 
168 tk 708
#if BUTTON_SOLO != BUTTON_DISABLED
134 tk 709
    case BUTTON_SOLO:   SEQ_UI_Button_Solo(pin_value); break;
710
#endif
168 tk 711
#if BUTTON_FAST != BUTTON_DISABLED
134 tk 712
    case BUTTON_FAST:   SEQ_UI_Button_Fast(pin_value); break;
713
#endif
168 tk 714
#if BUTTON_ALL != BUTTON_DISABLED
134 tk 715
    case BUTTON_ALL:    SEQ_UI_Button_All(pin_value); break;
716
#endif
717
 
168 tk 718
#if BUTTON_GROUP1 != BUTTON_DISABLED
134 tk 719
    case BUTTON_GROUP1: SEQ_UI_Button_Group(pin_value, 0); break;
720
#endif
168 tk 721
#if BUTTON_GROUP2 != BUTTON_DISABLED
134 tk 722
    case BUTTON_GROUP2: SEQ_UI_Button_Group(pin_value, 1); break;
723
#endif
168 tk 724
#if BUTTON_GROUP3 != BUTTON_DISABLED
134 tk 725
    case BUTTON_GROUP3: SEQ_UI_Button_Group(pin_value, 2); break;
726
#endif
168 tk 727
#if BUTTON_GROUP4 != BUTTON_DISABLED
134 tk 728
    case BUTTON_GROUP4: SEQ_UI_Button_Group(pin_value, 3); break;
729
#endif
730
 
168 tk 731
#if BUTTON_TRG_LAYER_A != BUTTON_DISABLED
134 tk 732
    case BUTTON_TRG_LAYER_A: SEQ_UI_Button_TrgLayer(pin_value, 0); break;
733
#endif
168 tk 734
#if BUTTON_TRG_LAYER_B != BUTTON_DISABLED
134 tk 735
    case BUTTON_TRG_LAYER_B: SEQ_UI_Button_TrgLayer(pin_value, 1); break;
736
#endif
168 tk 737
#if BUTTON_TRG_LAYER_C != BUTTON_DISABLED
134 tk 738
    case BUTTON_TRG_LAYER_C: SEQ_UI_Button_TrgLayer(pin_value, 2); break;
739
#endif
740
 
168 tk 741
#if BUTTON_STEP_VIEW != BUTTON_DISABLED
134 tk 742
    case BUTTON_STEP_VIEW: SEQ_UI_Button_StepView(pin_value); break;
743
#endif
744
 
168 tk 745
#if BUTTON_TAP_TEMPO != BUTTON_DISABLED
134 tk 746
    case BUTTON_TAP_TEMPO:   SEQ_UI_Button_TapTempo(pin_value); break;
747
#endif
748
 
749
    default:
750
      return -1; // button function not mapped to physical button
751
  }
752
 
753
  // request display update
159 tk 754
  seq_ui_display_update_req = 1;
134 tk 755
 
756
  return 0; // no error
757
}
758
 
759
 
760
/////////////////////////////////////////////////////////////////////////////
761
// Encoder handler
762
/////////////////////////////////////////////////////////////////////////////
763
s32 SEQ_UI_Encoder_Handler(u32 encoder, s32 incrementer)
764
{
765
  if( encoder > 16 )
766
    return -1; // encoder doesn't exist
767
 
768
  // limit incrementer
769
  if( incrementer > 3 )
770
    incrementer = 3;
771
  else if( incrementer < -3 )
772
    incrementer = -3;
773
 
173 tk 774
  if( ui_encoder_callback != NULL ) {
775
    ui_encoder_callback((encoder == 0) ? SEQ_UI_ENCODER_Datawheel : (encoder-1), incrementer);
776
    ui_cursor_flash_ctr = 0; // ensure that value is visible when it has been changed
134 tk 777
  }
778
 
779
  // request display update
159 tk 780
  seq_ui_display_update_req = 1;
134 tk 781
 
782
  return 0; // no error
783
}
784
 
785
 
786
/////////////////////////////////////////////////////////////////////////////
787
// Update LCD messages
788
// Usually called from background task
789
/////////////////////////////////////////////////////////////////////////////
790
s32 SEQ_UI_LCD_Handler(void)
791
{
159 tk 792
  if( seq_ui_display_init_req ) {
793
    seq_ui_display_init_req = 0; // clear request
134 tk 794
 
795
    // clear both LCDs
796
    int i;
797
    for(i=0; i<2; ++i) {
798
      MIOS32_LCD_DeviceSet(i);
799
      SEQ_LCD_Clear();
800
    }
801
 
168 tk 802
    // select first menu item
803
    ui_selected_item = 0;
804
 
167 tk 805
    // call init function of current page
806
    if( ui_init_callback[ui_page] != NULL )
807
      ui_init_callback[ui_page](0); // mode
134 tk 808
 
809
    // request display update
159 tk 810
    seq_ui_display_update_req = 1;
134 tk 811
  }
812
 
167 tk 813
  // perform high priority LCD update request
168 tk 814
  if( ui_lcd_callback != NULL && !seq_ui_button_state.MENU_PAGE_DISPLAYED )
167 tk 815
    ui_lcd_callback(1); // high_prio
816
 
817
  // perform low priority LCD update request if requested
159 tk 818
  if( seq_ui_display_update_req ) {
819
    seq_ui_display_update_req = 0; // clear request
134 tk 820
 
168 tk 821
    // menu page is visible until MENU button has been released, or first page has been selected
822
    if( seq_ui_button_state.MENU_PAGE_DISPLAYED ) {
823
      // print available menu pages
824
      MIOS32_LCD_DeviceSet(0);
825
      MIOS32_LCD_CursorSet(0, 0);
826
      //                      <-------------------------------------->
827
      //                      0123456789012345678901234567890123456789
828
      MIOS32_LCD_PrintString("                                        ");
829
      MIOS32_LCD_CursorSet(0, 1);
830
      MIOS32_LCD_PrintString("Mix  Evnt Mode Dir. Div. Len. Trn. Grv. ");
831
 
832
      MIOS32_LCD_DeviceSet(1);
833
      MIOS32_LCD_CursorSet(0, 0);
834
      //                      <-------------------------------------->
835
      //                      0123456789012345678901234567890123456789
836
      MIOS32_LCD_PrintString("                                        ");
837
      MIOS32_LCD_CursorSet(0, 1);
838
      MIOS32_LCD_PrintString("Trg.  Fx  Man. Mrp. BPM  Save MIDI SysEx");
839
    } else {
840
      if( ui_lcd_callback != NULL )
841
    ui_lcd_callback(0); // no high_prio
842
    }
134 tk 843
  }
844
 
159 tk 845
  // for debugging
846
#if 0
847
  MIOS32_LCD_DeviceSet(0);
848
  MIOS32_LCD_CursorSet(0, 0);
849
  MIOS32_LCD_PrintFormattedString("%5d  ", seq_midi_queue_size);
850
#endif
851
 
167 tk 852
#if 0
166 tk 853
  u32 bpm_tick = SEQ_BPM_TickGet();
854
  u32 bpm_sub = bpm_tick % SEQ_BPM_RESOLUTION_PPQN;
855
  u32 bpm_16th = (bpm_tick / (SEQ_BPM_RESOLUTION_PPQN/4)) % 16;
856
  u32 bpm_qn = (bpm_tick / SEQ_BPM_RESOLUTION_PPQN) % 4;
857
  u32 bpm_n = bpm_tick / (4*SEQ_BPM_RESOLUTION_PPQN);
858
  MIOS32_LCD_DeviceSet(0);
859
  MIOS32_LCD_CursorSet(0, 0);
860
  MIOS32_LCD_PrintFormattedString("%3d.%2d.%2d.%3d  ", bpm_n, bpm_qn, bpm_16th, bpm_sub);
861
#endif
862
 
134 tk 863
  return 0; // no error
864
}
865
 
866
 
867
 
868
/////////////////////////////////////////////////////////////////////////////
869
// Update all LEDs
870
// Usually called from background task
871
/////////////////////////////////////////////////////////////////////////////
872
s32 SEQ_UI_LED_Handler(void)
873
{
874
  u8 visible_track = SEQ_UI_VisibleTrackGet();
875
 
876
  // track LEDs
167 tk 877
  SEQ_LED_PinSet(LED_TRACK1, (ui_selected_tracks & (1 << 0)));
878
  SEQ_LED_PinSet(LED_TRACK2, (ui_selected_tracks & (1 << 1)));
879
  SEQ_LED_PinSet(LED_TRACK3, (ui_selected_tracks & (1 << 2)));
880
  SEQ_LED_PinSet(LED_TRACK4, (ui_selected_tracks & (1 << 3)));
134 tk 881
 
882
  // parameter layer LEDs
167 tk 883
  SEQ_LED_PinSet(LED_PAR_LAYER_A, (ui_selected_par_layer == 0));
884
  SEQ_LED_PinSet(LED_PAR_LAYER_B, (ui_selected_par_layer == 1));
885
  SEQ_LED_PinSet(LED_PAR_LAYER_C, (ui_selected_par_layer == 2));
134 tk 886
 
887
  // group LEDs
167 tk 888
  SEQ_LED_PinSet(LED_GROUP1, (ui_selected_group == 0));
889
  SEQ_LED_PinSet(LED_GROUP2, (ui_selected_group == 1));
890
  SEQ_LED_PinSet(LED_GROUP3, (ui_selected_group == 2));
891
  SEQ_LED_PinSet(LED_GROUP4, (ui_selected_group == 3));
134 tk 892
 
893
  // trigger layer LEDs
167 tk 894
  SEQ_LED_PinSet(LED_TRG_LAYER_A, (ui_selected_trg_layer == 0));
895
  SEQ_LED_PinSet(LED_TRG_LAYER_B, (ui_selected_trg_layer == 1));
896
  SEQ_LED_PinSet(LED_TRG_LAYER_C, (ui_selected_trg_layer == 2));
134 tk 897
 
898
  // remaining LEDs
167 tk 899
  SEQ_LED_PinSet(LED_EDIT, ui_page == SEQ_UI_PAGE_EDIT);
134 tk 900
  SEQ_LED_PinSet(LED_MUTE, 0);
901
  SEQ_LED_PinSet(LED_PATTERN, 0);
902
  SEQ_LED_PinSet(LED_SONG, 0);
903
 
904
  SEQ_LED_PinSet(LED_SOLO, 0);
905
  SEQ_LED_PinSet(LED_FAST, 0);
906
  SEQ_LED_PinSet(LED_ALL, 0);
907
 
166 tk 908
  SEQ_LED_PinSet(LED_PLAY, seq_core_state.RUN);
909
  SEQ_LED_PinSet(LED_STOP, !seq_core_state.RUN);
910
  SEQ_LED_PinSet(LED_PAUSE, seq_core_state.PAUSE);
134 tk 911
 
167 tk 912
  SEQ_LED_PinSet(LED_STEP_1_16, (ui_selected_step_view == 0));
913
  SEQ_LED_PinSet(LED_STEP_17_32, (ui_selected_step_view == 1)); // will be obsolete in MBSEQ V4
134 tk 914
 
167 tk 915
  SEQ_LED_PinSet(LED_MENU, seq_ui_button_state.MENU_PRESSED);
916
  SEQ_LED_PinSet(LED_SCRUB, 0);
917
  SEQ_LED_PinSet(LED_METRONOME, 0);
134 tk 918
 
167 tk 919
  // note: the background function is permanently interrupted - therefore we write the GP pattern
920
  // into a temporary variable, and take it over once completed
921
  u16 new_ui_gp_leds = 0x0000;
922
  if( seq_ui_button_state.MENU_PRESSED ) {
923
    // MENU button overruling - find out the selected menu (if accessible via MENU button)
924
    int i;
925
    for(i=0; i<16; ++i)
926
      if(ui_page == ui_direct_access_menu_pages[i])
927
    new_ui_gp_leds |= (1 << i);
928
  } else {
929
    // request GP LED values from current menu page
930
    // will be transfered to DOUT registers in SEQ_UI_LED_Handler_Periodic
931
    new_ui_gp_leds = 0x0000;
932
 
168 tk 933
    if( ui_led_callback != NULL )
173 tk 934
      ui_led_callback(&new_ui_gp_leds);
167 tk 935
  }
936
  ui_gp_leds = new_ui_gp_leds;
937
 
134 tk 938
  return 0; // no error
939
}
940
 
941
 
942
/////////////////////////////////////////////////////////////////////////////
943
// updates high-prio LED functions (GP LEDs and Beat LED)
168 tk 944
// called each mS
134 tk 945
/////////////////////////////////////////////////////////////////////////////
946
s32 SEQ_UI_LED_Handler_Periodic()
947
{
948
  // GP LEDs are only updated when ui_gp_leds or pos_marker_mask has changed
949
  static u16 prev_ui_gp_leds = 0x0000;
950
  static u16 prev_pos_marker_mask = 0x0000;
951
 
952
  // beat LED: tmp. for demo w/o real sequencer
167 tk 953
  SEQ_LED_PinSet(LED_BEAT, (seq_core_state.RUN && (seq_core_state.ref_step & 3) == 0));
134 tk 954
 
955
  // for song position marker (supports 16 LEDs, check for selected step view)
956
  u16 pos_marker_mask = 0x0000;
166 tk 957
  u8 played_step = seq_core_trk[SEQ_UI_VisibleTrackGet()].step;
958
  if( seq_core_state.RUN && (played_step >> 4) == ui_selected_step_view )
134 tk 959
    pos_marker_mask = 1 << (played_step & 0xf);
960
 
961
  // exit of pattern hasn't changed
173 tk 962
  if( prev_ui_gp_leds == ui_gp_leds && prev_pos_marker_mask == pos_marker_mask )
134 tk 963
    return 0;
173 tk 964
  prev_ui_gp_leds = ui_gp_leds;
134 tk 965
  prev_pos_marker_mask = pos_marker_mask;
966
 
967
  // transfer to GP LEDs
968
 
969
#ifdef DEFAULT_GP_DOUT_SR_L
970
# ifdef DEFAULT_GP_DOUT_SR_L2
173 tk 971
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_L-1, (ui_gp_leds >> 0) & 0xff);
134 tk 972
# else
173 tk 973
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_L-1, ((ui_gp_leds ^ pos_marker_mask) >> 0) & 0xff);
134 tk 974
# endif
975
#endif
976
#ifdef DEFAULT_GP_DOUT_SR_R
977
# ifdef DEFAULT_GP_DOUT_SR_R2
173 tk 978
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_R-1, (ui_gp_leds >> 8) & 0xff);
134 tk 979
#else
173 tk 980
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_R-1, ((ui_gp_leds ^ pos_marker_mask) >> 8) & 0xff);
134 tk 981
#endif
982
#endif
983
 
984
#ifdef DEFAULT_GP_DOUT_SR_L2
985
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_L2-1, (pos_marker_mask >> 0) & 0xff);
986
#endif
987
#ifdef DEFAULT_GP_DOUT_SR_R2
988
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_R2-1, (pos_marker_mask >> 8) & 0xff);
989
#endif
990
 
991
#if DEFAULT_SRM_ENABLED && DEFAULT_SRM_DOUT_M_MAPPING == 1
992
  // for wilba's frontpanel
993
 
994
  // BLM8X8 DOUT -> GP LED mapping
995
  // 0 = 15,16  1 = 13,14   2 = 11,12   3 = 9,10
996
  // 4 = 1,2    5 = 3,4     6 = 5,6     7 = 7,8
997
 
998
  // bit 7: first green (i.e. GP1-G)
999
  // bit 6: first red (i.e. GP1-R)
1000
  // bit 5: second green (i.e. GP2-G)
1001
  // bit 4: second red (i.e. GP2-R)
1002
 
1003
  // this mapping routine takes ca. 5 uS
173 tk 1004
  // since it's only executed when ui_gp_leds or gp_mask has changed, it doesn't really hurt
134 tk 1005
 
173 tk 1006
  u16 modified_gp_leds = ui_gp_leds;
134 tk 1007
#if 1
1008
  // extra: red LED is lit exclusively for higher contrast
1009
  modified_gp_leds &= ~pos_marker_mask;
1010
#endif
1011
 
1012
  int sr;
1013
  const u8 blm8x8_sr_map[8] = {4, 5, 6, 7, 3, 2, 1, 0};
1014
  u16 gp_mask = 1 << 0;
1015
  for(sr=0; sr<8; ++sr) {
1016
    u8 pattern = 0;
1017
 
1018
    if( modified_gp_leds & gp_mask )
1019
      pattern |= 0x80;
1020
    if( pos_marker_mask & gp_mask )
1021
      pattern |= 0x40;
1022
    gp_mask <<= 1;
1023
    if( modified_gp_leds & gp_mask )
1024
      pattern |= 0x20;
1025
    if( pos_marker_mask & gp_mask )
1026
      pattern |= 0x10;
1027
    gp_mask <<= 1;
1028
 
1029
    u8 mapped_sr = blm8x8_sr_map[sr];
1030
    blm8x8_led_row[mapped_sr] = (blm8x8_led_row[mapped_sr] & 0x0f) | pattern;
1031
  }
1032
#endif
1033
 
1034
}
1035
 
1036
 
1037
/////////////////////////////////////////////////////////////////////////////
168 tk 1038
// for menu handling (e.g. flashing cursor, doubleclick counter, etc...)
1039
// called each mS
1040
/////////////////////////////////////////////////////////////////////////////
1041
s32 SEQ_UI_MENU_Handler_Periodic()
1042
{
1043
  if( ++ui_cursor_flash_ctr >= SEQ_UI_CURSOR_FLASH_CTR_MAX ) {
1044
    ui_cursor_flash_ctr = 0;
1045
    seq_ui_display_update_req = 1;
173 tk 1046
  } else if( ui_cursor_flash_ctr == SEQ_UI_CURSOR_FLASH_CTR_LED_OFF ) {
168 tk 1047
    seq_ui_display_update_req = 1;
173 tk 1048
  }
1049
  // important: flash flag has to be recalculated on each invocation of this
1050
  // handler, since counter could also be reseted outside this function
1051
  ui_cursor_flash = ui_cursor_flash_ctr >= SEQ_UI_CURSOR_FLASH_CTR_LED_OFF;
168 tk 1052
 
1053
  return 0;
1054
}
1055
 
1056
 
1057
/////////////////////////////////////////////////////////////////////////////
134 tk 1058
// Returns the currently visible track
1059
/////////////////////////////////////////////////////////////////////////////
1060
u8 SEQ_UI_VisibleTrackGet(void)
1061
{
1062
  u8 offset = 0;
1063
 
1064
  if( ui_selected_tracks & (1 << 3) )
1065
    offset = 3;
1066
  if( ui_selected_tracks & (1 << 2) )
1067
    offset = 2;
1068
  if( ui_selected_tracks & (1 << 1) )
1069
    offset = 1;
1070
  if( ui_selected_tracks & (1 << 0) )
1071
    offset = 0;
1072
 
1073
  return 4*ui_selected_group + offset;
1074
}
1075
 
168 tk 1076
 
1077
/////////////////////////////////////////////////////////////////////////////
1078
// Increments the selected tracks/groups
1079
// OUT: 1 if value has been changed, otherwise 0
1080
/////////////////////////////////////////////////////////////////////////////
1081
s32 SEQ_UI_GxTyInc(s32 incrementer)
1082
{
1083
  int gxty = SEQ_UI_VisibleTrackGet();
1084
  int prev_gxty = gxty;
1085
 
1086
  if( incrementer >= 0 ) {
1087
    if( (gxty += incrementer) >= SEQ_CORE_NUM_TRACKS )
1088
      gxty = SEQ_CORE_NUM_TRACKS-1;
1089
  } else {
1090
    if( (gxty += incrementer) < 0 )
1091
      gxty = 0;
1092
  }
1093
 
1094
  if( gxty == prev_gxty )
1095
    return 0; // no change
1096
 
1097
  ui_selected_tracks = 1 << (gxty % 4);
1098
  ui_selected_group = gxty / 4;
1099
 
1100
  return 1; // value changed
1101
}
1102
 
1103
 
1104
/////////////////////////////////////////////////////////////////////////////
1105
// Increments a CC within given min/max range
1106
// OUT: 1 if value has been changed, otherwise 0
1107
/////////////////////////////////////////////////////////////////////////////
1108
s32 SEQ_UI_CCInc(u8 cc, u16 min, u16 max, s32 incrementer)
1109
{
1110
  u8 visible_track = SEQ_UI_VisibleTrackGet();
173 tk 1111
  int new_value = SEQ_CC_Get(visible_track, cc);
1112
  int prev_value = new_value;
168 tk 1113
 
1114
  if( incrementer >= 0 ) {
173 tk 1115
    if( (new_value += incrementer) >= max )
1116
      new_value = max;
168 tk 1117
  } else {
173 tk 1118
    if( (new_value += incrementer) < min )
1119
      new_value = min;
168 tk 1120
  }
1121
 
173 tk 1122
  if( new_value == prev_value )
168 tk 1123
    return 0; // no change
1124
 
173 tk 1125
  SEQ_CC_Set(visible_track, cc, new_value);
168 tk 1126
 
1127
  return 1; // value changed
1128
}
1129
 
173 tk 1130
 
1131
/////////////////////////////////////////////////////////////////////////////
1132
// Modifies a bitfield in a CC value to a given value
1133
// OUT: 1 if value has been changed, otherwise 0
1134
/////////////////////////////////////////////////////////////////////////////
1135
s32 SEQ_UI_CCSetFlags(u8 cc, u16 flag_mask, u16 value)
1136
{
1137
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1138
  int new_value = SEQ_CC_Get(visible_track, cc);
1139
  int prev_value = new_value;
1140
 
1141
  new_value = (new_value & ~flag_mask) | value;
1142
 
1143
  if( new_value == prev_value )
1144
    return 0; // no change
1145
 
1146
  SEQ_CC_Set(visible_track, cc, new_value);
1147
 
1148
  return 1; // value changed
1149
}
1150
 
1151