Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
2355 Sauraen 1
/*
2
 * MIDIbox Quad Genesis: Channel Mode
3
 *
4
 * ==========================================================================
5
 *
6
 *  Copyright (C) 2016 Sauraen (sauraen@gmail.com)
7
 *  Licensed for personal non-commercial use only.
8
 *  All other rights reserved.
9
 *
10
 * ==========================================================================
11
 */
12
 
13
#include <mios32.h>
14
#include "mode_chan.h"
15
 
2497 Sauraen 16
#include "filebrowser.h"
2391 Sauraen 17
#include "frontpanel.h"
18
#include "interface.h"
19
#include "syeng.h"
20
#include "mode_prog.h"
2372 Sauraen 21
#include "mode_voice.h"
2396 Sauraen 22
#include "mode_vgm.h"
2391 Sauraen 23
#include "nameeditor.h"
2355 Sauraen 24
 
2486 Sauraen 25
u8 selchan;
2391 Sauraen 26
static u8 submode;
27
static u8 cursor;
2372 Sauraen 28
 
29
static void DrawMenu(){
30
    switch(submode){
31
        case 0:
2376 Sauraen 32
            FrontPanel_LEDSet(FP_LED_NEW, 0);
33
            FrontPanel_LEDSet(FP_LED_DELETE, 0);
2372 Sauraen 34
            MIOS32_LCD_Clear();
35
            MIOS32_LCD_CursorSet(0,0);
36
            MIOS32_LCD_PrintFormattedString("Prt%d:Ch%2d", (selchan >> 4)+1, (selchan & 0xF)+1);
37
            MIOS32_LCD_CursorSet(0,1);
38
            if(channels[selchan].trackermode){
39
                u8 v = channels[selchan].trackervoice;
2380 Sauraen 40
                MIOS32_LCD_PrintFormattedString(" Free     ~Trkr G%d:%s", (v >> 4)+1, GetVoiceName(v & 0xF));
2372 Sauraen 41
            }else{
2376 Sauraen 42
                synprogram_t* prog = channels[selchan].program;
2492 Sauraen 43
                if(prog == NULL){
44
                    MIOS32_LCD_PrintString("~Free      Trkr");
45
                    MIOS32_LCD_CursorSet(20,0);
46
                    MIOS32_LCD_PrintFormattedString("Prog: <none>");
47
                }else{
48
                    MIOS32_LCD_PrintString("~Free               Edit");
49
                    MIOS32_LCD_CursorSet(20,0);
50
                    MIOS32_LCD_PrintFormattedString("Prog: %s", prog->name);
51
                }
2372 Sauraen 52
            }
53
            break;
2376 Sauraen 54
        case 1:
2380 Sauraen 55
            MIOS32_LCD_Clear();
56
            MIOS32_LCD_CursorSet(0,0);
57
            MIOS32_LCD_PrintFormattedString("Select voice to control with Prt%d:Ch%2d", (selchan >> 4)+1, (selchan & 0xF)+1);
58
            break;
59
        case 2:
2384 Sauraen 60
            MIOS32_LCD_Clear();
61
            MIOS32_LCD_CursorSet(0,0);
62
            MIOS32_LCD_PrintString("Which operator? (Ch3 4Freq/CSM)");
63
            MIOS32_LCD_CursorSet(0,1);
64
            MIOS32_LCD_PrintString("  1    2    3  4/All");
65
            break;
2372 Sauraen 66
        default:
67
            MIOS32_LCD_Clear();
68
            MIOS32_LCD_CursorSet(0,0);
69
            MIOS32_LCD_PrintFormattedString("Chan invalid submode %d!", submode);
70
    }
2355 Sauraen 71
}
2372 Sauraen 72
 
2391 Sauraen 73
void NameEditorDone(){
74
    Interface_ChangeToMode(MODE_PROG);
75
}
76
 
2516 Sauraen 77
void EditProgram(){
78
    if(channels[selchan].program == NULL) return;
79
    selprogram = channels[selchan].program;
80
    Mode_Vgm_InvalidateVgm(NULL);
81
    Interface_ChangeToMode(MODE_PROG);
82
}
83
 
2497 Sauraen 84
static void FilebrowserDoneLoading(char* filepath){
2516 Sauraen 85
    if(filepath == NULL){
86
        DrawMenu();
87
        return;
88
    }
89
    SyEng_DeleteProgram(selchan);
90
    synprogram_t* prog = vgmh2_malloc(sizeof(synprogram_t));
91
    channels[selchan].program = prog;
92
    s32 ret = SyEng_LoadProgram(filepath, prog);
93
    if(ret >= 0){
94
        EditProgram();
95
    }else{
96
        DrawMenu();
97
        MIOS32_LCD_CursorSet(0,0);
98
        MIOS32_LCD_PrintFormattedString("Error %d    ", ret);
99
    }
2497 Sauraen 100
}
101
 
