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