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 /* ARP Arp2600 */
23 
24 #include <fcntl.h>
25 
26 #include "brighton.h"
27 #include "brightonMini.h"
28 #include "brightoninternals.h"
29 
30 static int arp2600Init();
31 static int arp2600Configure();
32 static int arp2600Callback(brightonWindow *, int, int, float);
33 /*static int keyCallback(void *, int, int, float); */
34 static int arp2600MidiCallback(brightonWindow *, int, int, float);
35 
36 extern guimain global;
37 
38 /* #include "brightonKeys.h" */
39 
40 #define DEVICE_COUNT 201
41 #define ARP_OUTPUTS 40
42 #define ARP_INPUTS 60
43 #define OUTPUT_START 82
44 #define ACTIVE_DEVS (OUTPUT_START + ARP_OUTPUTS)
45 #define INPUT_START ACTIVE_DEVS
46 #define MEM_START (DEVICE_COUNT - 19)
47 #define MIDI_START (MEM_START + 14)
48 
49 #define DISPLAY_DEV (DEVICE_COUNT - 2)
50 #define DISPLAY_DEV2 (DEVICE_COUNT - 1)
51 
52 #define KEY_PANEL 1
53 
54 static int oselect;
55 static struct {
56 	int input;
57 	int id; /* From graphical interface. */
58 } links[ARP_OUTPUTS];
59 
60 #define CDIFF 30
61 #define CDIFF2 12
62 #define CDIFF3 24
63 #define CDIFF4 23
64 #define CDIFF5 20
65 
66 #define C0 25
67 #define C1 47
68 #define C2 67
69 #define C3 110
70 #define C4 (C3 + CDIFF)
71 #define C5 (C4 + CDIFF3)
72 #define C6 (C5 + CDIFF3)
73 #define C7 (C6 + CDIFF3)
74 #define C8 (C7 + CDIFF)
75 #define C9 (C8 + CDIFF3)
76 #define C10 (C9 + CDIFF3 - 1)
77 #define C11 (C10 + CDIFF3)
78 #define C12 (C11 + CDIFF3)
79 #define C13 (C12 + CDIFF + 1)
80 #define C14 (C13 + CDIFF3)
81 #define C15 (C14 + CDIFF3)
82 #define C16 (C15 + CDIFF3)
83 #define C17 (C16 + CDIFF3 - 1)
84 #define C18 (C17 + CDIFF)
85 #define C19 (C18 + CDIFF3)
86 #define C20 (C19 + CDIFF3)
87 #define C21 (C20 + CDIFF3)
88 #define C22 (C21 + CDIFF3)
89 #define C23 (C22 + CDIFF3 - 2)
90 #define C24 (C23 + CDIFF3 + 1)
91 #define C25 (C24 + CDIFF3)
92 
93 #define C26 (C25 + CDIFF3 + 4)
94 #define C27 (C26 + CDIFF3)
95 #define C28 (C27 + CDIFF3 - 1)
96 #define C29 (C28 + CDIFF3)
97 #define C30 (C29 + CDIFF3 + 7)
98 #define C31 (C30 + CDIFF3 - 1)
99 #define C32 (C31 + CDIFF3)
100 #define C33 (C32 + CDIFF3)
101 #define C34 (C33 + CDIFF3 + 6)
102 #define C35 (C34 + CDIFF3)
103 #define C36 (C35 + CDIFF3 - 1)
104 #define C37 (C36 + CDIFF3)
105 
106 #define Cb0 602
107 #define Cb1 (Cb0 + CDIFF5)
108 #define Cb2 (Cb1 + CDIFF5)
109 #define Cb3 (Cb2 + CDIFF5)
110 #define Cb4 (Cb3 + CDIFF5 + 8)
111 #define Cb5 (Cb4 + CDIFF5)
112 #define Cb6 (Cb5 + CDIFF5)
113 #define Cb7 (Cb6 + CDIFF5)
114 #define Cb8 (Cb7 + CDIFF5)
115 
116 /* 244 */
117 #define Cb9 100
118 #define Cb10 (Cb9 + CDIFF4 + 1)
119 
120 /* 360 */
121 #define Cb11 498
122 #define Cb12 (Cb11 + CDIFF4 + 2)
123 
124 #define R0 365
125 #define R1 72
126 #define R2 217
127 #define R3 720
128 #define R5 185
129 #define R6 435
130 
131 #define W0 11
132 #define W1 12
133 #define W2 13
134 #define L1 160
135 
136 #define BDIFF (CDIFF + 2)
137 #define BDIFF2 (CDIFF2 + 2)
138 
139 #define B0 170
140 #define B1 (B0 + BDIFF + BDIFF2)
141 #define B2 (B1 + BDIFF)
142 #define B3 (B2 + BDIFF)
143 #define B4 (B3 + BDIFF)
144 #define B5 (B4 + BDIFF)
145 #define B6 (B5 + BDIFF)
146 #define B7 (B6 + BDIFF)
147 #define B8 (B7 + BDIFF)
148 #define B9 (B8 + BDIFF + BDIFF2)
149 #define B10 (B9 + BDIFF)
150 #define B11 (B10 + BDIFF)
151 #define B12 (B11 + BDIFF)
152 #define B13 (B12 + BDIFF)
153 #define B14 (B13 + BDIFF)
154 #define B15 (B14 + BDIFF)
155 #define B16 (B15 + BDIFF)
156 #define B17 (B16 + BDIFF + BDIFF2)
157 
158 #define B18 (BDIFF)
159 #define B19 (B18 + BDIFF + BDIFF)
160 
161 /*
162  * This structure is for device definition. The structure is defined in
163  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
164  * include/brightoninternals.h
165  *
166  *	typedef int (*brightonCallback)(int, float);
167  *	typedef struct BrightonLocations {
168  *		int device; 0=rotary, 1=scale, etc.
169  *		float relx, rely; relative position with regards to 1000 by 1000 window
170  *		float relw, relh; relative height.
171  *		int from, to;
172  *		brightonCallback callback; specific to this dev
173  *		char *image; bitmap. If zero take a device default.
174  *		int flags;
175  *	} brightonLocations;
176  *
177  * This example is for a arp2600Bristol type synth interface.
178  */
179 static brightonLocations locations[DEVICE_COUNT] = {
180 	{"EnvFollow Gain", 1, C0 - 2, R0, W2, L1, 0, 1, 0,
181 		"bitmaps/knobs/sliderblackl2.xpm", 0, 0},
182 	{"RM in1 level", 1, C2 - 2, R0, W2, L1, 0, 1, 0,
183 		"bitmaps/knobs/sliderblackl2.xpm", 0, 0},
184 	{"RM in2 level", 1, C3 - 1, R0, W1, L1, 0, 1, 0,
185 		"bitmaps/knobs/sliderblackl2.xpm", 0, 0},
186 
187 	/* Osc-1 - 3 */
188 	{"VCO1 Transpose", 1, C4 - 5, R5, 7, 80, 0, 4, 0,
189 		"bitmaps/buttons/klunk3.xpm", 0, 0},
190 /*		"bitmaps/knobs/sliderblackl2.xpm", 0, 0}, */
191 /*	{"", 1, C4 - 1, R0, W1, L1, 0, 1, 0, */
192 /*		"bitmaps/knobs/sliderblackl2.xpm", 0, 0}, */
193 	{"VCO1 Tracking", 2, C4 - 6, R6 - 8, 9, 45, 0, 2, 0,
194 		"bitmaps/buttons/klunk2.xpm", 0, BRIGHTON_THREEWAY},
195 	{"VCO1 FM Mod1 lvl", 1, C5, R0, W1, L1, 0, 1, 0,
196 		"bitmaps/knobs/sliderblackl.xpm", 0, 0},
197 	{"VCO1 FM Mod2 lvl", 1, C6, R0, W1, L1, 0, 1, 0,
198 		"bitmaps/knobs/sliderblackl.xpm", 0, 0},
199 	{"VCO1 FM Mod3 lvl", 1, C7, R0, W1, L1, 0, 1, 0,
200 		"bitmaps/knobs/sliderblackl.xpm", 0, 0},
201 	{"VCO1 Sync 2->1", 2, C5 + 17, R5 - 15, 16, 14, 0, 1, 0,
202 		"bitmaps/buttons/klunk2.xpm", 0, 0},
203 	{"VCO1 Tune Coarse", 1, 138, 77, 104, 30, 0, 1, 0,
204 		"bitmaps/knobs/sliderpointL.xpm", 0,
205 		BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH},
206 	{"VCO1 Tune Fine", 1, 138, 120, 104, 30, 0, 1, 0,
207 		"bitmaps/knobs/sliderpointL.xpm", 0,
208 		BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH},
209 
210 	/* Osc-2 - 11 */
211 	{"VCO2 Transpose", 1, C8 - 6, R5, 7, 80, 0, 4, 0,
212 		"bitmaps/buttons/klunk3.xpm", 0, 0},
213 /*		"bitmaps/knobs/sliderblackl.xpm", 0, 0}, */
214 /*	{"VCO2-Transpose", 1, C8, R0, W1, L1, 0, 1, 0, */
215 /*		"bitmaps/knobs/sliderblackl.xpm", 0, 0}, */
216 	{"VCO2 Tracking", 2, C8 - 7, R6 - 8, 9, 45, 0, 2, 0,
217 		"bitmaps/buttons/klunk2.xpm", 0, BRIGHTON_THREEWAY},
218 	{"VCO2 FM Mod1 lvl", 1, C9, R0, W0, L1, 0, 1, 0,
219 		"bitmaps/knobs/sliderblackl.xpm", 0, 0},
220 	{"VCO2 FM Mod2 lvl", 1, C10, R0, W0, L1, 0, 1, 0,
221 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
222 	{"VCO2 FM Mod2 lvl", 1, C11, R0, W0, L1, 0, 1, 0,
223 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
224 	{"VCO2 PWM", 1, C12, R0, W0, L1, 0, 1, 0,
225 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
226 	{"VCO2 Tune Coarse", 1, 250, 77, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
227         BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH},
228 	{"VCO2 Tune Fine", 1, 250, 120, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
229         BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH},
230 	{"VCO2 PW", 1, 250, 165, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
231 		BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
232 
233 	/* Osc-3 - 20 */
234 	{"VCO3 Transpose", 1, C13 - 6, R5, 7, 80, 0, 4, 0,
235 		"bitmaps/buttons/klunk3.xpm", 0, 0},
236 /*		"bitmaps/knobs/sliderblack2.xpm", 0, 0}, */
237 /*	{"VCO3 Transpose", 1, C13, R0, W1, L1, 0, 1, 0, */
238 /*		"bitmaps/knobs/sliderblack2.xpm", 0, 0}, */
239 	{"VCO3 Tracking", 2, C13 - 7, R6 - 8, 9, 45, 0, 2, 0,
240 		"bitmaps/buttons/klunk2.xpm", 0, BRIGHTON_THREEWAY},
241 	{"VCO3 FM Mod1 lvl", 1, C14, R0, W0, L1, 0, 1, 0,
242 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
243 	{"VCO3 FM Mod2 lvl", 1, C15, R0, W0, L1, 0, 1, 0,
244 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
245 	{"VCO3 FM Mod3 lvl", 1, C16, R0, W0, L1, 0, 1, 0,
246 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
247 	{"VCO3 PWM", 1, C17, R0, W0, L1, 0, 1, 0,
248 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
249 	{"VCO3 Tune Coarse", 1, 376, 77, 104, 30, 0, 1, 0,
250 		"bitmaps/knobs/sliderpoint.xpm", 0,
251         BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH},
252 	{"VCO3 Tune Fine", 1, 376, 120, 104, 30, 0, 1, 0,
253 		"bitmaps/knobs/sliderpoint.xpm", 0,
254         BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH},
255 	{"VCO3 PW", 1, 376, 165, 104, 30, 0, 1, 0,
256 		"bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
257 
258 	/* VCF - 29 */
259 /*	{"", 1, C23 + 11, R1 + 14, 8, 78, 0, 4, 0, */
260 /*		"bitmaps/knobs/sliderblack2.xpm", 0, 0}, */
261 	{"VCF Mix1 lvl", 1, C18, R0, W0, L1, 0, 1, 0,
262 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
263 	{"VCF Mix2 lvl", 1, C19, R0, W0, L1, 0, 1, 0,
264 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
265 	{"VCF Mix3 lvl", 1, C20, R0, W0, L1, 0, 1, 0,
266 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
267 	{"VCF Mix4 lvl", 1, C21, R0, W0, L1, 0, 1, 0,
268 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
269 	{"VCF Mix5 lvl", 1, C22, R0, W0, L1, 0, 1, 0,
270 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
271 	{"VCF Mod1 lvl", 1, C23, R0, W0, L1, 0, 1, 0,
272 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
273 	{"VCF Mod2 lvl", 1, C24, R0, W0, L1, 0, 1, 0,
274 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
275 	{"VCF Mod3 lvl", 1, C25, R0, W0, L1, 0, 1, 0,
276 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
277 	{"VCF Cutoff", 1, 534, 77, 104, 30, 0, 1, 0,
278 		"bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
279 	{"VCF Resonance", 1, 534, 120, 104, 30, 0, 1, 0,
280 		"bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
281 /*	{"", 1, 500, 165, 104, 30, 0, 1, 0, */
282 /*		"bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, */
283 /*	{"", 1, 500, 208, 104, 30, 0, 1, 0, */
284 /*		"bitmaps/knobs/sliderpoint.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE}, */
285 
286 	/* ADSR/AR - 39 */
287 	{"Attack", 1, C26, R1, W1, L1, 0, 1, 0,
288 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
289 	{"Decay", 1, C27, R1, W1, L1, 0, 1, 0,
290 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
291 	{"Sustain", 1, C28, R1, W1, L1, 0, 1, 0,
292 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
293 	{"Release", 1, C29, R1, W1, L1, 0, 1, 0,
294 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
295 	{"AR Attack", 1, C26, R0, W1, L1, 0, 1, 0,
296 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
297 	{"AR Release", 1, C29, R0, W1, L1, 0, 1, 0,
298 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
299 	{"AR Gate", 2, C27 - 4, 474, 8, 25, 0, 1, 0,
300 		"bitmaps/buttons/klunk2.xpm", 0, BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
301 
302 	/* ?? - 46 */
303 	{"VCA Mix1 lvl", 1, C30, R0, W1, L1, 0, 1, 0,
304 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
305 	{"VCA Mix2 lvl", 1, C31, R0, W1, L1, 0, 1, 0,
306 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
307 	{"VCA Mod1 lvl", 1, C32, R0, W1, L1, 0, 1, 0,
308 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
309 	{"VCA Mod2 lvl", 1, C33, R0, W2, L1, 0, 1, 0,
310 		"bitmaps/knobs/sliderblackr2.xpm", 0, 0},
311 	/* Mixer */
312 	{"Mix lvl1", 1, C34 + 1, R0, W2, L1, 0, 1, 0,
313 		"bitmaps/knobs/sliderblackr2.xpm", 0, 0},
314 	{"Mix lvl2", 1, C35 + 1, R0, W2, L1, 0, 1, 0,
315 		"bitmaps/knobs/sliderblackr2.xpm", 0, 0},
316 
317 	/* Effects return - 52 */
318 	{"FX Return Left", 1, C36 + 2, R2, W2, L1, 0, 1, 0,
319 		"bitmaps/knobs/sliderblackr2.xpm", 0, 0},
320 	{"FX Return Right", 1, C37 + 2, R2, W2, L1, 0, 1, 0,
321 		"bitmaps/knobs/sliderblackr2.xpm", 0, 0},
322 
323 	/* - 54 */
324 	{"Chorus D1", 1, Cb0, R3, W0, L1, 0, 1, 0,
325 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
326 	{"Chorus D2", 1, Cb1, R3, W0, L1, 0, 1, 0,
327 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
328 	{"Chorus D3", 1, Cb2, R3, W0, L1, 0, 1, 0,
329 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
330 	{"Chorus D4", 1, Cb3, R3, W0, L1, 0, 1, 0,
331 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
332 
333 	/* - 58 */
334 	{"Reverb D1", 1, Cb4, R3, W0, L1, 0, 1, 0,
335 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
336 	{"Reverb D2", 1, Cb5, R3, W0, L1, 0, 1, 0,
337 		"bitmaps/knobs/sliderblackr.xpm", 0, 0},
338 	{"Reverb D3", 1, Cb6, R3, W1, L1, 0, 1, 0,
339 		"bitmaps/knobs/sliderblackr2.xpm", 0, 0},
340 	{"Reverb D4", 1, Cb7, R3, W1, L1, 0, 1, 0,
341 		"bitmaps/knobs/sliderblackr2.xpm", 0, 0},
342 	/* Manual start */
343 	{"", 2, 712, 382, 12, 15, 0, 1, 0, "bitmaps/buttons/patchlow.xpm",
344 		"bitmaps/buttons/patchon.xpm", BRIGHTON_NOSHADOW},
345 
346 	/* - 63 */
347 	{"Noise White/Pink", 1, Cb9, R3, W1, L1, 0, 1, 0,
348 		"bitmaps/knobs/sliderblackl2.xpm", 0, 0},
349 	{"Noise Level", 1, Cb10, R3, W1, L1, 0, 1, 0,
350 		"bitmaps/knobs/sliderblackl2.xpm", 0, 0},
351 
352 	/*; - 65 */
353 	{"LFO Level", 1, Cb11, R3, W0, L1, 0, 1, 0,
354 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
355 	{"LFO Rate", 1, Cb12, R3, W0, L1, 0, 1, 0,
356 		"bitmaps/knobs/sliderblack2.xpm", 0, 0},
357 
358 	/* - 67 */
359 	{"LFO Sync", 2, Cb12 + 5, 920, 16, 14, 0, 1, 0,
360 		"bitmaps/buttons/klunk2.xpm", 0, 0},
361 
362 	/* Global (now program) Volume - 68 */
363 	{"Volume Program", 1, 786, 120, 104, 30, 0, 1, 0,
364 		"bitmaps/knobs/sliderpointR.xpm", 0,BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
365 	{"Volume Pan", 1, 888, 120, 104, 30, 0, 1, 0,
366 		"bitmaps/knobs/sliderpointR.xpm", 0,BRIGHTON_VERTICAL|BRIGHTON_REVERSE|
367 		BRIGHTON_NOTCH},
368 
369 	/* Input gain and glide */
370 	{"Input Gain", 0, 47, 78, 50, 50, 0, 1, 0,
371 		"bitmaps/knobs/knobgreynew.xpm",
372 		"bitmaps/knobs/alpharotary.xpm", 0},
373 	{"Glide", 0, 101, 78, 50, 50, 0, 1, 0,
374 		"bitmaps/knobs/knobgreynew.xpm",
375 		"bitmaps/knobs/alpharotary.xpm", 0},
376 
377 	/* Voltage processors */
378 	{"Mix1 Gain1", 1, 243, 711, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
379         BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
380 	{"Mix1 Gain2", 1, 243, 767, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
381         BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
382 	{"Mix2 Gain2", 1, 243, 821, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
383         BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
384 	{"Mix3 LagRate", 1, 243, 881, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
385         BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
386 
387 	/* MARK used one dummy for VCA initial volume */
388 	{"VCA Initial Vol", 1, 786, 163, 104, 30, 0, 1, 0,
389 		"bitmaps/knobs/sliderpointR.xpm", 0,BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
390 	/* DUMMIES */
391 	{"", 1, 0, 0, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
392         BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN},
393 	{"", 1, 0, 0, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
394         BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN},
395 	{"", 1, 0, 0, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
396         BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN},
397 	{"", 1, 0, 0, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
398         BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN},
399 	{"", 1, 0, 0, 104, 30, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
400         BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN},
401 
402 	/*
403 	 * These are the patch buttons. Positions are unfortunately arbitrary.
404 	 * First the outputs, then the inputs.
405 	 */
406 	/* 82 */
407 	{"Output Preamp", 2, 110, 213, 12, 15, 0, 1, 0,
408 		"bitmaps/buttons/patchoff.xpm",
409 		"bitmaps/buttons/patchonl.xpm", 0},
410 	{"", 2, 110, 280, 12, 15, 0, 1, 0,
411 		"bitmaps/buttons/patchoff.xpm",
412 		"bitmaps/buttons/patchonl.xpm", 0},
413 	{"", 2, 46, 439, 12, 15, 0, 1, 0,
414 		"bitmaps/buttons/patchoff.xpm",
415 		"bitmaps/buttons/patchonl.xpm", 0},
416 	/* VCO1 */
417 	{"", 2, 212, 249, 12, 15, 0, 1, 0,
418 		"bitmaps/buttons/patchoff.xpm",
419 		"bitmaps/buttons/patchonl.xpm", 0},
420 	{"", 2, 212, 316, 12, 15, 0, 1, 0,
421 		"bitmaps/buttons/patchoff.xpm",
422 		"bitmaps/buttons/patchonl.xpm", 0},
423 	/* VCO2 */
424 	{"", 2, 313, 249, 12, 15, 0, 1, 0,
425 		"bitmaps/buttons/patchoff.xpm",
426 		"bitmaps/buttons/patchonl.xpm", 0},
427 	{"", 2, 313, 316, 12, 15, 0, 1, 0,
428 		"bitmaps/buttons/patchoff.xpm",
429 		"bitmaps/buttons/patchonl.xpm", 0},
430 	{"", 2, 337, 249, 12, 15, 0, 1, 0,
431 		"bitmaps/buttons/patchoff.xpm",
432 		"bitmaps/buttons/patchonl.xpm", 0},
433 	{"", 2, 337, 316, 12, 15, 0, 1, 0,
434 		"bitmaps/buttons/patchoff.xpm",
435 		"bitmaps/buttons/patchonl.xpm", 0},
436 	/* VCO3 */
437 	{"", 2, 438, 249, 12, 15, 0, 1, 0,
438 		"bitmaps/buttons/patchoff.xpm",
439 		"bitmaps/buttons/patchonl.xpm", 0},
440 	{"", 2, 438, 316, 12, 15, 0, 1, 0,
441 		"bitmaps/buttons/patchoff.xpm",
442 		"bitmaps/buttons/patchonl.xpm", 0},
443 	{"", 2, 462, 249, 12, 15, 0, 1, 0,
444 		"bitmaps/buttons/patchoff.xpm",
445 		"bitmaps/buttons/patchonl.xpm", 0},
446 	{"", 2, 462, 316, 12, 15, 0, 1, 0,
447 		"bitmaps/buttons/patchoff.xpm",
448 		"bitmaps/buttons/patchonl.xpm", 0},
449 	/* VCF */
450 	{"", 2, 660, 287, 12, 15, 0, 1, 0,
451 		"bitmaps/buttons/patchoff.xpm",
452 		"bitmaps/buttons/patchonl.xpm", 0},
453 	/* ADSR */
454 	{"", 2, 760, 287, 12, 15, 0, 1, 0,
455 		"bitmaps/buttons/patchoff.xpm",
456 		"bitmaps/buttons/patchonl.xpm", 0},
457 	{"", 2, 735, 382, 12, 15, 0, 1, 0,
458 		"bitmaps/buttons/patchoff.xpm",
459 		"bitmaps/buttons/patchonl.xpm", 0},
460 	{"", 2, 864, 287, 12, 15, 0, 1, 0,
461 		"bitmaps/buttons/patchoff.xpm",
462 		"bitmaps/buttons/patchonl.xpm", 0},
463 	/* Mix out */
464 	{"", 2, 902, 235, 12, 15, 0, 1, 0,
465 		"bitmaps/buttons/patchoff.xpm",
466 		"bitmaps/buttons/patchonl.xpm", 0},
467 	/* Noise/SH/Switch */
468 	{"", 2, 146, 797, 12, 15, 0, 1, 0,
469 		"bitmaps/buttons/patchoff.xpm",
470 		"bitmaps/buttons/patchonl.xpm", 0},
471 	/* SH/Switch - 324 */
472 	{"", 2, 463, 797, 12, 15, 0, 1, 0,
473 		"bitmaps/buttons/patchoff.xpm",
474 		"bitmaps/buttons/patchonl.xpm", 0},
475 	{"", 2, 560, 666, 12, 15, 0, 1, 0,
476 		"bitmaps/buttons/patchoff.xpm",
477 		"bitmaps/buttons/patchonl.xpm", 0},
478 	{"", 2, 560, 906, 12, 15, 0, 1, 0,
479 		"bitmaps/buttons/patchoff.xpm",
480 		"bitmaps/buttons/patchonl.xpm", 0},
481 	{"", 2, 891, 339, 12, 15, 0, 1, 0,
482 		"bitmaps/buttons/patchoff.xpm",
483 		"bitmaps/buttons/patchonl.xpm", 0},
484 	{"", 2, 915, 339, 12, 15, 0, 1, 0,
485 		"bitmaps/buttons/patchoff.xpm",
486 		"bitmaps/buttons/patchonl.xpm", 0},
487 	/* Voltage Processor Outputs */
488 	{"", 2, 411, 734, 12, 15, 0, 1, 0,
489 		"bitmaps/buttons/patchoff.xpm",
490 		"bitmaps/buttons/patchonl.xpm", 0},
491 	{"", 2, 411, 792, 12, 15, 0, 1, 0,
492 		"bitmaps/buttons/patchoff.xpm",
493 		"bitmaps/buttons/patchonl.xpm", 0},
494 	{"", 2, 411, 832, 12, 15, 0, 1, 0,
495 		"bitmaps/buttons/patchoff.xpm",
496 		"bitmaps/buttons/patchonl.xpm", 0},
497 	{"", 2, 411, 886, 12, 15, 0, 1, 0,
498 		"bitmaps/buttons/patchoff.xpm",
499 		"bitmaps/buttons/patchonl.xpm", 0},
500 	/* Reverb R out */
501 	{"", 2, 961, 505, 12, 15, 0, 1, 0,
502 		"bitmaps/buttons/patchoff.xpm",
503 		"bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
504 	/* CV/Audio inputs */
505 	{"", 2, 30, 716, 12, 15, 0, 1, 0,
506 		"bitmaps/buttons/patchoff.xpm",
507 		"bitmaps/buttons/patchonl.xpm", 0},
508 	{"", 2, 30, 772, 12, 15, 0, 1, 0,
509 		"bitmaps/buttons/patchoff.xpm",
510 		"bitmaps/buttons/patchonl.xpm", 0},
511 	{"", 2, 30, 826, 12, 15, 0, 1, 0,
512 		"bitmaps/buttons/patchoff.xpm",
513 		"bitmaps/buttons/patchonl.xpm", 0},
514 	{"", 2, 30, 886, 12, 15, 0, 1, 0,
515 		"bitmaps/buttons/patchoff.xpm",
516 		"bitmaps/buttons/patchonl.xpm", 0},
517 	/* DUMMIES */
518 	{"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
519 		"bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
520 	{"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
521 		"bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
522 	{"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
523 		"bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
524 	{"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
525 		"bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
526 	{"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
527 		"bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
528 	{"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
529 		"bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
530 	{"", 2, 0, 0, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoff.xpm",
531 		"bitmaps/buttons/patchonl.xpm", BRIGHTON_WITHDRAWN},
532 	/*
533 	 * Inputs. From the envelope follower onwards, these offset start from '1'
534 	 * rather than from zero, this corrected later in the code.
535 	 */
536 	{"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
537 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
538 	{"Input EnvFollow", 2, 24, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
539 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
540 	{"", 2, 67, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
541 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
542 	{"", 2, 110, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
543 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
544 	/* VCO1 - the KDB CV input is disabled - FFS in engine. */
545 	{"", 2, 140, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
546 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
547 	{"", 2, 164, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
548 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
549 	{"", 2, 188, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
550 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
551 	{"", 2, 212, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
552 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
553 	/* VCO2 */
554 	{"", 2, 242, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
555 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
556 	{"", 2, 266, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
557 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
558 	{"", 2, 289, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
559 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
560 	{"", 2, 313, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
561 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
562 	{"", 2, 337, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
563 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
564 	/* VCO3 12 */
565 	{"", 2, 367, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
566 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
567 	{"", 2, 391, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
568 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
569 	{"", 2, 415, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
570 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
571 	{"", 2, 438, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
572 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
573 	{"", 2, 462, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
574 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
575 	/* VCF */
576 	{"", 2, 493, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
577 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
578 	{"", 2, 516, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
579 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
580 	{"", 2, 540, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
581 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
582 	{"", 2, 564, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
583 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
584 	{"", 2, 588, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
585 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
586 	{"", 2, 611, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
587 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
588 	{"", 2, 635, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
589 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
590 	{"", 2, 659, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
591 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
592 	/* Envelopes, etc. */
593 	{"", 2, 687, 287, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
594 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
595 	{"", 2, 710, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
596 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
597 	{"", 2, 734, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
598 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
599 	{"", 2, 758, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
600 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
601 	/* AMP, etc. */
602 	{"", 2, 789, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
603 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
604 	{"", 2, 813, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
605 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
606 	{"", 2, 837, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
607 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
608 	{"", 2, 861, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
609 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
610 	/* The rest */
611 	{"", 2, 891, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
612 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
613 	{"", 2, 915, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
614 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
615 	{"", 2, 938, 552, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
616 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
617 	/* Lin, Rin */
618 	{"", 2, 891, 180, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
619 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
620 	{"", 2, 961, 180, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
621 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
622 	/* Electro inputs */
623 	{"", 2, 560, 754, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
624 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
625 	{"", 2, 560, 797, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
626 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
627 	/* Noise into SH */
628 	{"", 2, 463, 666, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
629 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
630 	/* Ext and switch clock */
631 	{"", 2, 324, 886, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
632 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
633 	{"", 2, 544, 864, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
634 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
635 	/* Pan */
636 	{"", 2, 915, 180, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
637 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
638 	/* Voltage Processor inputs */
639 	{"", 2, 197, 716, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
640 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
641 	{"", 2, 197, 772, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
642 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
643 	{"", 2, 197, 826, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
644 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
645 	{"", 2, 197, 886, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
646 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
647 	{"", 2, 362, 690, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
648 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
649 	{"", 2, 362, 746, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
650 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
651 	{"", 2, 362, 802, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
652 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
653 	/* CV/Audio inputs */
654 	{"", 2, 950, 716, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
655 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
656 	{"", 2, 950, 772, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
657 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
658 	{"", 2, 950, 826, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
659 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
660 	{"", 2, 950, 886, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
661 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON},
662 	/* DUMMIES */
663 	{"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
664 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
665 	{"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
666 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
667 	{"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
668 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
669 	{"", 2, 900, 900, 12, 15, 0, 1, 0, "bitmaps/buttons/patchoffb.xpm",
670 		"bitmaps/buttons/patchon.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
671 
672 #define XS 808
673 #define XD 30
674 #define YS 730
675 #define YD 35
676 
677 #define XSZ 19
678 #define YSZ 26
679 
680 	/* L-S-0 */
681 	{"", 2, XS, YS+3*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/L.xpm",
682 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
683 	{"", 2, XS+2*XD, YS+3*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/S.xpm",
684 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
685 	{"", 2, XS+XD, YS+3*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/0.xpm",
686 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
687 
688 	/* 1-2-3 */
689 	{"", 2, XS, YS, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/1.xpm",
690 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
691 	{"", 2, XS+XD, YS, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/2.xpm",
692 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
693 	{"", 2, XS+2*XD, YS, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/3.xpm",
694 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
695 
696 	/* 4-5-6 */
697 	{"", 2, XS, YS+1*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/4.xpm",
698 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
699 	{"", 2, XS+XD, YS+1*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/5.xpm",
700 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
701 	{"", 2, XS+2*XD, YS+1*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/6.xpm",
702 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
703 
704 	/* 7-8-9 */
705 	{"", 2, XS, YS+2*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/7.xpm",
706 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
707 	{"", 2, XS+XD, YS+2*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/8.xpm",
708 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
709 	{"", 2, XS+2*XD, YS+2*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/9.xpm",
710 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
711 
712 	/* U-P */
713 	{"", 2, XS, YS+4*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/Down.xpm",
714 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
715 	{"", 2, XS+2*XD, YS+4*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/Up.xpm",
716 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
717 
718 	{"", 2, XS, YS+5*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/Down.xpm",
719 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
720 	{"", 2, XS+2*XD, YS+5*YD, XSZ, YSZ, 0, 1, 0, "bitmaps/digits/Up.xpm",
721 		"bitmaps/buttons/jellyon.xpm", BRIGHTON_CHECKBUTTON},
722 
723 	/* MARK Stuff in another control for Global Volume */
724 	{"", 1, 786, 77, 104, 30, 0, 1, 0,
725 		"bitmaps/knobs/sliderpointR.xpm", 0,BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
726 	/* Display */
727 	{"", 3, 797, 670, 100, YSZ, 0, 1, 0, 0,
728 		"bitmaps/images/alphadisplay3.xpm", 0}, /*display 60 */
729 	{"", 3, 797, 695, 100, YSZ, 0, 1, 0, 0,
730 		"bitmaps/images/alphadisplay2.xpm", 0}, /*display 60 */
731 /*		0, 0}, //display 60 */
732 };
733 
734 /*
735  */
736 
737 /*
738  * This is a set of globals for the main window rendering. Again taken from
739  * include/brighton.h
740  */
741 brightonApp arp2600App = {
742 	"arp2600",
743 	0, /* no blueprint on wood background. */
744 	"bitmaps/textures/metal4.xpm",
745 	0, /* BRIGHTON_STRETCH, //flags */
746 	arp2600Init,
747 	arp2600Configure, /* 3 callbacks, unused? */
748 	arp2600MidiCallback,
749 	destroySynth,
750 	{1, 100, 3, 2, 5, 520, 0, 0},
751 	886, 500, 0, 0,
752 	1, /* Panels */
753 	{
754 		{
755 			"Arp2600",
756 			"bitmaps/blueprints/arp2600.xpm",
757 			/*"bitmaps/textures/metal4.xpm", */
758 			"bitmaps/textures/metal2.xpm",
759 			/*"bitmaps/textures/bluemeanie.xpm", */
760 			BRIGHTON_STRETCH, /* flags */
761 			0,
762 			0,
763 			arp2600Callback,
764 			0, 0, 1000, 1000,
765 			DEVICE_COUNT,
766 			locations
767 		}
768 	}
769 };
770 
771 static int
arp2600MidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)772 arp2600MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
773 {
774 	bristolMidiSendMsg(fd, chan, c, o, v);
775 	return(0);
776 }
777 
778 /*
779  * This is a shim, when loading a memory we have to clear out all existing
780  * patches and then re-request them afterwards. This is a slow memory operation
781  * since we have to unpatch everything before the memory can be allocated.
782  *
783  * This could be improved.
784  */
785 static int
arp2600LoadMemory(guiSynth * synth,char * n,char * a,int b,int c,int d,int e)786 arp2600LoadMemory(guiSynth *synth, char *n, char *a, int b, int c, int d, int e)
787 {
788 	brightonEvent event;
789 	int i, result;
790 
791 	if (e == 0)
792 	{
793 		for (i = 0; i < ARP_OUTPUTS; i++)
794 		{
795 			if (links[i].input > 0)
796 			{
797 /*				printf("Mem disconnecting %i from %i", i, links[i].input); */
798 				event.type = BRIGHTON_UNLINK;
799 				event.intvalue = 16382;
800 				brightonParamChange(synth->win, 0, OUTPUT_START+ i, &event);
801 				for (i = 0; i < ARP_OUTPUTS; i++)
802 				{
803 					links[i].input = -1;
804 					links[i].id = -1;
805 				}
806 				break;
807 			}
808 		}
809 
810 		/*
811 		 * This is used to ensure we could not have left any patches hanging in
812 		 * the engine. We could use a similar 'clear all' operation for the GUI
813 		 * so speed things up?
814 		 */
815 		bristolMidiSendMsg(global.controlfd, synth->sid, 102, 0, 0);
816 	}
817 
818 	result = loadMemory(synth, n, a, b, c, d, e);
819 
820 	/*
821 	 * See if we need to patch things back in.
822 	 */
823 	if (e == 0)
824 	{
825 		for (i = 0; i < ARP_OUTPUTS; i++)
826 		{
827 			links[i].input = -1;
828 			links[i].id = -1;
829 
830 			if (synth->mem.param[OUTPUT_START + i] > 0)
831 			{
832 				int connect = synth->mem.param[OUTPUT_START + i];
833 
834 /*				printf("Mem connecting %i to %1.0f\n", i, */
835 /*					synth->mem.param[OUTPUT_START + i]); */
836 
837 				/*
838 				 * Select the input, request a link for the GUI and then the
839 				 * link request to the engine.
840 				 */
841 				event.type = BRIGHTON_PARAMCHANGE;
842 				event.value = 1;
843 				brightonParamChange(synth->win, 0, OUTPUT_START + i, &event);
844 
845 				event.type = BRIGHTON_LINK;
846 				event.intvalue = INPUT_START + connect;
847 				links[oselect].input = connect;
848 				links[oselect].id =
849 					brightonParamChange(synth->win, 0, OUTPUT_START + i,
850 						&event);
851 
852 				/*
853 				 * This call could be put into another early cycle through the
854 				 * table. This would cause the engine to be patched almost
855 				 * immediately, and the GUI would follow shortly afterwards.
856 				 *
857 				 * Subtraction of 1 is due to offset differences
858 				 */
859 				bristolMidiSendMsg(global.controlfd, synth->sid, 100, i,
860 					connect - 1);
861 
862 				synth->mem.param[OUTPUT_START + i] = connect;
863 			}
864 		}
865 		oselect = -1;
866 
867 		/* PW Osc-1 */
868 		bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 16383);
869 	}
870 
871 	return(result);
872 }
873 
874 static int
arp2600MidiCallback(brightonWindow * win,int command,int value,float v)875 arp2600MidiCallback(brightonWindow *win, int command, int value, float v)
876 {
877 	guiSynth *synth = findSynth(global.synths, win);
878 
879 	printf("midi callback: %x, %i\n", command, value);
880 
881 	switch(command)
882 	{
883 		case MIDI_PROGRAM:
884 			printf("midi program: %x, %i\n", command, value);
885 			synth->location = value;
886 
887 			arp2600LoadMemory(synth, "arp2600", 0,
888 				synth->location, synth->mem.active, 0, 0);
889 
890 			break;
891 		case MIDI_BANK_SELECT:
892 			printf("midi banksel: %x, %i\n", command, value);
893 			synth->bank = value;
894 			break;
895 	}
896 	return(0);
897 }
898 
899 static int
arp2600Memory(guiSynth * synth,int fd,int chan,int c,int o,int v)900 arp2600Memory(guiSynth *synth, int fd, int chan, int c, int o, int v)
901 {
902 /*	printf("	arp2600Memory(B: %i L %i: %i, %i)\n", */
903 /*		synth->bank, synth->location, c, o); */
904 
905 	switch (c) {
906 		default:
907 		case 0:
908 			synth->location = synth->location * 10 + o;
909 
910 			if (synth->location >= 1000)
911 				synth->location = o;
912 			if (loadMemory(synth, "arp2600", 0, synth->location,
913 				synth->mem.active, 0, BRISTOL_STAT) < 0)
914 				displayText(synth, "FRE", synth->location, DISPLAY_DEV);
915 			else
916 				displayText(synth, "PRG", synth->location, DISPLAY_DEV);
917 			break;
918 		case 1:
919 			arp2600LoadMemory(synth, "arp2600", 0, synth->location,
920 				synth->mem.active, 0, 0);
921 			displayText(synth, "PRG", synth->location, DISPLAY_DEV);
922 			break;
923 		case 2:
924 			/*
925 			 * Before we can save a memory we have to merge our links into
926 			 * the mem buffer
927 			 */
928 			saveMemory(synth, "arp2600", 0, synth->location, 0);
929 			displayText(synth, "PRG", synth->location, DISPLAY_DEV);
930 			break;
931 		case 3:
932 			/*
933 			 * Go through the memories, but do not load any of them. This will
934 			 * break when we find a used one.
935 			 */
936 			while (arp2600LoadMemory(synth, "arp2600", 0, --synth->location,
937 				synth->mem.active, 0, 1) < 0)
938 			{
939 				if (synth->location < 0)
940 				{
941 					synth->location = 1000;
942 				}
943 			}
944 			/* Then load it */
945 			arp2600LoadMemory(synth, "arp2600", 0, synth->location,
946 				synth->mem.active, 0, 0);
947 			displayText(synth, "PRG", synth->location, DISPLAY_DEV);
948 			break;
949 		case 4:
950 			/*
951 			 * Go through the memories, but do not load any of them. This will
952 			 * break when we find a used one.
953 			 */
954 			while (arp2600LoadMemory(synth, "arp2600", 0, ++synth->location,
955 				synth->mem.active, 0, 1) < 0)
956 			{
957 				if (synth->location > 999)
958 				{
959 					synth->location = -1;
960 				}
961 			}
962 			/* Then load it */
963 			arp2600LoadMemory(synth, "arp2600", 0, synth->location,
964 				synth->mem.active, 0, 0);
965 			displayText(synth, "PRG", synth->location, DISPLAY_DEV);
966 			break;
967 	}
968 	return(0);
969 }
970 
971 static int
arp2600Midi(guiSynth * synth,int fd,int chan,int c,int o,int v)972 arp2600Midi(guiSynth *synth, int fd, int chan, int c, int o, int v)
973 {
974 	int newchan;
975 
976 	if ((synth->flags & OPERATIONAL) == 0)
977 		return(0);
978 
979 	if (c == 1) {
980 		if ((newchan = synth->midichannel - 1) < 0)
981 		{
982 			newchan = synth->midichannel = 0;
983 			displayText(synth, "MIDI", newchan + 1, DISPLAY_DEV2);
984 			return(0);
985 		}
986 	} else {
987 		if ((newchan = synth->midichannel + 1) >= 16)
988 		{
989 			newchan = synth->midichannel = 15;
990 			displayText(synth, "MIDI", newchan + 1, DISPLAY_DEV2);
991 			return(0);
992 		}
993 	}
994 
995 	displayText(synth, "MIDI", newchan + 1, DISPLAY_DEV2);
996 
997 	if (global.libtest == 0)
998 	{
999 		/*
1000 		 * To overcome that we should consider checking a sequence number in
1001 		 * the message library? That is non trivial since it requires that
1002 		 * our midi messges have a 'ack' flag included - we cannot check for
1003 		 * ack here (actually, we could, and in the app is probably the right
1004 		 * place to do it rather than the lib however both would have to be
1005 		 * changed to suppor this - nc).
1006 		 */
1007 		bristolMidiSendMsg(global.controlfd, synth->sid,
1008 			127, 0, BRISTOL_MIDICHANNEL|newchan);
1009 	}
1010 
1011 	synth->midichannel = newchan;
1012 	return(0);
1013 }
1014 
1015 /*
1016  * For the sake of ease of use, links have been placed here to be called
1017  * by any of the devices created. They would be better in some other file,
1018  * perhaps with this as a dispatch.
1019  *
1020  * Param refers to the device index in the locations table given below.
1021  */
1022 static int
arp2600Callback(brightonWindow * win,int panel,int index,float value)1023 arp2600Callback(brightonWindow * win, int panel, int index, float value)
1024 {
1025 	guiSynth *synth = findSynth(global.synths, win);
1026 	int sendvalue;
1027 
1028 	/* printf("arp2600Callback(%i, %f): %x\n", index, value, synth); */
1029 
1030 	if (synth == 0)
1031 		return(0);
1032 
1033 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
1034 		return(0);
1035 
1036 	if (arp2600App.resources[0].devlocn[index].to == 1.0)
1037 		sendvalue = value * (CONTROLLER_RANGE - 1);
1038 	else
1039 		sendvalue = value;
1040 
1041 	synth->mem.param[index] = value;
1042 
1043 	/*if ((!global.libtest) || (index >= ACTIVE_DEVS)) */
1044 	if ((!global.libtest) || (index >= 71))
1045 		synth->dispatch[index].routine(synth,
1046 			global.controlfd, synth->sid,
1047 			synth->dispatch[index].controller,
1048 			synth->dispatch[index].operator,
1049 			sendvalue);
1050 
1051 #ifdef DEBUG
1052 	else
1053 		printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index,
1054 			global.controlfd, synth->sid,
1055 			synth->dispatch[index].controller,
1056 			synth->dispatch[index].operator,
1057 			sendvalue);
1058 #endif
1059 
1060 	return(0);
1061 }
1062 
1063 static int
arp2600Volume(guiSynth * synth,int fd,int chan,int c,int o,int v)1064 arp2600Volume(guiSynth *synth, int fd, int chan, int c, int o, int v)
1065 {
1066 	bristolMidiSendMsg(global.controlfd, synth->sid, c, o,
1067 		 (int) (synth->mem.param[68] * synth->mem.param[198] * C_RANGE_MIN_1));
1068 
1069 	return(0);
1070 }
1071 
1072 static int
arp2600ManualStart(guiSynth * synth,int fd,int chan,int c,int o,int v)1073 arp2600ManualStart(guiSynth *synth, int fd, int chan, int c, int o, int v)
1074 {
1075 	if (v == 0)
1076 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
1077 			BRISTOL_EVENT_KEYOFF, 0, 40);
1078 	else
1079 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
1080 			BRISTOL_EVENT_KEYON, 0, 40);
1081 	return(0);
1082 }
1083 
1084 static int
arp2600IOSelect(guiSynth * synth,int fd,int chan,int c,int o,int v)1085 arp2600IOSelect(guiSynth *synth, int fd, int chan, int c, int o, int v)
1086 {
1087 	brightonEvent event;
1088 
1089 	if ((synth->flags & OPERATIONAL) == 0)
1090 		return(0);
1091 
1092 /*	printf("arp2600IOSelect(%i, %i, %i)", c, o, v); */
1093 
1094 	event.command = BRIGHTON_PARAMCHANGE;
1095 
1096 	/*
1097 	 * We have quite a lot of work here, we need to mark any output that is
1098 	 * selected, if an input is selected then we should mark active the previous
1099 	 * output to link them up and draw the desired layer item. We should keep
1100 	 * all this in some structure such that it can be deconfigured, ie, patches
1101 	 * can be removed.
1102 	 *
1103 	 * The structure we need should have an input and output list, this should
1104 	 * give the true co-ords for the start and endpoint since it will be used
1105 	 * to evaluate the transforms for the patch source to the on-screen dest
1106 	 * bitmaps.
1107 	 *
1108 	 * There should also be a sanity check that clears any wayward output
1109 	 * selections, required before saveMemory() can be called.
1110 	 *
1111 	 * We will probably need a selection of bitmaps so that we can simplify
1112 	 * the stretch algorithm. If we only have one bitmaps then we need a more
1113 	 * complex transform since the end points should not be stretched, only
1114 	 * the intermittant cabling:
1115 	 *	cable source is 146bits, 3 for each end.
1116 	 * 	Target length is 725 for example
1117 	 *	the 3 start and end pixels get copied,
1118 	 *	the middle 140 bits must be scaled to 719.
1119 	 *	The result should then be rotated into position.
1120 	 */
1121 	if (c == 1)
1122 	{
1123 		if (v > 0)
1124 			oselect = o;
1125 		else
1126 			oselect = -1;
1127 
1128 		/*
1129 		 * If we select an output that is assigned then clear it.
1130 		 */
1131 		if (links[o].input > 0)
1132 		{
1133 			bristolMidiSendMsg(global.controlfd, synth->sid,
1134 				101, o, links[o].input - 1);
1135 			links[o].input = 0;
1136 			event.type = BRIGHTON_UNLINK;
1137 			event.intvalue = links[o].id;
1138 			brightonParamChange(synth->win, 0, OUTPUT_START + o, &event);
1139 		}
1140 	} else if (c == 2) {
1141 		int i;
1142 
1143 		if (oselect >= 0) {
1144 			for (i = 0; i < ARP_OUTPUTS; i++)
1145 			{
1146 				if ((links[i].input > 0)
1147 					&& (links[i].input == o))
1148 				{
1149 					int hold;
1150 
1151 /*					event.intvalue = links[i].id; */
1152 /*					event.type = BRIGHTON_UNLINK; */
1153 /*					brightonParamChange(synth->win, 0, OUTPUT_START+ i, &event); */
1154 					hold = oselect;
1155 					event.type = BRIGHTON_PARAMCHANGE;
1156 					event.value = 0;
1157 					brightonParamChange(synth->win, 0, OUTPUT_START+ i, &event);
1158 					oselect = hold;
1159 				}
1160 			}
1161 
1162 			synth->mem.param[OUTPUT_START + oselect] = o;
1163 			links[oselect].input = o;
1164 			/*
1165 			 * Need to request the drawing of a link. We need to send a message
1166 			 * that the library will interpret as a connection request.
1167 			 * All we have is brighton param change. We should consider sending
1168 			 * one message with each key click on an output, and another on
1169 			 * each input - this is the only way we can get two panel numbers
1170 			 * across, something we will eventually require.
1171 				brightonParamChange(synth->win, 1, INPUT_START + oselect,
1172 					&event);
1173 			 * Subtraction of 1 is due to offset differences
1174 			 */
1175 			bristolMidiSendMsg(global.controlfd, synth->sid, 100, oselect, o-1);
1176 			event.type = BRIGHTON_LINK;
1177 			event.intvalue = INPUT_START + o;
1178 			links[oselect].id =
1179 				brightonParamChange(synth->win, 0, OUTPUT_START + oselect,
1180 					&event);
1181 		} else {
1182 			/*
1183 			 * See if this input is connected, if so clear it.
1184 			 */
1185 			for (i = 0; i < ARP_OUTPUTS; i++)
1186 			{
1187 				if ((links[i].input > 0)
1188 					&& (links[i].input == o))
1189 				{
1190 					/*
1191 					 * What I need to do is send an event to the output device
1192 					 * turning it off.
1193 					 */
1194 					event.type = BRIGHTON_PARAMCHANGE;
1195 					event.value = 0;
1196 					brightonParamChange(synth->win, 0, OUTPUT_START+i, &event);
1197 				}
1198 			}
1199 		}
1200 
1201 		oselect = -1;
1202 	}
1203 	return(0);
1204 }
1205 
1206 /*
1207  * Any location initialisation required to run the callbacks. For bristol, this
1208  * will connect to the engine, and give it some base parameters.
1209  * May need to generate some application specific menus.
1210  * Will also then make specific requests to some of the devices to alter their
1211  * rendering.
1212  */
1213 static int
arp2600Init(brightonWindow * win)1214 arp2600Init(brightonWindow *win)
1215 {
1216 	guiSynth *synth = findSynth(global.synths, win);
1217 	dispatcher *dispatch;
1218 	int i;
1219 
1220 	if (synth == 0)
1221 	{
1222 		synth = findSynth(global.synths, (int) 0);
1223 		if (synth == 0)
1224 		{
1225 			printf("cannot init\n");
1226 			return(0);
1227 		}
1228 	}
1229 
1230 	synth->win = win;
1231 
1232 	printf("Initialise the arp2600 link to bristol: %p\n", synth->win);
1233 
1234 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
1235 	synth->mem.count = DEVICE_COUNT;
1236 	synth->mem.active = ACTIVE_DEVS;
1237 	synth->dispatch = (dispatcher *)
1238 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
1239 	dispatch = synth->dispatch;
1240 
1241 	/*
1242 	 * We really want to have three connection mechanisms. These should be
1243 	 *	1. Unix named sockets.
1244 	 *	2. UDP sockets.
1245 	 *	3. MIDI pipe.
1246 	 */
1247 	if (!global.libtest)
1248 	{
1249 		if ((synth->sid = initConnection(&global, synth)) < 0)
1250 			return(-1);
1251 	}
1252 
1253 	for (i = 0; i < DEVICE_COUNT; i++)
1254 	{
1255 		/*
1256 		 * This sets up the input and output code.
1257 		 */
1258 		if (i >= MEM_START) {
1259 			synth->dispatch[i].controller = 0;
1260 		} else if (i >= INPUT_START) {
1261 			/* Inputs */
1262 			synth->dispatch[i].controller = 2;
1263 			synth->dispatch[i].operator = i - ACTIVE_DEVS;
1264 			synth->dispatch[i].routine = (synthRoutine) arp2600IOSelect;
1265 		} else if (i >= OUTPUT_START) {
1266 			/* Outputs */
1267 			synth->dispatch[i].controller = 1;
1268 			synth->dispatch[i].operator = i - ACTIVE_DEVS + ARP_OUTPUTS;
1269 			synth->dispatch[i].routine = (synthRoutine) arp2600IOSelect;
1270 		} else
1271 			synth->dispatch[i].routine = arp2600MidiSendMsg;
1272 	}
1273 
1274 	/* Env and Ringmod */
1275 	dispatch[0].controller = 11;
1276 	dispatch[0].operator = 0;
1277 	dispatch[1].controller = 8;
1278 	dispatch[1].operator = 0;
1279 	dispatch[2].controller = 8;
1280 	dispatch[2].operator = 1;
1281 	/* VCO1 */
1282 	dispatch[3].controller = 0;
1283 	dispatch[3].operator = 1;
1284 	/* 4 is KBD control */
1285 	dispatch[4].controller = 126;
1286 	dispatch[4].operator = 3;
1287 	dispatch[5].controller = 103;
1288 	dispatch[5].operator = 4;
1289 	dispatch[6].controller = 103;
1290 	dispatch[6].operator = 5;
1291 	dispatch[7].controller = 103;
1292 	dispatch[7].operator = 6;
1293 	dispatch[8].controller = 1; /* Sync NEXT osc to this on */
1294 	dispatch[8].operator = 7;
1295 	dispatch[9].controller = 0;
1296 	dispatch[9].operator = 2;
1297 	dispatch[10].controller = 0;
1298 	dispatch[10].operator = 10;
1299 	/* VCO2 */
1300 	dispatch[11].controller = 1; /* Transpose */
1301 	dispatch[11].operator = 1;
1302 	/* 12 is KDB control */
1303 	dispatch[12].controller = 126;
1304 	dispatch[12].operator = 4;
1305 	dispatch[13].controller = 103;
1306 	dispatch[13].operator = 8;
1307 	dispatch[14].controller = 103;
1308 	dispatch[14].operator = 9;
1309 	dispatch[15].controller = 103;
1310 	dispatch[15].operator = 10;
1311 	dispatch[16].controller = 103; /* Gain PWM of square wave. */
1312 	dispatch[16].operator = 11;
1313 	dispatch[17].controller = 1;
1314 	dispatch[17].operator = 2;
1315 	dispatch[18].controller = 1;
1316 	dispatch[18].operator = 10;
1317 	dispatch[19].controller = 1;
1318 	dispatch[19].operator = 0;
1319 	/* VCO3 */
1320 	dispatch[20].controller = 2;
1321 	dispatch[20].operator = 1;
1322 	/* 21 is KDB control */
1323 	dispatch[21].controller = 126;
1324 	dispatch[21].operator = 5;
1325 	dispatch[22].controller = 103;
1326 	dispatch[22].operator = 13;
1327 	dispatch[23].controller = 103;
1328 	dispatch[23].operator = 14;
1329 	dispatch[24].controller = 103;
1330 	dispatch[24].operator = 15;
1331 	dispatch[25].controller = 103;
1332 	dispatch[25].operator = 16;
1333 	dispatch[26].controller = 2;
1334 	dispatch[26].operator = 2;
1335 	dispatch[27].controller = 2;
1336 	dispatch[27].operator = 10;
1337 	dispatch[28].controller = 2;
1338 	dispatch[28].operator = 0;
1339 	/* Mixer into VCF */
1340 	dispatch[29].controller = 103;
1341 	dispatch[29].operator = 17;
1342 	dispatch[30].controller = 103;
1343 	dispatch[30].operator = 18;
1344 	dispatch[31].controller = 103;
1345 	dispatch[31].operator = 19;
1346 	dispatch[32].controller = 103;
1347 	dispatch[32].operator = 20;
1348 	dispatch[33].controller = 103;
1349 	dispatch[33].operator = 21;
1350 	/*
1351 	dispatch[29].routine = dispatch[30].routine = dispatch[31].routine
1352 		= dispatch[32].routine = dispatch[33].routine
1353 			= (synthRoutine) arp2600FilterMix;
1354 	*/
1355 
1356 	/* VCF mods */
1357 	dispatch[34].controller = 103;
1358 	dispatch[34].operator = 22;
1359 	dispatch[35].controller = 103;
1360 	dispatch[35].operator = 23;
1361 	dispatch[36].controller = 103;
1362 	dispatch[36].operator = 24;
1363 	/* VCF Params */
1364 	dispatch[37].controller = 3;
1365 	dispatch[37].operator = 0;
1366 	dispatch[38].controller = 3;
1367 	dispatch[38].operator = 1;
1368 	/* Env Params */
1369 	dispatch[39].controller = 4;
1370 	dispatch[39].operator = 0;
1371 	dispatch[40].controller = 4;
1372 	dispatch[40].operator = 1;
1373 	dispatch[41].controller = 4;
1374 	dispatch[41].operator = 2;
1375 	dispatch[42].controller = 4;
1376 	dispatch[42].operator = 3;
1377 	/* AR */
1378 	dispatch[43].controller = 7;
1379 	dispatch[43].operator = 0;
1380 	dispatch[44].controller = 7;
1381 	dispatch[44].operator = 3;
1382 	/* Trigger. */
1383 	dispatch[45].controller = 126;
1384 	dispatch[45].operator = 7;
1385 	/* AMP Params */
1386 	dispatch[46].controller = 103;
1387 	dispatch[46].operator = 29;
1388 	dispatch[47].controller = 103;
1389 	dispatch[47].operator = 30;
1390 	dispatch[48].controller = 103;
1391 	dispatch[48].operator = 31;
1392 	dispatch[49].controller = 103;
1393 	dispatch[49].operator = 32;
1394 	/* Mixer */
1395 	dispatch[50].controller = 103;
1396 	dispatch[50].operator = 33;
1397 	dispatch[51].controller = 103;
1398 	dispatch[51].operator = 34;
1399 
1400 	/* FX levels */
1401 	dispatch[52].controller = 99;
1402 	dispatch[52].operator = 4;
1403 	dispatch[53].controller = 99;
1404 	dispatch[53].operator = 5;
1405 
1406 	/* Four dimension D controls - 13 */
1407 	dispatch[54].controller = 13;
1408 	dispatch[54].operator = 0;
1409 	dispatch[55].controller = 13;
1410 	dispatch[55].operator = 1;
1411 	dispatch[56].controller = 13;
1412 	dispatch[56].operator = 2;
1413 	dispatch[57].controller = 13;
1414 	dispatch[57].operator = 3;
1415 	/* Reverb controls */
1416 	dispatch[58].controller = 99;
1417 	dispatch[58].operator = 0;
1418 	dispatch[59].controller = 99;
1419 	dispatch[59].operator = 1;
1420 	dispatch[60].controller = 99;
1421 	dispatch[60].operator = 2;
1422 	dispatch[61].controller = 99;
1423 	dispatch[61].operator = 3;
1424 	dispatch[62].controller = 99;
1425 	dispatch[62].operator = 60;
1426 	dispatch[62].routine = (synthRoutine) arp2600ManualStart;
1427 
1428 	/* Noise */
1429 	dispatch[63].controller = 6;
1430 	dispatch[63].operator = 2;
1431 	dispatch[64].controller = 6;
1432 	dispatch[64].operator = 0;
1433 	/* LFO stuff */
1434 	dispatch[65].controller = 126;
1435 	dispatch[65].operator = 6;
1436 	dispatch[66].controller = 9;
1437 	dispatch[66].operator = 0;
1438 	dispatch[67].controller = 9;
1439 	dispatch[67].operator = 1;
1440 
1441 	/* Master Volume and Pan - both should become GM2 option MARK */
1442 	dispatch[68].controller = 126;
1443 	dispatch[68].operator = 11;
1444 	dispatch[68].routine = (synthRoutine) arp2600Volume;
1445 	dispatch[69].controller = 126;
1446 	dispatch[69].operator = 2;
1447 
1448 	/* Preamplifier */
1449 	dispatch[70].controller = 126;
1450 	dispatch[70].operator = 10;
1451 
1452 	/* Glide */
1453 	dispatch[71].controller = 126;
1454 	dispatch[71].operator = 0;
1455 
1456 	/* Voltage processing */
1457 	dispatch[72].controller = 103;
1458 	dispatch[72].operator = 44;
1459 	dispatch[73].controller = 103;
1460 	dispatch[73].operator = 45;
1461 	dispatch[74].controller = 103;
1462 	dispatch[74].operator = 46;
1463 	dispatch[75].controller = 12;
1464 	dispatch[75].operator = 0;
1465 
1466 	dispatch[76].controller = 126;
1467 	dispatch[76].operator = 12;
1468 
1469 	dispatch[MEM_START +0].routine = dispatch[MEM_START +1].routine =
1470 		dispatch[MEM_START +2].routine = dispatch[MEM_START +3].routine =
1471 		dispatch[MEM_START +4].routine = dispatch[MEM_START +5].routine =
1472 		dispatch[MEM_START +6].routine = dispatch[MEM_START +7].routine =
1473 		dispatch[MEM_START +8].routine = dispatch[MEM_START +9].routine =
1474 		dispatch[MEM_START +10].routine = dispatch[MEM_START +11].routine =
1475 		dispatch[MEM_START +12].routine = dispatch[MEM_START +13].routine
1476 		= (synthRoutine) arp2600Memory;
1477 
1478 	dispatch[MEM_START + 0].controller = 1;
1479 	dispatch[MEM_START + 1].controller = 2;
1480 	dispatch[MEM_START + 2].operator = 0;
1481 	dispatch[MEM_START + 3].operator = 1;
1482 	dispatch[MEM_START + 4].operator = 2;
1483 	dispatch[MEM_START + 5].operator = 3;
1484 	dispatch[MEM_START + 6].operator = 4;
1485 	dispatch[MEM_START + 7].operator = 5;
1486 	dispatch[MEM_START + 8].operator = 6;
1487 	dispatch[MEM_START + 9].operator = 7;
1488 	dispatch[MEM_START + 10].operator = 8;
1489 	dispatch[MEM_START + 11].operator = 9;
1490 	dispatch[MEM_START + 12].controller = 3;
1491 	dispatch[MEM_START + 13].controller = 4;
1492 
1493 	dispatch[MIDI_START].controller = 1;
1494 	dispatch[MIDI_START + 1].controller = 2;
1495 	dispatch[MIDI_START].routine = dispatch[MIDI_START + 1].routine
1496 		= (synthRoutine) arp2600Midi;
1497 
1498 	dispatch[198].controller = 126;
1499 	dispatch[198].operator = 11;
1500 	dispatch[198].routine = (synthRoutine) arp2600Volume;
1501 
1502 	/*
1503 	 * Need to specify env gain fixed, filter mod on, osc waveform.
1504 	 */
1505 	bristolMidiSendMsg(global.controlfd, synth->sid, 102, 0, 0); /* clear patch */
1506 	/* No filter kbd tracking - we emulate it */
1507 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16383);
1508 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, 0);
1509 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4);
1510 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 7, 4096);
1511 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 8, 100);
1512 	bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, 1);
1513 	/* AR Env params */
1514 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 16383);
1515 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 1, 16383);
1516 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 16383);
1517 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 4, 16383);
1518 /*	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 16383); */
1519 /*	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16383); */
1520 /*	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 4, 16383); */
1521 /*	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, 16383); */
1522 	/* Request rooney filter for lag operator. */
1523 	bristolMidiSendMsg(global.controlfd, synth->sid, 12, 4, 3);
1524 
1525 	return(0);
1526 }
1527 
1528 /*
1529  * This will be called to make any routine specific parameters available.
1530  */
1531 static int
arp2600Configure(brightonWindow * win)1532 arp2600Configure(brightonWindow* win)
1533 {
1534 	guiSynth *synth = findSynth(global.synths, win);
1535 	brightonEvent event;
1536 
1537 	if (synth == 0)
1538 	{
1539 		printf("problems going operational\n");
1540 		return(-1);
1541 	}
1542 
1543 	if (synth->flags & OPERATIONAL)
1544 		return(0);
1545 
1546 printf("going operational\n");
1547 
1548 	synth->flags |= OPERATIONAL;
1549 	synth->keypanel = synth->keypanel2 = -1;
1550 	synth->transpose = 36;
1551 
1552 	synth->bank = 0;
1553 	event.value = 1;
1554 
1555 	arp2600LoadMemory(synth, "arp2600", 0,
1556 		synth->location, synth->mem.active, 0, 0);
1557 	/*
1558 	 * This needs to be fixed. If we load a memory it can override the active
1559 	 * device count. Perhaps for eventual release of the software this is not
1560 	 * an issue though - the active count and memories are then set in stone.
1561 	 * If they do not match then we should back out, but it is a bit on the
1562 	 * late side now. Should be put into the loadMem routines.
1563 	 */
1564 	synth->mem.active = ACTIVE_DEVS;
1565 
1566 	/*
1567 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1568 	 * occurs on first paint, so we suppress the first paint, and then request
1569 	 * an expose here.
1570 	 */
1571 	event.type = BRIGHTON_FLOAT;
1572 	event.value = 0.8;
1573 	brightonParamChange(synth->win, 0, 198, &event);
1574 
1575 	/*
1576 	 * Touch a key on/off
1577 	 */
1578 /*	bristolMidiSendMsg(global.controlfd, synth->midichannel, */
1579 /*		BRISTOL_EVENT_KEYON, 0, 10 + synth->transpose); */
1580 /*	bristolMidiSendMsg(global.controlfd, synth->midichannel, */
1581 /*		BRISTOL_EVENT_KEYOFF, 0, 10 + synth->transpose); */
1582 	configureGlobals(synth);
1583 
1584 	synth->loadMemory = (loadRoutine) arp2600LoadMemory;
1585 
1586 	return(0);
1587 }
1588 
1589