1
2 /*
3 * Diverse Bristol audio routines.
4 * Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22
23 #include <fcntl.h>
24
25 #include "brighton.h"
26 #include "brightonMini.h"
27 #include "brightoninternals.h"
28
29 static int ms20Init();
30 static int ms20Configure();
31 static int ms20Callback(brightonWindow *, int, int, float);
32
33 extern guimain global;
34
35 #include "brightonKeys.h"
36
37 #define KEY_PANEL 1
38
39 #define FIRST_DEV 0
40
41 /* 36 controllers, 4 idle, 35 patches, 5 idle, then memory. */
42 #define DEVICE_COUNT 98
43 #define ACTIVE_DEVS 79 /* 35 of 40 jack connectors active. */
44 #define MEM_START (ACTIVE_DEVS + 1)
45 #define MS20_OUTPUTS 20
46 #define MS20_INPUTS 20
47 #define OUTPUT_START 40
48 #define INPUT_START 60
49
50 #define DISPLAY1 (DEVICE_COUNT - 2)
51 #define DISPLAY2 (DEVICE_COUNT - 1)
52
53 #define S1 60
54 #define S2 74
55
56 #define R1 150
57 #define R2 383
58 #define R3 616
59 #define R4 800
60
61 #define RD1 ((R4 - R1) / 4)
62
63 #define RR1 R1
64 #define RR2 (RR1 + RD1)
65 #define RR3 (RR2 + RD1)
66 #define RR4 (RR3 + RD1)
67 #define RR5 R4
68
69 #define CD1 67
70 #define C1 17
71 #define C2 (C1 + CD1)
72 #define C3 (C2 + CD1)
73 #define C4 (C3 + CD1 + 1)
74 #define C5 (C4 + CD1 - 1)
75 #define C6 (C5 + CD1 + 1)
76 #define C7 (C6 + CD1)
77 #define C8 (C7 + CD1)
78 #define C9 (C8 + CD1 + 4)
79 #define C10 (C9 + CD1 + 1)
80 #define C11 (C10 + CD1 + 3)
81 #define C12 (C11 + CD1)
82 #define C13 (C12 + CD1)
83 #define C14 (C13 + CD1)
84
85 static int oselect;
86 static struct {
87 int input;
88 int id; /* From graphical interface. */
89 } links[MS20_OUTPUTS];
90
91 /*
92 * This structure is for device definition. The structure is defined in
93 * include/brighton.h, further definitions in brighton/brightonDevtable.h and
94 * include/brightoninternals.h
95 *
96 * typedef int (*brightonCallback)(int, float);
97 * typedef struct BrightonLocations {
98 * int device; 0=rotary, 1=scale, etc.
99 * float relx, rely; relative position with regards to 1000 by 1000 window
100 * float relw, relh; relative height.
101 * int from, to;
102 * brightonCallback callback; specific to this dev
103 * char *image; bitmap. If zero take a device default.
104 * int flags;
105 * } brightonLocations;
106 *
107 * This example is for a ms20Bristol type synth interface.
108 */
109 static brightonLocations locations[DEVICE_COUNT] = {
110 /* LFO and control */
111 {"", 0, C1 - 1, R1 - 12, S2, S2, 0, 3, 0,
112 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
113 {"", 0, C1, R2 - 30, S1, S1, 0, 1, 0,
114 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
115 {"", 0, C1 - 1, R3 - 72, S2, S2, 0, 3, 0,
116 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
117 {"", 0, C1, R4, S1, S1, 0, 1, 0,
118 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
119
120 {"", 0, C2 - 5, R1 - 12, S2, S2, 0, 3, 0,
121 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
122 {"", 0, C2, R2 - 30, S1, S1, 0, 1, 0,
123 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
124 {"", 0, C2 - 5, R3 - 72, S2, S2, 0, 3, 0,
125 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
126 {"", 0, C2, R4, S1, S1, 0, 1, 0,
127 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
128
129 {"", 0, C3, R1, S1, S1, 0, 1, 0,
130 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
131 {"", 0, C3, R2, S1, S1, 0, 1, 0,
132 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
133 {"", 0, C3, RR4, S1, S1, 0, 1, 0,
134 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
135 {"", 0, C3, RR5, S1, S1, 0, 1, 0,
136 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
137
138 {"", 0, C4 - 3, R1 + 3, S2, S2, 0, 1, 0,
139 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
140 {"", 0, C4, R2 + 6, S1, S1, 0, 1, 0,
141 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
142 {"", 0, C4, RR4 + 6, S1, S1, 0, 1, 0,
143 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
144 {"", 0, C4, RR5 + 6, S1, S1, 0, 1, 0,
145 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
146
147 {"", 0, C5 - 3, R1 + 3, S2, S2, 0, 1, 0,
148 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
149 {"", 0, C5, R2 + 6, S1, S1, 0, 1, 0,
150 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
151 {"", 0, C5, RR4 + 6, S1, S1, 0, 1, 0,
152 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
153 {"", 0, C5, RR5 + 6, S1, S1, 0, 1, 0,
154 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
155
156 {"", 0, C6, RR4 + 5, S1, S1, 0, 1, 0,
157 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
158 {"", 0, C6, RR5 + 5, S1, S1, 0, 1, 0,
159 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
160
161 {"", 0, C7, RR3 + 5, S1, S1, 0, 1, 0,
162 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
163 {"", 0, C7, RR4 + 5, S1, S1, 0, 1, 0,
164 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
165 {"", 0, C7, RR5 + 5, S1, S1, 0, 1, 0,
166 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
167
168 {"", 0, C8, RR1 + 5, S1, S1, 0, 1, 0,
169 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
170 {"", 0, C8, RR2 + 5, S1, S1, 0, 1, 0,
171 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
172 {"", 0, C8, RR3 + 5, S1, S1, 0, 1, 0,
173 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
174 {"", 0, C8, RR4 + 5, S1, S1, 0, 1, 0,
175 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
176 {"", 0, C8, RR5 + 5, S1, S1, 0, 1, 0,
177 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
178
179 {"", 0, C9, R4 + 6, S1, S1, 0, 1, 0,
180 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
181 {"", 0, C10, R4 + 6, S1, S1, 0, 1, 0,
182 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
183 {"", 0, C11 - 2, R4 + 4, S1, S1, 0, 1, 0,
184 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
185 {"", 0, C12 - 1, R4 + 2, S1, S1, 0, 1, 0,
186 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
187 {"", 0, C13, R4, S1, S1, 0, 1, 0,
188 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
189
190 {"", 0, C14 + 2, R1 - 30, S2, S2, 0, 1, 0,
191 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_NOSHADOW|BRIGHTON_REDRAW},
192
193 /* Dummies */
194 {"", 0, C10, R1, S1, S1, 0, 1, 0,
195 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_WITHDRAWN},
196 {"", 0, C11, R1, S1, S1, 0, 1, 0,
197 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_WITHDRAWN},
198 {"", 0, C12, R1, S1, S1, 0, 1, 0,
199 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_WITHDRAWN},
200 {"", 0, C13, R1, S1, S1, 0, 1, 0,
201 "bitmaps/knobs/line.xpm", 0, BRIGHTON_NOTCH|BRIGHTON_WITHDRAWN},
202
203 /*
204 * First the Outputs. Start with clocks at 40.
205 */
206 {"", 2, 549, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
207 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
208 {"", 2, 627, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
209 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
210 /* Env-1 out */
211 {"", 2, 680, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
212 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
213 {"", 2, 680, 401, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
214 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
215 /* Env-2 rev out */
216 {"", 2, 849, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
217 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
218 /* KBD CV and TRIG out */
219 {"", 2, 964, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
220 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
221 {"", 2, 964, 401, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
222 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
223 /* S&H Out */
224 {"", 2, 627, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
225 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
226 {"", 2, 756, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
227 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
228 {"", 2, 798, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
229 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
230 {"", 2, 877, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
231 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
232 /* Ext Sig Proc outputs */
233 {"", 2, 627, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
234 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
235 {"", 2, 735, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
236 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
237 {"", 2, 820, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
238 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
239 {"", 2, 923, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
240 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
241 {"", 2, 964, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
242 "bitmaps/buttons/patchonl.xpm", BRIGHTON_NOSHADOW},
243 /* Dummies */
244 {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
245 "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
246 {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
247 "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
248 {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
249 "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
250 {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
251 "bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
252
253 /*
254 * Then the inputs. The primary is a dummy. I will put in 15 inputs and
255 * 25 outputs, there are 353 in total with some dummies and a couple that
256 * are not active.
257 */
258 {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
259 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
260
261 /* The top line */
262 {"", 2, 549, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
263 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
264 {"", 2, 611, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
265 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
266 {"", 2, 664, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
267 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
268 {"", 2, 725, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
269 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
270 {"", 2, 777, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
271 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
272 {"", 2, 832, 180, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
273 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
274 /* Control and trig */
275 {"", 2, 735, 401, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
276 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
277 {"", 2, 797, 401, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
278 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
279 /* KBD Control and trig */
280 {"", 2, 923, 297, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
281 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
282 {"", 2, 923, 401, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
283 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
284 {"", 2, 885, 347, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
285 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
286 /* S&H and its clock, VCA */
287 {"", 2, 586, 412, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
288 "bitmaps/buttons/patchon.xpm", BRIGHTON_NOSHADOW},
289 {"", 2, 549, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
290 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
291 {"", 2, 680, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
292 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
293 /* Wheels */
294 {"", 2, 923, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
295 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
296 {"", 2, 964, 527, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
297 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
298 /* Sig In */
299 {"", 2, 549, 690, 12, 30, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
300 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
301 /* Dummy ins */
302 {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
303 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
304 {"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
305 "bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
306
307 /* memories */
308 #define MH1 53
309 #define MH2 50
310 #define MW1 11
311 #define MW2 10
312
313 #define MR1 225
314 #define MR2 308
315
316 #define MCD 14
317 #define MC1 338
318 #define MC2 (MC1 + MCD)
319 #define MC3 (MC2 + MCD)
320 #define MC4 (MC3 + MCD)
321 #define MC5 (MC4 + MCD)
322 #define MC6 (MC5 + MCD)
323 #define MC7 (MC6 + MCD)
324 #define MC8 (MC7 + MCD + MCD)
325
326 /* Should be put into parameters, fixed values does not work... */
327 {"", 2, MC2, MR1, MW1, MH1, 0, 1.01, 0,
328 "bitmaps/buttons/pressoff.xpm",
329 "bitmaps/buttons/presson.xpm", 0},
330 {"", 2, MC3, MR1, MW1, MH1, 0, 1.01, 0,
331 "bitmaps/buttons/pressoff.xpm",
332 "bitmaps/buttons/presson.xpm", 0},
333 {"", 2, MC4, MR1, MW1, MH1, 0, 1.01, 0,
334 "bitmaps/buttons/pressoff.xpm",
335 "bitmaps/buttons/presson.xpm", 0},
336 {"", 2, MC5, MR1, MW1, MH1, 0, 1.01, 0,
337 "bitmaps/buttons/pressoff.xpm",
338 "bitmaps/buttons/presson.xpm", 0},
339 {"", 2, MC6, MR1, MW1, MH1, 0, 1.01, 0,
340 "bitmaps/buttons/pressoff.xpm",
341 "bitmaps/buttons/presson.xpm", 0},
342 {"", 2, MC2, MR2, MW1, MH1, 0, 1.01, 0,
343 "bitmaps/buttons/pressoff.xpm",
344 "bitmaps/buttons/presson.xpm", 0},
345 {"", 2, MC3, MR2, MW1, MH1, 0, 1.01, 0,
346 "bitmaps/buttons/pressoff.xpm",
347 "bitmaps/buttons/presson.xpm", 0},
348 {"", 2, MC4, MR2, MW1, MH1, 0, 1.01, 0,
349 "bitmaps/buttons/pressoff.xpm",
350 "bitmaps/buttons/presson.xpm", 0},
351 {"", 2, MC5, MR2, MW1, MH1, 0, 1.01, 0,
352 "bitmaps/buttons/pressoff.xpm",
353 "bitmaps/buttons/presson.xpm", 0},
354 {"", 2, MC6, MR2, MW1, MH1, 0, 1.01, 0,
355 "bitmaps/buttons/pressoff.xpm",
356 "bitmaps/buttons/presson.xpm", 0},
357 {"", 2, MC1, MR1, MW2, MH2, 0, 1.01, 0,
358 "bitmaps/buttons/pressoffg.xpm",
359 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
360 {"", 2, MC1, MR2, MW2, MH2, 0, 1.01, 0,
361 "bitmaps/buttons/pressoffo.xpm",
362 "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
363 /* mem up down */
364 {"", 2, MC7, MR1, MW2, MH2, 0, 1.01, 0,
365 "bitmaps/buttons/pressoffg.xpm",
366 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
367 {"", 2, MC7, MR2, MW2, MH2, 0, 1.01, 0,
368 "bitmaps/buttons/pressoffg.xpm",
369 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
370 /* MIDI up down */
371 {"", 2, MC8, MR1, MW2, MH2, 0, 1.01, 0,
372 "bitmaps/buttons/pressoffg.xpm",
373 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
374 {"", 2, MC8, MR2, MW2, MH2, 0, 1.01, 0,
375 "bitmaps/buttons/pressoffg.xpm",
376 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
377 /* displays */
378 {"", 3, 343, 90, 110, 45, 0, 1, 0, 0,
379 "bitmaps/images/alphadisplay3.xpm", 0},
380 {"", 3, 343, 132, 110, 45, 0, 1, 0, 0, 0, 0}
381 };
382
383 /*
384 * These are new mod controls for the Pro-1. Used here for the MS-20.
385 */
386 static brightonLocations newmods[2] = {
387 {"", BRIGHTON_MODWHEEL, 280, 180, 140, 550, 0, 1, 0,
388 "bitmaps/knobs/modwheel.xpm", 0,
389 BRIGHTON_REVERSE|BRIGHTON_HSCALE|BRIGHTON_NOSHADOW|BRIGHTON_CENTER|BRIGHTON_NOTCH},
390 {"", BRIGHTON_MODWHEEL, 620, 180, 140, 550, 0, 1, 0,
391 "bitmaps/knobs/modwheel.xpm", 0,
392 BRIGHTON_REVERSE|BRIGHTON_HSCALE|BRIGHTON_NOSHADOW},
393 };
394
395 /*
396 * This is a set of globals for the main window rendering. Again taken from
397 * include/brighton.h
398 */
399 brightonApp ms20App = {
400 "ms20",
401 0,
402 "bitmaps/textures/metal7.xpm",
403 BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* default is tesselate */
404 ms20Init,
405 ms20Configure, /* 3 callbacks, unused? */
406 0,
407 destroySynth,
408 {1, 100, 2, 2, 5, 520, 0, 0},
409 865, 440, 0, 0,
410 5, /* one panel only */
411 {
412 {
413 "ms-20",
414 "bitmaps/blueprints/ms20.xpm",
415 "bitmaps/textures/metal6.xpm",
416 BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */
417 0,
418 ms20Configure,
419 ms20Callback,
420 12, 25, 980, 677,
421 DEVICE_COUNT,
422 locations
423 },
424 {
425 "Keyboard",
426 0,
427 "bitmaps/newkeys/ekbg.xpm", /* flags */
428 0x020|BRIGHTON_STRETCH,
429 0,
430 0,
431 keyCallback,
432 140, 700, 840, 300,
433 KEY_COUNT_3OCTAVE,
434 keys3octave
435 },
436 {
437 "Mods",
438 0, //"bitmaps/blueprints/mods.xpm",
439 "bitmaps/textures/metal7.xpm", /* flags */
440 BRIGHTON_STRETCH,
441 0,
442 0,
443 modCallback,
444 12, 700, 128, 300,
445 2,
446 newmods
447 },
448 {
449 "SP1",
450 0,
451 "bitmaps/images/rhodes.xpm",
452 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
453 0,
454 0,
455 0,
456 0, 0, 12, 1000,
457 0,
458 0
459 },
460 {
461 "SP2",
462 0,
463 "bitmaps/images/rhodes.xpm",
464 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
465 0,
466 0,
467 0,
468 988, 0, 12, 1000,
469 0,
470 0
471 },
472 }
473 };
474
475 /*static dispatcher dispatch[DEVICE_COUNT]; */
476
477 static int
ms20MidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)478 ms20MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
479 {
480 bristolMidiSendMsg(fd, chan, c, o, v);
481 return(0);
482 }
483
484 static int
ms20Memory(guiSynth * synth,int fd,int chan,int c,int o,int v)485 ms20Memory(guiSynth *synth, int fd, int chan, int c, int o, int v)
486 {
487 /* printf("ms20Memory(%i %i %i %i %i)\n", fd, chan, c, o, v); */
488
489 if (synth->flags & MEM_LOADING)
490 return(0);
491 if ((synth->flags & OPERATIONAL) == 0)
492 return(0);
493
494 if (synth->dispatch[MEM_START].other2)
495 {
496 synth->dispatch[MEM_START].other2 = 0;
497 return(0);
498 }
499
500 switch (c) {
501 default:
502 case 0:
503 if (synth->dispatch[MEM_START].other1 != -1)
504 {
505 brightonEvent event;
506 synth->dispatch[MEM_START].other2 = 1;
507
508 if (synth->dispatch[MEM_START].other1 != c)
509 event.value = 0;
510 else
511 event.value = 1;
512
513 brightonParamChange(synth->win, synth->panel,
514 synth->dispatch[MEM_START].other1, &event);
515 }
516 synth->dispatch[MEM_START].other1 = c;
517
518 synth->location = synth->location * 10 + o;
519
520 if (synth->location >= 1000)
521 synth->location = o;
522
523 if (loadMemory(synth, "ms20", 0, synth->location,
524 synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0)
525 displayText(synth, "FRE", synth->location, DISPLAY1);
526 else
527 displayText(synth, "PRG", synth->location, DISPLAY1);
528 break;
529 case 1:
530 if (loadMemory(synth, "ms20", 0, synth->location,
531 synth->mem.active, FIRST_DEV, 0) < 0)
532 displayText(synth, "FRE", synth->location, DISPLAY2);
533 else
534 displayText(synth, "PRG", synth->location, DISPLAY2);
535 /* synth->location = 0; */
536 break;
537 case 2:
538 saveMemory(synth, "ms20", 0, synth->location, FIRST_DEV);
539 displayText(synth, "PRG", synth->location, DISPLAY2);
540 /* synth->location = 0; */
541 break;
542 case 3:
543 while (loadMemory(synth, "ms20", 0, ++synth->location,
544 synth->mem.active, FIRST_DEV, 0) < 0)
545 {
546 if (synth->location > 999)
547 synth->location = -1;
548 }
549 displayText(synth, "PRG", synth->location, DISPLAY2);
550 break;
551 case 4:
552 while (loadMemory(synth, "ms20", 0, --synth->location,
553 synth->mem.active, FIRST_DEV, 0) < 0)
554 {
555 if (synth->location < 0)
556 synth->location = 999;
557 }
558 displayText(synth, "PRG", synth->location, DISPLAY2);
559 break;
560 }
561 return(0);
562 }
563
564 /*
565 * For the sake of ease of use, links have been placed here to be called
566 * by any of the devices created. They would be better in some other file,
567 * perhaps with this as a dispatch.
568 *
569 * Param refers to the device index in the locations table given below.
570 */
571 static int
ms20Callback(brightonWindow * win,int panel,int index,float value)572 ms20Callback(brightonWindow * win, int panel, int index, float value)
573 {
574 guiSynth *synth = findSynth(global.synths, win);
575 int sendvalue;
576
577 /* printf("ms20Callback(%i, %i, %f): %i %x\n", panel, index, value, synth); */
578
579 if (synth == 0)
580 return(0);
581
582 if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
583 return(0);
584 if (index >= DEVICE_COUNT)
585 return(0);
586
587 if (ms20App.resources[0].devlocn[index].to == 1.0)
588 sendvalue = value * (CONTROLLER_RANGE - 1);
589 else
590 sendvalue = value;
591
592 synth->mem.param[index] = value;
593
594 /* if ((!global.libtest) || (index >= ACTIVE_DEVS)) */
595 if ((!global.libtest) || (index >= 40))
596 synth->dispatch[index].routine(synth,
597 global.controlfd, synth->sid,
598 synth->dispatch[index].controller,
599 synth->dispatch[index].operator,
600 sendvalue);
601 else
602 printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
603 global.controlfd, synth->sid,
604 synth->dispatch[index].controller,
605 synth->dispatch[index].operator,
606 sendvalue);
607
608 return(0);
609 }
610
611 static void
ms20Midi(guiSynth * synth,int fd,int chan,int c,int o,int v)612 ms20Midi(guiSynth *synth, int fd, int chan, int c, int o, int v)
613 {
614 printf("ms20Midi(%i %i %i %i %i)\n", fd, chan, c, o, v);
615
616 if ((synth->flags & OPERATIONAL) == 0)
617 return;
618
619 if (synth->dispatch[MEM_START + 14].other1 == MEM_START + 14)
620 {
621 int newchan;
622
623 if (c == 1) {
624 if ((newchan = synth->midichannel - 1) < 0)
625 {
626 synth->midichannel = 0;
627 return;
628 }
629 } else {
630 if ((newchan = synth->midichannel + 1) >= 16)
631 {
632 synth->midichannel = 15;
633 return;
634 }
635 }
636
637 if (global.libtest == 0)
638 {
639 bristolMidiSendMsg(global.controlfd, synth->sid,
640 127, 0, BRISTOL_MIDICHANNEL|newchan);
641 }
642
643 synth->midichannel = newchan;
644
645 displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1);
646 } else {
647 if (c == 1) {
648 while (locations[--synth->dispatch[MEM_START + 15].other2].name[0]
649 == '\0')
650 {
651 if (synth->dispatch[MEM_START + 15].other2 < 0)
652 synth->dispatch[MEM_START + 15].other2 = 49;
653 }
654 } else {
655 while (locations[++synth->dispatch[MEM_START + 15].other2].name[0]
656 == '\0')
657 {
658 if (synth->dispatch[MEM_START + 15].other2 >= 49)
659 synth->dispatch[MEM_START + 15].other2 = 0;
660 }
661 }
662 displayText(synth,
663 locations[synth->dispatch[MEM_START + 15].other2].name,
664 synth->dispatch[MEM_START + 15].other2,
665 DISPLAY2);
666 if (synth->dispatch[MEM_START + 15].other1 == 1)
667 {
668 /*printf("PANEL X SELECTOR %i %i = %i %i\n", */
669 /*synth->dispatch[MEM_START + 15].other1, */
670 /*synth->dispatch[MEM_START + 15].other2, */
671 /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].controller, */
672 /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].operator); */
673 synth->dispatch[54].controller =
674 synth->dispatch[
675 synth->dispatch[MEM_START + 15].other2].controller;
676 synth->dispatch[54].operator =
677 synth->dispatch[
678 synth->dispatch[MEM_START + 15].other2].operator;
679 } else {
680 /*printf("PANEL Y SELECTOR %i %i = %i %i\n", */
681 /*synth->dispatch[MEM_START + 15].other1, */
682 /*synth->dispatch[MEM_START + 15].other2, */
683 /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].controller, */
684 /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].operator); */
685 synth->dispatch[55].controller =
686 synth->dispatch[
687 synth->dispatch[MEM_START + 15].other2].controller;
688 synth->dispatch[55].operator =
689 synth->dispatch[
690 synth->dispatch[MEM_START + 15].other2].operator;
691 }
692 }
693 }
694
695 static void
ms20PanelSelect(guiSynth * synth,int fd,int chan,int c,int o,int v)696 ms20PanelSelect(guiSynth *synth, int fd, int chan, int c, int o, int v)
697 {
698
699 /* printf("ms20PanelSelect(%x, %i, %i, %i, %i, %i\n", */
700 /* synth, fd, chan, c, o, v); */
701 /* dispatch[MEM_START + 14] = dispatch[MEM_START + 15] */
702
703 if (synth->dispatch[MEM_START + 14].other2)
704 {
705 synth->dispatch[MEM_START + 14].other2 = 0;
706 return;
707 }
708
709 if (synth->dispatch[MEM_START + 14].other1 != -1)
710 {
711 brightonEvent event;
712 synth->dispatch[MEM_START + 14].other2 = 1;
713
714 if (synth->dispatch[MEM_START + 14].other1 != c)
715 event.value = 0;
716 else
717 event.value = 1;
718
719 brightonParamChange(synth->win, synth->panel,
720 synth->dispatch[MEM_START + 14].other1, &event);
721 }
722 displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1);
723
724 if (c == MEM_START + 15)
725 {
726 if (synth->dispatch[MEM_START + 15].other1 > 1)
727 synth->dispatch[MEM_START + 15].other1 = 0;
728
729 switch (synth->dispatch[MEM_START + 15].other1) {
730 case 0:
731 default:
732 displayText(synth, "PAN-X",
733 synth->dispatch[MEM_START + 15].other2, DISPLAY1);
734 break;
735 case 1:
736 displayText(synth, "PAN-Y",
737 synth->dispatch[MEM_START + 15].other2, DISPLAY1);
738 break;
739 }
740 synth->dispatch[MEM_START + 15].other1++;
741 }
742 synth->dispatch[MEM_START + 14].other1 = c;
743 }
744
745 static void
ms20IOSelect(guiSynth * synth,int fd,int chan,int c,int o,int v)746 ms20IOSelect(guiSynth *synth, int fd, int chan, int c, int o, int v)
747 {
748 brightonEvent event;
749
750 /* printf("ms20IOSelect(%i, %i, %i)\n", c, o, v); */
751
752 if ((synth->flags & OPERATIONAL) == 0)
753 return;
754
755 event.command = BRIGHTON_PARAMCHANGE;
756
757 /*
758 * We have quite a lot of work here, we need to mark any output that is
759 * selected, if an input is selected then we should mark active the previous
760 * output to link them up and draw the desired layer item. We should keep
761 * all this in some structure such that it can be deconfigured, ie, patches
762 * can be removed.
763 *
764 * The structure we need should have an input and output list, this should
765 * give the true co-ords for the start and endpoint since it will be used
766 * to evaluate the transforms for the patch source to the on-screen dest
767 * bitmaps.
768 *
769 * There should also be a sanity check that clears any wayward output
770 * selections, required before saveMemory() can be called.
771 *
772 * We will probably need a selection of bitmaps so that we can simplify
773 * the stretch algorithm. If we only have one bitmaps then we need a more
774 * complex transform since the end points should not be stretched, only
775 * the intermittant cabling:
776 * cable source is 146bits, 3 for each end.
777 * Target length is 725 for example
778 * the 3 start and end pixels get copied,
779 * the middle 140 bits must be scaled to 719.
780 * The result should then be rotated into position.
781 */
782 if (c == 1)
783 {
784 if (v > 0)
785 oselect = o;
786 else
787 oselect = -1;
788
789 /*
790 * If we select an output that is assigned then clear it.
791 */
792 if (links[o].input > 0)
793 {
794 bristolMidiSendMsg(global.controlfd, synth->sid,
795 101, o, links[o].input);
796 links[o].input = 0;
797 event.type = BRIGHTON_UNLINK;
798 event.intvalue = links[o].id;
799 brightonParamChange(synth->win, 0, OUTPUT_START + o, &event);
800 }
801 } else if (c == 2) {
802 int i;
803
804 if (oselect >= 0) {
805 for (i = 0; i < MS20_OUTPUTS; i++)
806 {
807 if ((links[i].input > 0)
808 && (links[i].input == o))
809 {
810 int hold;
811
812 /* event.intvalue = links[i].id; */
813 /* event.type = BRIGHTON_UNLINK; */
814 /* brightonParamChange(synth->win, 0, OUTPUT_START+ i, &event); */
815 hold = oselect;
816 event.type = BRIGHTON_PARAMCHANGE;
817 event.value = 0;
818 brightonParamChange(synth->win, 0, OUTPUT_START+ i, &event);
819 oselect = hold;
820 }
821 }
822
823 synth->mem.param[OUTPUT_START + oselect] = o;
824 links[oselect].input = o;
825 /*
826 * Need to request the drawing of a link. We need to send a message
827 * that the library will interpret as a connection request.
828 * All we have is brighton param change. We should consider sending
829 * one message with each key click on an output, and another on
830 * each input - this is the only way we can get two panel numbers
831 * across, something we will eventually require.
832 brightonParamChange(synth->win, 1, INPUT_START + oselect,
833 &event);
834 */
835 bristolMidiSendMsg(global.controlfd, synth->sid, 100, oselect, o);
836 event.type = BRIGHTON_LINK;
837 event.intvalue = INPUT_START + o;
838 links[oselect].id =
839 brightonParamChange(synth->win, 0, OUTPUT_START + oselect,
840 &event);
841 } else {
842 /*
843 * See if this input is connected, if so clear it.
844 */
845 for (i = 0; i < MS20_OUTPUTS; i++)
846 {
847 if ((links[i].input > 0)
848 && (links[i].input == o))
849 {
850 /*
851 * What I need to do is send an event to the output device
852 * turning it off.
853 */
854 event.type = BRIGHTON_PARAMCHANGE;
855 event.value = 0;
856 brightonParamChange(synth->win, 0, OUTPUT_START+i, &event);
857 }
858 }
859 }
860
861 oselect = -1;
862 }
863 }
864
865 /*
866 * Any location initialisation required to run the callbacks. For bristol, this
867 * will connect to the engine, and give it some base parameters.
868 * May need to generate some application specific menus.
869 * Will also then make specific requests to some of the devices to alter their
870 * rendering.
871 */
872 static int
ms20Init(brightonWindow * win)873 ms20Init(brightonWindow *win)
874 {
875 guiSynth *synth = findSynth(global.synths, win);
876 dispatcher *dispatch;
877 int i;
878
879 if (synth == 0)
880 {
881 synth = findSynth(global.synths, 0);
882 if (synth == 0)
883 {
884 printf("cannot init\n");
885 return(0);
886 }
887 }
888
889 synth->win = win;
890
891 printf("Initialise the ms20 link to bristol: %p\n", synth->win);
892
893 synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
894 synth->mem.count = DEVICE_COUNT;
895 synth->mem.active = ACTIVE_DEVS;
896 synth->dispatch = (dispatcher *)
897 brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
898 dispatch = synth->dispatch;
899
900 /*
901 * We really want to have three connection mechanisms. These should be
902 * 1. Unix named sockets.
903 * 2. UDP sockets.
904 * 3. MIDI pipe.
905 */
906 if (!global.libtest)
907 if ((synth->sid = initConnection(&global, synth)) < 0)
908 return(-1);
909
910 /* for (i = 0; i < DEVICE_COUNT; i++) */
911 /* synth->dispatch[i].routine = ms20MidiSendMsg; */
912
913 for (i = 0; i < DEVICE_COUNT; i++)
914 {
915 /*
916 * This sets up the input and output code.
917 */
918 if (i >= MEM_START) {
919 synth->dispatch[i].controller = 0;
920 } else if (i >= INPUT_START) {
921 /* Inputs */
922 synth->dispatch[i].controller = 2;
923 synth->dispatch[i].operator = i - INPUT_START;
924 synth->dispatch[i].routine = (synthRoutine) ms20IOSelect;
925 } else if (i >= OUTPUT_START) {
926 /* Outputs */
927 synth->dispatch[i].controller = 1;
928 synth->dispatch[i].operator = i - OUTPUT_START;
929 synth->dispatch[i].routine = (synthRoutine) ms20IOSelect;
930 } else
931 synth->dispatch[i].routine = ms20MidiSendMsg;
932 }
933
934 /* memory */
935 dispatch[MEM_START].operator = 0;
936 dispatch[MEM_START].controller = MEM_START;
937 dispatch[MEM_START + 1].operator = 1;
938 dispatch[MEM_START + 1].controller = MEM_START + 1;
939 dispatch[MEM_START + 2].operator = 2;
940 dispatch[MEM_START + 2].controller = MEM_START + 2;
941 dispatch[MEM_START + 3].operator = 3;
942 dispatch[MEM_START + 3].controller = MEM_START + 3;
943 dispatch[MEM_START + 4].operator = 4;
944 dispatch[MEM_START + 4].controller = MEM_START + 4;
945 dispatch[MEM_START + 5].operator = 5;
946 dispatch[MEM_START + 5].controller = MEM_START + 5;
947 dispatch[MEM_START + 6].operator = 6;
948 dispatch[MEM_START + 6].controller = MEM_START + 6;
949 dispatch[MEM_START + 7].operator = 7;
950 dispatch[MEM_START + 7].controller = MEM_START + 7;
951 dispatch[MEM_START + 8].operator = 8;
952 dispatch[MEM_START + 8].controller = MEM_START + 8;
953 dispatch[MEM_START + 9].operator = 9;
954 dispatch[MEM_START + 9].controller = MEM_START + 9;
955
956 dispatch[MEM_START + 10].controller = 1;
957 dispatch[MEM_START + 11].controller = 2;
958 dispatch[MEM_START + 16].controller = 3;
959 dispatch[MEM_START + 17].controller = 4;
960
961 dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine =
962 dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine =
963 dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine =
964 dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine =
965 dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine =
966 dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine =
967 dispatch[MEM_START + 16].routine = dispatch[MEM_START + 17].routine =
968 (synthRoutine) ms20Memory;
969
970 /* midi */
971 dispatch[MEM_START + 12].controller = 2;
972 dispatch[MEM_START + 13].controller = 1;
973 dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine =
974 (synthRoutine) ms20Midi;
975
976 /* midi/panel selectors */
977 dispatch[MEM_START + 14].controller = MEM_START + 14;
978 dispatch[MEM_START + 15].controller = MEM_START + 15;
979 dispatch[MEM_START + 14].routine = dispatch[MEM_START + 15].routine =
980 (synthRoutine) ms20PanelSelect;
981 return(0);
982 }
983
984 /*
985 * This will be called to make any routine specific parameters available.
986 */
987 static int
ms20Configure(brightonWindow * win)988 ms20Configure(brightonWindow *win)
989 {
990 guiSynth *synth = findSynth(global.synths, win);
991 brightonEvent event;
992
993 if (synth == 0)
994 {
995 printf("problems going operational\n");
996 return(-1);
997 }
998
999 if (synth->flags & OPERATIONAL)
1000 return(0);
1001
1002 printf("going operational\n");
1003
1004 synth->flags |= OPERATIONAL;
1005 synth->keypanel = 1;
1006 synth->keypanel2 = -1;
1007 synth->transpose = 36;
1008
1009 displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1);
1010
1011 loadMemory(synth, "ms20", 0, synth->location, synth->mem.active,
1012 FIRST_DEV, 0);
1013 displayText(synth, "PRG", synth->location, DISPLAY2);
1014
1015 brightonPut(win,
1016 "bitmaps/blueprints/ms20shade.xpm", 0, 0, win->width, win->height);
1017
1018 /*
1019 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1020 * occurs on first paint, so we suppress the first paint then request
1021 * an expose here.
1022 */
1023 event.type = BRIGHTON_EXPOSE;
1024 event.intvalue = 1;
1025 brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1026
1027 return(0);
1028 }
1029
1030