102
static void FilebrowserDoneSaving(char* filepath){
103
    if(filepath == NULL){
104
        DrawMenu();
105
        return;
106
    }
107
    synprogram_t* prog = channels[selchan].program;
108
    if(prog == NULL){
109
        DrawMenu();
110
        return;
111
    }
2516 Sauraen 112
    s32 ret = SyEng_SaveProgram(prog, filepath);
113
    if(ret >= 0){
114
        DrawMenu();
115
        MIOS32_LCD_CursorSet(0,0);
116
        MIOS32_LCD_PrintString("Saved       ");
117
    }else{
118
        DrawMenu();
119
        MIOS32_LCD_CursorSet(0,0);
120
        MIOS32_LCD_PrintFormattedString("Error %d    ", ret);
2497 Sauraen 121
    }
122
}
123
 
2372 Sauraen 124
void Mode_Chan_Init(){
125
    selchan = 0;
126
    submode = 0;
127
    cursor = 0;
128
}
2355 Sauraen 129
void Mode_Chan_GotFocus(){
2372 Sauraen 130
    submode = 0;
131
    DrawMenu();
132
    FrontPanel_GenesisLEDSet((selchan >> 4), 0, 1, 1);
133
    FrontPanel_GenesisLEDSet((selchan >> 2) & 3, (selchan & 3)+8, 1, 1);
134
    if(channels[selchan].trackermode){
135
        u8 v = channels[selchan].trackervoice;
136
        FrontPanel_GenesisLEDSet(v >> 4, v & 0xF, 0, 1);
137
    }
2355 Sauraen 138
}
139
 
140
void Mode_Chan_Tick(){
141
 
142
}
143
void Mode_Chan_Background(){
144
 
145
}
146
 
147
void Mode_Chan_BtnGVoice(u8 gvoice, u8 state){
2372 Sauraen 148
    if(!state) return;
149
    u8 g = gvoice >> 4;
150
    u8 v = gvoice & 0xF;
151
    u8 t = channels[selchan].trackervoice;
2380 Sauraen 152
    switch(submode){
153
        case 0:
154
            if(v == 0){
2384 Sauraen 155
                FrontPanel_GenesisLEDSet(t >> 4, (t & 0xF) < 0xC ? (t & 0xF) : 3 , 0, 0);
2380 Sauraen 156
                FrontPanel_GenesisLEDSet((selchan >> 4), 0, 1, 0);
157
                selchan = (g << 4) | (selchan & 0xF);
158
                FrontPanel_GenesisLEDSet(g, 0, 1, 1);
159
                if(channels[selchan].trackermode){
160
                    t = channels[selchan].trackervoice;
2384 Sauraen 161
                    FrontPanel_GenesisLEDSet(t >> 4, (t & 0xF) < 0xC ? (t & 0xF) : 3, 0, 1);
2380 Sauraen 162
                }
163
                DrawMenu();
164
            }else if(v >= 8 && v <= 11){
165
                v -= 8;
2384 Sauraen 166
                FrontPanel_GenesisLEDSet(t >> 4, (t & 0xF) < 0xC ? (t & 0xF) : 3, 0, 0);
2380 Sauraen 167
                FrontPanel_GenesisLEDSet((selchan >> 2) & 3, (selchan & 3)+8, 1, 0);
168
                selchan = (selchan & 0xF0) | (g << 2) | v;
169
                FrontPanel_GenesisLEDSet(g, v+8, 1, 1);
170
                if(channels[selchan].trackermode){
171
                    t = channels[selchan].trackervoice;
2384 Sauraen 172
                    FrontPanel_GenesisLEDSet(t >> 4, (t & 0xF) < 0xC ? (t & 0xF) : 3, 0, 1);
2380 Sauraen 173
                }
174
                DrawMenu();
175
            }
176
            break;
177
        case 1:
2384 Sauraen 178
            if(v == 3 && syngenesis[g].channels[3].use == 3){
179
                cursor = g;
180
                submode = 2;
181
            }else{
182
                SyEng_ClearVoice(g, v);
183
                syngenesis[g].channels[v].use = 3;
184
                channels[selchan].trackervoice = (g << 4) | v;
185
                channels[selchan].trackermode = 1;
186
                FrontPanel_GenesisLEDSet(g, v, 0, 1);
187
                submode = 0;
188
            }
2380 Sauraen 189
            DrawMenu();
190
            break;
2372 Sauraen 191
    }
2355 Sauraen 192
}
193
void Mode_Chan_BtnSoftkey(u8 softkey, u8 state){
2372 Sauraen 194
    if(!state) return;
195
    switch(submode){
196
        case 0:
197
            switch(softkey){
198
                case 0:
2380 Sauraen 199
                    if(!channels[selchan].trackermode) return;
200
                    channels[selchan].trackermode = 0;
2372 Sauraen 201
                    u8 v = channels[selchan].trackervoice;
2384 Sauraen 202
                    u8 g = v >> 4;
203
                    v &= 0xF;
204
                    u8 c, t;
205
                    if(v == 3){
206
                        //Is there any other channel controlling Ch3 main?
207
                        for(c=0; c<16*MBQG_NUM_PORTS; ++c){
208
                            if(channels[c].trackermode && channels[c].trackervoice == 3){
209
                                break;
210
                            }
211
                        }
212
                        if(c == 16*MBQG_NUM_PORTS){ //there was none
213
                            syngenesis[g].channels[3].use = 0;
214
                            //Also clear trackermode from voices controlling Ch3 operator frequencies
215
                            for(c=0; c<16*MBQG_NUM_PORTS; ++c){
216
                                if(channels[c].trackermode){
217
                                    t = channels[c].trackervoice;
218
                                    if((t >> 4) == g && (t & 0xF) >= 0xC){
219
                                        channels[c].trackermode = 0;
220
                                    }
221
                                }
222
                            }
223
                        }
224
                    }else if(v >= 0xC){
225
                        //don't clear use
226
                        v = 3; //turn off ch3 LED
227
                    }else{
228
                        //Is there any other channel controlling Ch3 main?
229
                        for(c=0; c<16*MBQG_NUM_PORTS; ++c){
230
                            if(channels[c].trackermode && channels[c].trackervoice == v){
231
                                break;
232
                            }
233
                        }
234
                        if(c == 16*MBQG_NUM_PORTS){ //there was none
235
                            syngenesis[g].channels[v].use = 0;
236
                        }
237
                    }
238
                    FrontPanel_GenesisLEDSet(g, v, 0, 0);
2372 Sauraen 239
                    DrawMenu();
240
                    break;
241
                case 2:
2380 Sauraen 242
                    if(channels[selchan].trackermode) return;
243
                    submode = 1;
2372 Sauraen 244
                    DrawMenu();
245
                    break;
2391 Sauraen 246
                case 4:
2492 Sauraen 247
                    EditProgram();
2391 Sauraen 248
                    break;
2372 Sauraen 249
            }
250
            break;
2380 Sauraen 251
        case 2:
2384 Sauraen 252
            if(softkey == 3){
253
                SyEng_ClearVoice(cursor, 3);
254
                syngenesis[cursor].channels[3].use = 3;
255
                channels[selchan].trackervoice = (cursor << 4) | 3;
256
            }else if(softkey <= 2){
257
                channels[selchan].trackervoice = (cursor << 4) | (0xC + softkey);
258
            }else{
259
                return;
260
            }
261
            channels[selchan].trackermode = 1;
262
            FrontPanel_GenesisLEDSet(cursor, 3, 0, 1);
263
            submode = 0;
264
            DrawMenu();
265
            break;
2372 Sauraen 266
    }
2355 Sauraen 267
}
268
void Mode_Chan_BtnSelOp(u8 op, u8 state){
269
 
270
}
271
void Mode_Chan_BtnOpMute(u8 op, u8 state){
272
 
273
}
274
void Mode_Chan_BtnSystem(u8 button, u8 state){
2376 Sauraen 275
    if(!state) return;
276
    if(button == FP_B_MENU){
277
        submode = 0;
278
        DrawMenu();
279
        return;
280
    }
2518 Sauraen 281
    u8 dir = 0;
2376 Sauraen 282
    switch(submode){
283
        case 0:
284
            switch(button){
285
                case FP_B_LOAD:
2497 Sauraen 286
                    if(channels[selchan].program != NULL){
287
                        MIOS32_LCD_CursorSet(0,0);
2518 Sauraen 288
                        MIOS32_LCD_PrintString("Delete prog first!");
2497 Sauraen 289
                    }else{
290
                        Filebrowser_Start(NULL, "PGM", 0, &FilebrowserDoneLoading);
291
                    }
2376 Sauraen 292
                    break;
293
                case FP_B_SAVE:
2497 Sauraen 294
                    if(channels[selchan].program == NULL){
295
                        MIOS32_LCD_CursorSet(0,0);
2518 Sauraen 296
                        MIOS32_LCD_PrintString("No prog to save!");
2497 Sauraen 297
                    }else{
298
                        Filebrowser_Start(NULL, "PGM", 1, &FilebrowserDoneSaving);
299
                    }
2376 Sauraen 300
                    break;
301
                case FP_B_NEW:
302
                    if(channels[selchan].program != NULL){
303
                        MIOS32_LCD_CursorSet(0,0);
2518 Sauraen 304
                        MIOS32_LCD_PrintString("Delete prog first!");
2376 Sauraen 305
                    }else{
2391 Sauraen 306
                        synprogram_t* prog = vgmh2_malloc(sizeof(synprogram_t));
307
                        channels[selchan].program = prog;
308
                        prog->usage.all = 0;
309
                        prog->initsource = NULL;
310
                        prog->noteonsource = NULL;
311
                        prog->noteoffsource = NULL;
312
                        prog->rootnote = 60;
2515 Sauraen 313
                        prog->tlbaseoffs = 0;
2391 Sauraen 314
                        prog->name[0] = 'A';
315
                        prog->name[1] = 0;
316
                        selprogram = prog;
2396 Sauraen 317
                        Mode_Vgm_InvalidateVgm(NULL);
2391 Sauraen 318
                        NameEditor_Start(selprogram->name, 12, "New program", &NameEditorDone);
2376 Sauraen 319
                    }
320
                    break;
321
                case FP_B_DELETE:
2486 Sauraen 322
                    SyEng_DeleteProgram(selchan);
323
                    DrawMenu();
2376 Sauraen 324
                    break;
2492 Sauraen 325
                case FP_B_ENTER:
326
                    EditProgram();
327
                    break;
2518 Sauraen 328
                case FP_B_MOVEUP:
329
                    dir = 1; //No typo--continues below
330
                case FP_B_MOVEDN:
331
                    if(channels[selchan].trackermode) return;
332
                    if(channels[selchan].program == NULL) return;
333
                    s16 i;
334
                    for(i=selchan; dir ? (i>=0) : (i<16*MBQG_NUM_PORTS); dir ? --i : ++i){
335
                        if(channels[i].trackermode) continue;
336
                        if(channels[i].program != NULL) continue;
337
                        break;
338
                    }
339
                    if(i < 0 || i >= 16*MBQG_NUM_PORTS) return; //No place for it
340
                    //Got a place to move it
341
                    SyEng_HardFlushProgram(channels[selchan].program);
342
                    vTaskSuspendAll();
343
                    u8 p;
344
                    synproginstance_t* pi;
345
                    for(p=0; p<MBQG_NUM_PROGINSTANCES; ++p){
346
                        pi = &proginstances[p];
347
                        if(pi->sourcechannel == selchan){
348
                            pi->sourcechannel = i;
349
                        }
350
                    }
351
                    channels[i].program = channels[selchan].program;
352
                    channels[selchan].program = NULL;
353
                    xTaskResumeAll();
354
                    //Turn off old channel LEDs
355
                    FrontPanel_GenesisLEDSet((selchan >> 4), 0, 1, 0);
356
                    FrontPanel_GenesisLEDSet((selchan >> 2) & 3, (selchan & 3)+8, 1, 0);
357
                    //Change to new channel
358
                    selchan = i;
359
                    //Turn on new channel LEDs
360
                    FrontPanel_GenesisLEDSet((selchan >> 4), 0, 1, 1);
361
                    FrontPanel_GenesisLEDSet((selchan >> 2) & 3, (selchan & 3)+8, 1, 1);
362
                    //Update LCD
363
                    DrawMenu();
364
                    MIOS32_LCD_CursorSet(0,0);
365
                    MIOS32_LCD_PrintFormattedString("Moved prog to Prt%d:Ch%2d  ", (selchan >> 4), (selchan & 0xF)+1);
366
                    break;
2376 Sauraen 367
            }
368
            break;
369
    }
2355 Sauraen 370
}
371
void Mode_Chan_BtnEdit(u8 button, u8 state){
2376 Sauraen 372
 
2355 Sauraen 373
}
374
 
375
void Mode_Chan_EncDatawheel(s32 incrementer){
2391 Sauraen 376
 
2355 Sauraen 377
}
378
void Mode_Chan_EncEdit(u8 encoder, s32 incrementer){
379
 
380
}