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  * We have 64 params available of which 50 are from the original and 12 others
24  * are defined to be:
25  *
26  *	chorus params		47 58 68 78
27  *	LFO single multi	85
28  *	Osc PW - 1&2		34 36
29  *	Osc PWM - 1&2		35 37
30  *	Osc Sync - 2		28
31  *	Env velocities		57
32  *	Detune globally		38
33  *
34  * DE 67/77 are currently unused. Add Glide?
35  *
36  * We have one more from seq clock 88 := config OMNI
37  *
38  * Poly/Chord/Hold options OK
39  *
40  * Check Sync OK
41  *
42  * Bend Implemented but check dynamics OK
43  *
44  * Clear up diags output REQ
45  *
46  * Check all the parameters audibly.
47  *
48  * Check depth on current detune
49  *
50  * Check out click on note off events.
51  */
52 
53 #include <fcntl.h>
54 
55 #include "brighton.h"
56 #include "brightonMini.h"
57 #include "brightoninternals.h"
58 
59 static int poly800Init();
60 static int poly800Configure();
61 static int poly800Callback(brightonWindow *, int, int, float);
62 static int midiCallback(brightonWindow *, int, int, float);
63 static int poly800KeyCallback(brightonWindow *, int, int, float);
64 
65 extern guimain global;
66 static guimain manual;
67 
68 #include "brightonKeys.h"
69 
70 #define SYNTH_NAME synth->resources->name
71 
72 #define ACTIVE_DEVS 89
73 #define MEM_MGT ACTIVE_DEVS
74 #define MIDI_MGT (MEM_MGT + 12)
75 
76 #define ENTRY_POT 18
77 #define MODS_COUNT 32
78 
79 #define DEVICE_COUNT (ACTIVE_DEVS + MODS_COUNT)
80 
81 #define KEY_PANEL 1
82 #define MODS_PANEL 2
83 #define DISPLAY_DEV (MODS_COUNT - 6)
84 
85 #define MODE_SINGLE	0
86 #define MODE_SPLIT	1
87 #define MODE_LAYER	2
88 
89 static int dc, mbh = 0, crl = 0;
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 poly800Bristol type synth interface.
108  */
109 #define S1 418
110 #define S2 312
111 #define S3 228
112 #define S4 644
113 #define S5 262
114 #define S6 558
115 #define S7 644
116 #define S8 600
117 #define D1 42
118 #define W1 33
119 
120 /*
121  * We really need to define parameter types and ranges here to make the
122  * interface complete. For example, the midi channels only go from 1 to 16 and
123  * when selected as the input then the pot should configure this range.
124  *
125  * Similarly, if this is a button it should be 0 for the first half and 1 for
126  * the second half.
127  *
128  * This only applies to the displays, not to the parameters.
129  *
130  * Continuous controllers actually deliver a value between 0 and 1 to the
131  * engine - the Inc/Dec buttons actually do the steps emulating the original
132  * by going from 0.0 to 1.0 in the given number of stages. The pot, however,
133  * is continuous. Memories save the floating point value between 0 and 1.0,
134  * the stepped values are firstly put on the display and sent to the engine
135  * as the last stage of interpretation.
136  *
137  * The stepped controllers deliver integer values along the given range.
138  */
139 #define POLY800_CONTINUOUS 0
140 #define POLY800_STEPPED 1
141 
142 #define P800_INACTIVE		0x001 /* Skip this parameter */
143 #define P800_INHERIT_PRI	0x002 /* Copy from the primary layer when loading */
144 #define P800_INACTIVE_PEER	0x004 /* Not active in upper (second load) layer */
145 #define P800_USE_PRI		0x008 /* Take value from primary only */
146 #define P800_ALWAYS			0x010 /* All editing in double/split mode */
147 #define P800_INHERIT_SEC	0x020 /* Copy to the primary layer when changing */
148 #define P800_NO_LOAD		0x040 /* All editing in double/split mode */
149 #define P800_REZERO			0x080 /* Normalise signal to engine back to zero */
150 
151 typedef struct P800range {
152 	int type;
153 	float min;
154 	float max;
155 	int op;
156 	int cont;  /* link to the engine code */
157 	int flags;
158 } p800range;
159 
160 /*
161  * STEPPED controllers are sent as that integer value. CONTINUOUS are sent
162  * as values from 0 to 1.0 but the range values specify how they are displayed
163  * on the LEDs.
164  *
165  * We only use 64 parameters, numbered 11 through 88 using just 8 digits. Of
166  * these 50 are selectable from the 'membrane', the rest from the prog digits.
167  *
168  * The Mods:
169  */
170 p800range poly800Range[DEVICE_COUNT] = {
171 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
172 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
173 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
174 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
175 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
176 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
177 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
178 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
179 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
180 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
181 
182 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 10 */
183 	{POLY800_STEPPED,	 1, 3, 0, 101, P800_REZERO}, /* Octave shim */
184 	{POLY800_CONTINUOUS, 1, 2, 0, 102, P800_REZERO}, /* Waveform shim */
185 	{POLY800_CONTINUOUS, 0, 1, 0, 4, 0}, /* 16 */
186 	{POLY800_CONTINUOUS, 0, 1, 0, 5, 0}, /* 8 */
187 	{POLY800_CONTINUOUS, 0, 1, 0, 6, 0}, /* 4 */
188 	{POLY800_CONTINUOUS, 0, 1, 0, 7, 0}, /* 2 */
189 	{POLY800_CONTINUOUS, 0, 31, 4, 9, 0}, /* Level = gain of env */
190 	{POLY800_STEPPED,	 1, 2, 126, 10, P800_REZERO}, /* Double */
191 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
192 
193 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 20 */
194 	{POLY800_STEPPED,	 1, 3, 1, 101, P800_REZERO}, /* Octave */
195 	{POLY800_CONTINUOUS, 1, 2, 1, 102, P800_REZERO}, /* Waveform */
196 	{POLY800_CONTINUOUS, 0, 1, 1, 4, 0}, /* 16 */
197 	{POLY800_CONTINUOUS, 0, 1, 1, 5, 0}, /* 8 */
198 	{POLY800_CONTINUOUS, 0, 1, 1, 6, 0}, /* 4 */
199 	{POLY800_CONTINUOUS, 0, 1, 1, 7, 0}, /* 2 */
200 	{POLY800_CONTINUOUS, 0, 31, 5, 9, 0}, /* Level = gain of env */
201 	{POLY800_STEPPED,	 0, 1, 126, 13, 0}, /* DE Sync */
202 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
203 
204 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 30 */
205 	{POLY800_STEPPED,	 0, 12, 2, 102, P800_REZERO}, /* Interval */
206 	{POLY800_CONTINUOUS, 0, 3, 1, 9, 0}, /* Detune - shim to half a semi */
207 	{POLY800_CONTINUOUS, 0, 15, 3, 0, 0}, /* Noise level - shim it down? */
208 	{POLY800_CONTINUOUS, 0, 99, 0, 13, 0}, /* DCO1 PW entry */
209 	{POLY800_CONTINUOUS, 0, 99, 126, 4, 0}, /* DCO1 PWM entry */
210 	{POLY800_CONTINUOUS, 0, 99, 1, 13, 0}, /* DCO2 PW entry */
211 	{POLY800_CONTINUOUS, 0, 99, 126, 5, 0}, /* DCO2 PWM entry */
212 	{POLY800_CONTINUOUS, 0, 99, 16, 101, 0}, /* Detune entry */
213 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
214 
215 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 40 */
216 	{POLY800_CONTINUOUS, 0, 99, 2, 0, 0}, /* Filter Cutoff */
217 	{POLY800_CONTINUOUS, 0, 15, 2, 1, 0}, /* Filter res */
218 	{POLY800_CONTINUOUS, 0, 2, 2, 3, 0}, /* KBD tracking */
219 	{POLY800_STEPPED,	 1, 2, 126, 20, P800_REZERO}, /* Env polarity */
220 	{POLY800_CONTINUOUS, 0, 15, 126, 21, 0}, /* Env Amount */
221 	{POLY800_STEPPED,	 1, 2, 6, 12, P800_REZERO}, /* Env Trigger */
222 	{POLY800_CONTINUOUS, 0, 99, 100, 3, 0}, /* Chorus P-3 Multi */
223 	{POLY800_STEPPED, 0, 1, 100, 3, 0}, /* Chorus On/Off shim */
224 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
225 
226 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 50 */
227 	{POLY800_CONTINUOUS, 0, 31, 4, 1, 0}, /* Env-1 */
228 	{POLY800_CONTINUOUS, 0, 31, 4, 3, 0}, /* Env-1 */
229 	{POLY800_CONTINUOUS, 0, 31, 4, 4, 0}, /* Env-1 */
230 	{POLY800_CONTINUOUS, 0, 31, 4, 5, 0}, /* Env-1 */
231 	{POLY800_CONTINUOUS, 0, 31, 4, 6, 0}, /* Env-1 */
232 	{POLY800_CONTINUOUS, 0, 31, 4, 7, 0}, /* Env-1 */
233 	{POLY800_STEPPED,	 0, 7, 126, 101, 0}, /* Env-1 touch */
234 	{POLY800_CONTINUOUS, 0, 99, 100, 0, 0}, /* DE 58 Chorus-0 entry */
235 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
236 
237 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 60 */
238 	{POLY800_CONTINUOUS, 0, 31, 5, 1, 0}, /* Env-2 */
239 	{POLY800_CONTINUOUS, 0, 31, 5, 3, 0}, /* Env-2 */
240 	{POLY800_CONTINUOUS, 0, 31, 5, 4, 0}, /* Env-2 */
241 	{POLY800_CONTINUOUS, 0, 31, 5, 5, 0}, /* Env-2 */
242 	{POLY800_CONTINUOUS, 0, 31, 5, 6, 0}, /* Env-2 */
243 	{POLY800_CONTINUOUS, 0, 31, 5, 7, 0}, /* Env-2 */
244 	{POLY800_CONTINUOUS, 0, 1, 126, 0, 0}, /* Glide */
245 	{POLY800_CONTINUOUS, 0, 99, 100, 1, 0}, /* DE 58 Chorus-1 entry */
246 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
247 
248 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 70 */
249 	{POLY800_CONTINUOUS, 0, 31, 6, 1, 0}, /* Env-3 */
250 	{POLY800_CONTINUOUS, 0, 31, 6, 3, 0}, /* Env-3 */
251 	{POLY800_CONTINUOUS, 0, 31, 6, 4, 0}, /* Env-3 */
252 	{POLY800_CONTINUOUS, 0, 31, 6, 5, 0}, /* Env-3 */
253 	{POLY800_CONTINUOUS, 0, 31, 6, 6, 0}, /* Env-3 */
254 	{POLY800_CONTINUOUS, 0, 31, 6, 7, 0}, /* Env-3 */
255 	{POLY800_STEPPED,	 0, 1, 6, 10, 0}, /* FREE */
256 	{POLY800_CONTINUOUS, 0, 99, 100, 2, 0}, /* DE 58 Chorus-2 entry */
257 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry */
258 
259 	{POLY800_STEPPED,	 0, 1, 126, 126, P800_NO_LOAD}, /* Dummy entry 80 */
260 	{POLY800_CONTINUOUS, 0, 15, 8, 0, 0}, /* LFO Freq */
261 	{POLY800_CONTINUOUS, 0, 15, 126, 24, 0}, /* LFO Delay */
262 	{POLY800_CONTINUOUS, 0, 15, 126, 22, 0}, /* DCO */
263 	{POLY800_CONTINUOUS, 0, 15, 126, 23, 0}, /* VCF */
264 	{POLY800_STEPPED,	 0, 1, 126, 11, 0}, /* LFO Multi entry */
265 	{POLY800_STEPPED,	 1, 16, 126, 126, P800_REZERO}, /* Midi Chan Shim */
266 	{POLY800_STEPPED,	 0, 1, 126, 126, 0}, /* Midi Prog Change */
267 	{POLY800_STEPPED,	 1, 2, 126, 126, P800_REZERO}, /* OMNI */
268 
269 };
270 
271 #define P8H 410
272 #define P8W 39
273 #define PR1 13
274 #define PR2 513
275 
276 #define C1 3
277 #define C2 (C1 + P8W + 1)
278 #define C3 (C2 + P8W + 0)
279 #define C4 (C3 + P8W + 1)
280 #define C5 (C4 + P8W + 1)
281 #define C6 (C5 + P8W + 0)
282 #define C7 (C6 + P8W + 1)
283 #define C8 (C7 + P8W + 1)
284 #define C9 (C8 + P8W + 2)
285 #define C10 (C9 + P8W + 1)
286 #define C11 (C10 + P8W + 1)
287 #define C12 (C11 + P8W + 0)
288 #define C13 (C12 + P8W + 0)
289 #define C14 (C13 + P8W + 1)
290 #define C15 (C14 + P8W + 0)
291 #define C16 (C15 + P8W - 1)
292 #define C17 (C16 + P8W + 3)
293 #define C18 (C17 + P8W + 2)
294 #define C19 (C18 + P8W + 4)
295 #define C20 (C19 + P8W + 1)
296 #define C21 (C20 + P8W - 1)
297 #define C22 (C21 + P8W + 0)
298 #define C23 (C22 + P8W + 3)
299 #define C24 (C23 + P8W + 0)
300 #define C25 (C24 + P8W + 1)
301 
302 #define LC1 3
303 #define LC2 (LC1 + P8W + 1)
304 #define LC3 (LC2 + P8W + 1)
305 #define LC4 (LC3 + P8W + 0)
306 #define LC5 (LC4 + P8W + 1)
307 #define LC6 (LC5 + P8W + 0)
308 #define LC7 (LC6 + P8W + 3)
309 #define LC8 (LC7 + P8W + 1)
310 #define LC9 (LC8 + P8W + 1)
311 #define LC10 (LC9 + P8W + 0)
312 #define LC11 (LC10 + P8W + 1)
313 #define LC12 (LC11 + P8W + 0)
314 #define LC13 (LC12 + P8W + 3)
315 #define LC14 (LC13 + P8W + 1)
316 #define LC15 (LC14 + P8W + 0)
317 #define LC16 (LC15 + P8W + 1)
318 #define LC17 (LC16 + P8W + 0)
319 #define LC18 (LC17 + P8W + 1)
320 #define LC19 (LC18 + P8W + 3)
321 #define LC20 (LC19 + P8W + 1)
322 #define LC21 (LC20 + P8W + 0)
323 #define LC22 (LC21 + P8W + 1)
324 #define LC23 (LC22 + P8W + 2)
325 #define LC24 (LC23 + P8W + 0)
326 #define LC25 (LC24 + P8W + 0)
327 
328 static
329 brightonLocations locations[DEVICE_COUNT] = {
330 	/*
331 	 * The first are dummies, count starts at 11
332 	 */
333 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
334 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
335 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
336 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
337 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
338 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
339 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
340 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
341 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
342 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
343 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
344 
345 	{"DCO1 Octave", 9, C1, PR1, P8W, P8H, 0, 1, 0,
346 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
347 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
348 	{"DCO1 Wave", 9, C2, PR1, P8W, P8H, 0, 1, 0,
349 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
350 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
351 	{"DCO1 16'", 9, C3, PR1, P8W, P8H, 0, 1, 0,
352 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
353 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
354 	{"DCO1 8'", 9, C4, PR1, P8W, P8H, 0, 1, 0,
355 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
356 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
357 	{"DCO1 4'", 9, C5, PR1, P8W, P8H, 0, 1, 0,
358 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
359 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
360 	{"DCO1 2'", 9, C6, PR1, P8W, P8H, 0, 1, 0,
361 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
362 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
363 	{"DCO1 Level", 9, C7, PR1, P8W, P8H, 0, 1, 0,
364 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
365 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
366 	/* Noise 18 */
367 	{"DCO Mode", 9, C8, PR1, P8W, P8H, 0, 1, 0,
368 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
369 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
370 
371 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
372 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
373 
374 	/* DCO 21 */
375 	{"DCO2 Octave", 9, C9, PR1, P8W, P8H, 0, 1, 0,
376 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
377 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
378 	{"DCO2 Wave", 9, C10, PR1, P8W, P8H, 0, 1, 0,
379 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
380 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
381 	{"DCO2 16'", 9, C11, PR1, P8W, P8H, 0, 1, 0,
382 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
383 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
384 	{"DCO2 8'", 9, C12, PR1, P8W, P8H, 0, 1, 0,
385 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
386 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
387 	{"DCO2 4'", 9, C13, PR1, P8W, P8H, 0, 1, 0,
388 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
389 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
390 	{"DCO2 2'", 9, C14, PR1, P8W, P8H, 0, 1, 0,
391 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
392 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
393 	{"DCO2 Level", 9, C15, PR1, P8W, P8H, 0, 1, 0,
394 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
395 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
396 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
397 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
398 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
399 	/* DCO 2 31 */
400 	{"DCO2 Interval", 9, C16, PR1, P8W + 2, P8H, 0, 1, 0,
401 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
402 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
403 	{"DCO2 Detune", 9, C17, PR1, P8W, P8H, 0, 1, 0,
404 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
405 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
406 	/* Noise 33 */
407 	{"Noise", 9, C18, PR1, P8W, P8H, 0, 1, 0,
408 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
409 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
410 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
411 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
412 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
413 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
414 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
415 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
416 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
417 	/* VCF 41 */
418 	{"VCF Cutoff", 9, C19, PR1, P8W, P8H, 0, 1, 0,
419 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
420 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
421 	{"VCF Resonance", 9, C20, PR1, P8W, P8H, 0, 1, 0,
422 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
423 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
424 	{"VCF KBD", 9, C21, PR1, P8W, P8H, 0, 1, 0,
425 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
426 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
427 	{"VCF EnvPolarity", 9, C22, PR1, P8W + 2, P8H, 0, 1, 0,
428 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
429 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
430 	{"VCF EngTrack", 9, C23, PR1, P8W, P8H, 0, 1, 0,
431 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
432 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
433 	{"VCF Env Trigger", 9, C24, PR1, P8W, P8H, 0, 1, 0,
434 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
435 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
436 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
437 	{"On/Off", 9, C25, PR1, P8W, P8H, 0, 1, 0,
438 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
439 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
440 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
441 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
442 	/* DEG 1 51 */
443 	{"DEG1 Attack", 9, LC1, PR2, P8W, P8H, 0, 1, 0,
444 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
445 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
446 	{"DEG1 Decay", 9, LC2, PR2, P8W, P8H, 0, 1, 0,
447 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
448 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
449 	{"DEG1 Break", 9, LC3, PR2, P8W, P8H, 0, 1, 0,
450 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
451 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
452 	{"DEG1 Slope", 9, LC4, PR2, P8W, P8H, 0, 1, 0,
453 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
454 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
455 	{"DEG1 Sustain", 9, LC5, PR2, P8W, P8H, 0, 1, 0,
456 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
457 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
458 	{"DEG1 Release", 9, LC6, PR2, P8W, P8H, 0, 1, 0,
459 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
460 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
461 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
462 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
463 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
464 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
465 	/* DEG 2 61 */
466 	{"DEG2 Attack", 9, LC7, PR2, P8W, P8H, 0, 1, 0,
467 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
468 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
469 	{"DEG2 Decay", 9, LC8, PR2, P8W, P8H, 0, 1, 0,
470 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
471 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
472 	{"DEG2 Break", 9, LC9, PR2, P8W, P8H, 0, 1, 0,
473 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
474 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
475 	{"DEG2 Slope", 9, LC10, PR2, P8W, P8H, 0, 1, 0,
476 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
477 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
478 	{"DEG2 Sustain", 9, LC11, PR2, P8W, P8H, 0, 1, 0,
479 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
480 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
481 	{"DEG2 Release", 9, LC12, PR2, P8W, P8H, 0, 1, 0,
482 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
483 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
484 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
485 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
486 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
487 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
488 	/* DEG 3 71 */
489 	{"DEG3 Attack", 9, LC13, PR2, P8W, P8H, 0, 1, 0,
490 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
491 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
492 	{"DEG3 Decay", 9, LC14, PR2, P8W, P8H, 0, 1, 0,
493 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
494 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
495 	{"DEG3 Break", 9, LC15, PR2, P8W, P8H, 0, 1, 0,
496 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
497 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
498 	{"DEG3 Slope", 9, LC16, PR2, P8W, P8H, 0, 1, 0,
499 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
500 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
501 	{"DEG3 Sustain", 9, LC17, PR2, P8W, P8H, 0, 1, 0,
502 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
503 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
504 	{"DEG3 Release", 9, LC18, PR2, P8W, P8H, 0, 1, 0,
505 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
506 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
507 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
508 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
509 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
510 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
511 	/* Mod 81 */
512 	{"LFO Freq", 9, LC19, PR2, P8W, P8H, 0, 1, 0,
513 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
514 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
515 	{"LFO Delay", 9, LC20, PR2, P8W, P8H, 0, 1, 0,
516 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
517 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
518 	{"LFO DCO", 9, LC21, PR2, P8W, P8H, 0, 1, 0,
519 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
520 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
521 	{"LFO VCF", 9, LC22, PR2, P8W, P8H, 0, 1, 0,
522 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
523 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
524 	{"", 2, 0, 0, 10, 10, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN},
525 	{"MidiChannel", 9, LC23, PR2, P8W, P8H, 0, 1, 0,
526 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
527 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
528 	{"ProgEnable", 9, LC24, PR2, P8W, P8H, 0, 1, 0,
529 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
530 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
531 	{"OmniOnOff", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
532 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
533 		BRIGHTON_NOSHADOW|BRIGHTON_CHECKBUTTON|BRIGHTON_TRACKING},
534 	/* Done */
535 
536 	{"", 9, 5, 5, 5, 5, 0, 1, 0,
537 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
538 		BRIGHTON_WITHDRAWN},
539 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
540 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
541 		BRIGHTON_WITHDRAWN},
542 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
543 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
544 		BRIGHTON_WITHDRAWN},
545 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
546 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
547 		BRIGHTON_WITHDRAWN},
548 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
549 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
550 		BRIGHTON_WITHDRAWN},
551 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
552 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
553 		BRIGHTON_WITHDRAWN},
554 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
555 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
556 		BRIGHTON_WITHDRAWN},
557 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
558 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
559 		BRIGHTON_WITHDRAWN},
560 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
561 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
562 		BRIGHTON_WITHDRAWN},
563 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
564 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
565 		BRIGHTON_WITHDRAWN},
566 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
567 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
568 		BRIGHTON_WITHDRAWN},
569 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
570 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
571 		BRIGHTON_WITHDRAWN},
572 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
573 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
574 		BRIGHTON_WITHDRAWN},
575 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
576 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
577 		BRIGHTON_WITHDRAWN},
578 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
579 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
580 		BRIGHTON_WITHDRAWN},
581 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
582 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
583 		BRIGHTON_WITHDRAWN},
584 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
585 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
586 		BRIGHTON_WITHDRAWN},
587 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
588 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
589 		BRIGHTON_WITHDRAWN},
590 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
591 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
592 		BRIGHTON_WITHDRAWN},
593 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
594 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
595 		BRIGHTON_WITHDRAWN},
596 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
597 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
598 		BRIGHTON_WITHDRAWN},
599 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
600 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
601 		BRIGHTON_WITHDRAWN},
602 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
603 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
604 		BRIGHTON_WITHDRAWN},
605 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
606 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
607 		BRIGHTON_WITHDRAWN},
608 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
609 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
610 		BRIGHTON_WITHDRAWN},
611 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
612 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
613 		BRIGHTON_WITHDRAWN},
614 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
615 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
616 		BRIGHTON_WITHDRAWN},
617 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
618 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
619 		BRIGHTON_WITHDRAWN},
620 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
621 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
622 		BRIGHTON_WITHDRAWN},
623 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
624 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
625 		BRIGHTON_WITHDRAWN},
626 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
627 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
628 		BRIGHTON_WITHDRAWN},
629 	{"", 9, LC25, PR2, P8W, P8H, 0, 1, 0,
630 		"bitmaps/buttons/blue.xpm", "bitmaps/buttons/green.xpm",
631 		BRIGHTON_WITHDRAWN},
632 
633 };
634 
635 #define PMW 40
636 #define PMH 130
637 
638 static
639 brightonLocations p800mods[MODS_COUNT] = {
640 	/* Bank */
641 	{"", 2, 647, 820, 100, 33, 0, 1, 0, "bitmaps/buttons/polyblue.xpm",
642 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
643 	/* Digits 1 */
644 	{"", 2, 600, 700, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm",
645 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
646 	{"", 2, 670, 700, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm",
647 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
648 	{"", 2, 740, 700, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm",
649 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
650 	{"", 2, 600, 590, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm",
651 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
652 	{"", 2, 670, 590, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm",
653 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
654 	{"", 2, 740, 590, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm",
655 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
656 	{"", 2, 600, 460, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm",
657 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
658 	{"", 2, 670, 460, 50, 40, 0, 1, 0, "bitmaps/buttons/polyblue.xpm",
659 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
660 	/* Prog button 9 */
661 	{"", 2, 740, 460, 50, 40, 0, 1, 0, "bitmaps/buttons/polywhiteH.xpm",
662 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
663 
664 	{"MasterVolume", 0, 210, 645, 130, 180, 0, 1, 0, "bitmaps/knobs/line.xpm", 0,
665 		BRIGHTON_REDRAW|BRIGHTON_NOSHADOW},
666 	{"", 1, 190, 500, 150, 35, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm", 0,
667 		BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOTCH|BRIGHTON_NOSHADOW},
668 	{"", 1, 362, 540, 15, 300, 0, 11, 0, "bitmaps/buttons/polywhiteV.xpm", 0,
669 		BRIGHTON_HALFSHADOW},
670 
671 	{"", 2, 430, 530, 25, 200, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm",
672 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
673 	{"", 2, 490, 530, 25, 200, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm",
674 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
675 	{"", 2, 550, 530, 25, 200, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm",
676 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
677 
678 // 16
679 	{"", 2, 835, 530, 25, 200, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm",
680 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
681 	{"", 2, 885, 530, 25, 200, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm",
682 		"bitmaps/buttons/polyredV.xpm", BRIGHTON_CHECKBUTTON},
683 
684 	/* Entry pot 18 */
685 	{"DataEntry", 0, 835, 750, 100, 140, 0, 1, 0, "bitmaps/knobs/knob1.xpm", 0, 0},
686 
687 	/* Midi is now in the memory */
688 	{"", 2, 0, 0, 25, 140, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm",
689 		"bitmaps/buttons/polyredV.xpm",BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
690 	{"", 2, 600, 340, 18, 35, 0, 1, 0, "bitmaps/textures/p8b.xpm",
691 		"bitmaps/images/led.xpm", BRIGHTON_NOSHADOW},
692 
693 	{"", 2, 940, 530, 25, 140, 0, 1, 0, "bitmaps/buttons/polyredV.xpm",
694 		"bitmaps/buttons/polyblue.xpm", BRIGHTON_CHECKBUTTON},
695 
696 	/* Joystick 22 - we need to keep the dummy since it dispatches X/Y events */
697 	{"", 5, 3, 620, 150, 240, 0, 1, 0, "bitmaps/images/sphere.xpm",
698 		0, BRIGHTON_WIDE},
699 	{"", 0, 0, 0, 10, 10, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm",
700 		0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW}, /* DUMMY */
701 
702 	/* Two LED for denoting prog or param - 24*/
703 	{"", 2, 693, 340, 18, 35, 0, 1, 0, "bitmaps/textures/p8b.xpm",
704 		"bitmaps/images/led.xpm", BRIGHTON_NOSHADOW},
705 	{"", 2, 843, 340, 18, 35, 0, 1, 0, "bitmaps/textures/p8b.xpm",
706 		"bitmaps/images/led.xpm", BRIGHTON_NOSHADOW},
707 
708 	{"", 8, 610, 200, PMW, PMH, 0, 9, 0, 0, 0, 0},
709 	{"", 8, 610 + PMW + 5, 200, PMW, PMH, 0, 9, 0, 0, 0, 0},
710 
711 	{"", 8, 750, 200, PMW, PMH, 0, 9, 0, 0, 0, 0},
712 	{"", 8, 750 + PMW + 5, 200, PMW, PMH, 0, 9, 0, 0, 0, 0},
713 
714 	{"", 8, 890, 200, PMW, PMH, 0, 9, 0, 0, 0, 0},
715 	{"", 8, 890 + PMW + 5, 200, PMW, PMH, 0, 9, 0, 0, 0, 0},
716 };
717 
718 /*
719  * This is a set of globals for the main window rendering. Again taken from
720  * include/brighton.h
721  * Hm, the bit-1 was black, and the bit 99 was in various builds including a
722  * white one, but also a black one and a black one with wood panels. I would
723  * like the black one with wood panels, so that will have to be the bit-1, the
724  * bit-99 will be white with thin metal panels.
725  */
726 brightonApp poly800App = {
727 	"poly800",
728 	0, /* no blueprint on wood background. */
729 	"bitmaps/textures/p8b.xpm",
730 	BRIGHTON_STRETCH,
731 	poly800Init,
732 	poly800Configure, /* 3 callbacks, unused? */
733 	midiCallback,
734 	destroySynth,
735 	{8, 100, 2, 2, 5, 520, 0, 0},
736 	1016, 370, 0, 0,
737 	3, /* one panel only */
738 	{
739 		{
740 			"Poly800",
741 			"bitmaps/blueprints/poly800.xpm",
742 			"bitmaps/textures/p8b.xpm",
743 			BRIGHTON_STRETCH, /* flags */
744 			0,
745 			0,
746 			poly800Callback,
747 			317, 40, 674, 444,
748 			DEVICE_COUNT,
749 			locations
750 		},
751 		{
752 			"Keyboard",
753 			0,
754 //			"bitmaps/keys/kbg.xpm",
755 			"bitmaps/newkeys/nkbg.xpm",
756 			0x020|BRIGHTON_STRETCH,
757 			0,
758 			0,
759 			poly800KeyCallback,
760 			32, 550, 952, 430,
761 			KEY_COUNT_4OCTAVE,
762 			keys4octave2
763 //			KEY_COUNT,
764 //			keysprofile2
765 		},
766 		{
767 			"Poly800Mods",
768 			"bitmaps/blueprints/poly800mods.xpm",
769 			"bitmaps/textures/p8b.xpm",
770 			BRIGHTON_STRETCH, /* flags */
771 			0,
772 			0,
773 			poly800Callback,
774 			7, 20, 300, 444,
775 			MODS_COUNT,
776 			p800mods
777 		},
778 	}
779 };
780 
781 /*
782  * The next two should come out of here and go into a separate arpeggiator file
783  * or failing that into brightonRoutines.c
784  *
785  * This has been commented out until it is integrated into the p800 emulator
786  *
787 static int
788 poly800seqInsert(arpeggiatorMemory *seq, int note, int transpose)
789 {
790 printf("arpeg %i + %i at %i\n", note, transpose, (int) seq->s_max);
791 	if (seq->s_max == 0)
792 		seq->s_dif = note + transpose;
793 
794 	seq->sequence[(int) (seq->s_max)] = (float) (note + transpose - seq->s_dif);
795 
796 	if ((seq->s_max += 1) >= BRISTOL_SEQ_MAX) {
797 		seq->s_max = BRISTOL_SEQ_MAX;
798 		return(-1);
799 	}
800 
801 	return(0);
802 }
803 
804 static void
805 poly800SeqRelearn(guiSynth *synth, int fd, int chan, int c, int o, int v)
806 {
807 	if (v != 0) {
808 		bristolMidiSendMsg(fd, synth->sid,
809 			BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0);
810 		bristolMidiSendMsg(fd, synth->sid,
811 			BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 1);
812 		synth->seq1.param[BRISTOL_AM_SMAX] = 0;
813 
814 		return;
815 	}
816 
817 	bristolMidiSendMsg(fd, synth->sid,
818 		BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0);
819 }
820  */
821 
822 static void
poly800ChordRelearn(guiSynth * synth,int fd,int chan,int c,int o,int v)823 poly800ChordRelearn(guiSynth *synth, int fd, int chan, int c, int o, int v)
824 {
825 	if (synth->seq1.param == NULL)
826 		loadSequence(&synth->seq1, SYNTH_NAME, 0, 0);
827 	if (synth->seq2.param == NULL)
828 		loadSequence(&synth->seq2, SYNTH_NAME, 0, BRISTOL_SID2);
829 
830 // We need to turn off chording to do this and reset one index
831 	if (v != 0) {
832 		bristolMidiSendMsg(fd, synth->sid,
833 			BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0);
834 		bristolMidiSendMsg(fd, synth->sid,
835 			BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 1);
836 		synth->seq1.param[BRISTOL_AM_CCOUNT] = 0;
837 
838 		return;
839 	}
840 
841 	bristolMidiSendMsg(fd, synth->sid,
842 		BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0);
843 }
844 
845 static int
poly800ChordInsert(arpeggiatorMemory * seq,int note,int transpose)846 poly800ChordInsert(arpeggiatorMemory *seq, int note, int transpose)
847 {
848 	//printf("chord %i + %i at %i\n", note, transpose, (int) seq->c_count);
849 	if (seq->c_count == 0)
850 		seq->c_dif = note + transpose;
851 
852 	seq->chord[(int) (seq->c_count)] = (float) (note + transpose - seq->c_dif);
853 
854 	if ((seq->c_count += 1) >= BRISTOL_CHORD_MAX) {
855 		seq->c_count = BRISTOL_CHORD_MAX;
856 		crl = 0;
857 		return(-1);
858 	}
859 
860 	return(0);
861 }
862 
863 /*
864  * We really want to just use one midi channel and let the midi library decide
865  * that we have multiple synths on the channel with their own split points.
866  * The lower layer should define the midi channel, split point and transpose
867  * of upper layer.
868  */
869 static int
poly800KeyCallback(brightonWindow * win,int panel,int index,float value)870 poly800KeyCallback(brightonWindow *win, int panel, int index, float value)
871 {
872 	guiSynth *synth = findSynth(global.synths, win);
873 
874 	/*
875 	if ((synth->mem.param[155] != 0) && (value != 0))
876 	{
877 		seqInsert((arpeggiatorMemory *) synth->seq1.param,
878 			(int) index, synth->transpose);
879 	}
880 	*/
881 
882 	if (crl)
883 	{
884 		poly800ChordInsert((arpeggiatorMemory *) synth->seq1.param,
885 			(int) index, synth->transpose);
886 	}
887 
888 	if (global.libtest)
889 		return(0);
890 
891 	/*
892 	 * So we have a single key event and two MIDI channels. Just send the
893 	 * event on both channels, no need to be difficult about it since if this
894 	 * was a split configuration the library filters out the events.
895 	 */
896 	if (value) {
897 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
898 			BRISTOL_EVENT_KEYON, 0, index + synth->transpose);
899 	} else {
900 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
901 			BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose);
902 	}
903 
904 	return(0);
905 }
906 
907 /*
908  * At this point we have loaded a memory so we need to send those actual new
909  * parameters to the engine. This is an issue for MIDI program load, perhaps
910  * we should consider dual load above memory 74 as per the original?
911  *
912  * The path of least resistance here is to scan through the the memory table
913  * incrementing the input selector and delivering the memory value to the
914  * data entry pot.....
915  */
916 static void
loadMemoryShim(guiSynth * synth,int from)917 loadMemoryShim(guiSynth *synth, int from)
918 {
919 	int i, current;
920 	brightonEvent event;
921 
922 	current = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] * 10
923 		+ synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3];
924 
925 	loadMemory(synth, SYNTH_NAME, 0, from,
926 		synth->mem.active, 0, BRISTOL_FORCE|BRISTOL_NOCALLS);
927 
928 	synth->flags |= MEM_LOADING;
929 
930 	event.type = BRIGHTON_FLOAT;
931 
932 	for (i = 0; i < synth->mem.active; i++)
933 	{
934 		if (poly800Range[i].flags & P800_NO_LOAD)
935 			continue;
936 
937 		synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] = i / 10;
938 		synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3] = i % 10;
939 
940 		event.value = synth->mem.param[i];
941 
942 		brightonParamChange(synth->win, MODS_PANEL, ENTRY_POT, &event);
943 	}
944 	synth->flags &= ~MEM_LOADING;
945 
946 	synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] = current / 10;
947 	synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3] = current % 10;
948 
949 	event.value = synth->mem.param[current];
950 	brightonParamChange(synth->win, MODS_PANEL, ENTRY_POT, &event);
951 }
952 
953 int
p800loadMemory(guiSynth * synth,char * algo,char * name,int location,int active,int skip,int flags)954 p800loadMemory(guiSynth *synth, char *algo, char *name, int location,
955 int active, int skip, int flags)
956 {
957 	loadMemoryShim(synth, location);
958 	return(0);
959 }
960 
961 static int
midiCallback(brightonWindow * win,int controller,int value,float n)962 midiCallback(brightonWindow *win, int controller, int value, float n)
963 {
964 	guiSynth *synth = findSynth(global.synths, win);
965 
966 	switch(controller)
967 	{
968 		case MIDI_PROGRAM:
969 			if (synth->mem.param[87] == 0)
970 				return(0);
971 			/*
972 			 * We should accept 0..74 as lower layer and above that as dual
973 			 * loading requests.
974 			 */
975 			printf("midi program: %x, %i\n", controller, value);
976 			synth->location = value;
977 			loadMemoryShim(synth, synth->location);
978 			break;
979 		case MIDI_BANK_SELECT:
980 			printf("midi banksel: %x, %i\n", controller, value);
981 			synth->bank = value;
982 			break;
983 	}
984 	return(0);
985 }
986 
987 static int
poly800UpdateDisplayDec(guiSynth * synth,int fd,int chan,int c,int o,int v)988 poly800UpdateDisplayDec(guiSynth *synth, int fd, int chan, int c, int o, int v)
989 {
990 	int ho, lo, dev = DISPLAY_DEV + o;
991 	brightonEvent event;
992 
993 	/* printf("Dec %i %i %i\n", c, o, v); */
994 
995 	if (v < 0)
996 	{
997 		ho = lo = -10;
998 	} else {
999 		lo = v % 10;
1000 		ho = v / 10;
1001 	}
1002 
1003 	event.type = BRIGHTON_FLOAT;
1004 	event.value = (float) ho;
1005 
1006 	brightonParamChange(synth->win, MODS_PANEL, dev, &event);
1007 
1008 	event.value = (float) lo;
1009 	brightonParamChange(synth->win, MODS_PANEL, dev + 1, &event);
1010 
1011 	return(0);
1012 }
1013 
1014 static int
poly800UpdateDisplay(guiSynth * synth,int fd,int chan,int c,int o,int v)1015 poly800UpdateDisplay(guiSynth *synth, int fd, int chan, int c, int o, int v)
1016 {
1017 	int ho, lo, dev = DISPLAY_DEV + o;
1018 	brightonEvent event;
1019 
1020 	/* printf("Disp %i %i %i\n", c, o, v); */
1021 
1022 	if (v < 0)
1023 	{
1024 		ho = lo = -10;
1025 	} else {
1026 		ho = v * 100 / (CONTROLLER_RANGE + 1);
1027 		lo = ho % 10;
1028 		ho = ho / 10;
1029 	}
1030 
1031 	event.type = BRIGHTON_FLOAT;
1032 	event.value = (float) ho;
1033 
1034 	brightonParamChange(synth->win, MODS_PANEL, dev, &event);
1035 
1036 	event.value = (float) lo;
1037 	brightonParamChange(synth->win, MODS_PANEL, dev + 1, &event);
1038 
1039 	synth->mem.param[ACTIVE_DEVS + dev] = ho;
1040 	synth->mem.param[ACTIVE_DEVS + dev + 1] = lo;
1041 
1042 	return(0);
1043 }
1044 
1045 static int
poly800MidiNull(void * synth,int fd,int chan,int c,int o,int v)1046 poly800MidiNull(void *synth, int fd, int chan, int c, int o, int v)
1047 {
1048 	if (global.libtest)
1049 		printf("This is a null callback on panel 0 id 0\n");
1050 
1051 	return(0);
1052 }
1053 
1054 static void
poly800MidiShim(guiSynth * synth,int fd,int chan,int c,int o,int v)1055 poly800MidiShim(guiSynth *synth, int fd, int chan, int c, int o, int v)
1056 {
1057 	bristolMidiSendMsg(fd, synth->sid, c, o, v);
1058 }
1059 
1060 static int
poly800MidiSendMsg(guiSynth * synth,int fd,int chan,int o,int c,int v)1061 poly800MidiSendMsg(guiSynth *synth, int fd, int chan, int o, int c, int v)
1062 {
1063 	c = poly800Range[o].cont;
1064 	o = poly800Range[o].op;
1065 
1066 	if (global.libtest)
1067 		return(0);
1068 
1069 	bristolMidiSendMsg(fd, synth->sid, o, c, v);
1070 
1071 	return(0);
1072 }
1073 
1074 static int
poly800EntryPot(guiSynth * synth,int fd,int chan,int o,int c,float v)1075 poly800EntryPot(guiSynth *synth, int fd, int chan, int o, int c, float v)
1076 {
1077 	int index;
1078 	float decimal;
1079 	int value;
1080 
1081 //printf("EP %f %f: %f\n", synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2], synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3], v);
1082 
1083 	/*
1084 	 * Get the param index from the second display
1085 	 */
1086 	if ((index = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] * 10
1087 		+ synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3]) < 11)
1088 		return(0);
1089 
1090 	if (poly800Range[index].flags & P800_INACTIVE) {
1091 		v = 0;
1092 		decimal = 0;
1093 	}
1094 
1095 	synth->mem.param[index] = v;
1096 
1097 	/*
1098 	 * We have a value for the pot position and that has to be worked into
1099 	 * the entry range.
1100 	 *
1101 	 * This was originally wrong:
1102 
1103 	decimal = poly800Range[index].min +
1104 		(v + 0.00001) * (poly800Range[index].max - poly800Range[index].min);
1105 
1106 	 * This only changes at the limits, rather than halfway through a range
1107 	 * which appears better - it truncates whilst it should round...
1108 	 */
1109 	decimal = (float) ((int) (0.5 + poly800Range[index].min +
1110 		(v + 0.00001) * (poly800Range[index].max - poly800Range[index].min)));
1111 
1112 	/*
1113 	if ((synth->flags & MEM_LOADING) != 0)
1114 	{
1115 		synth->mem.param[index] = v;
1116 		poly800UpdateDisplayDec(synth, fd, chan, c, 4, decimal);
1117 		return(0);
1118 	}
1119 	*/
1120 
1121 	if (poly800Range[index].type == POLY800_STEPPED) {
1122 		value = (int) decimal;
1123 		if (poly800Range[index].flags & P800_REZERO)
1124 			value -= poly800Range[index].min;
1125 	} else
1126 		value = (int) (v * C_RANGE_MIN_1);
1127 
1128 //printf("EP %i %f = send %i\n", index, decimal, value);
1129 
1130 	if ((synth->flags & MEM_LOADING) == 0)
1131 		poly800UpdateDisplayDec(synth, fd, chan, c, 4, decimal);
1132 
1133 	if (synth->dispatch[index].routine != NULL)
1134 		synth->dispatch[index].routine(synth,
1135 			global.controlfd, synth->sid,
1136 			poly800Range[index].op,
1137 			poly800Range[index].cont,
1138 			value);
1139 	else
1140 		poly800MidiSendMsg(synth,
1141 			global.controlfd, synth->sid,
1142 			synth->dispatch[index].controller,
1143 			synth->dispatch[index].operator,
1144 			value);
1145 
1146 	return(0);
1147 }
1148 
1149 static int
poly800Select(guiSynth * synth,int fd,int chan,int c,int o,int v)1150 poly800Select(guiSynth *synth, int fd, int chan, int c, int o, int v)
1151 {
1152 	brightonEvent event;
1153 
1154 	poly800UpdateDisplay(synth, fd, chan, c, 2,
1155 		(c + 1) * CONTROLLER_RANGE / 100);
1156 
1157 	event.type = BRIGHTON_FLOAT;
1158 	event.value = synth->mem.param[c];
1159 	brightonParamChange(synth->win, MODS_PANEL, ENTRY_POT, &event);
1160 
1161 	/* Select Param entry */
1162 	event.value = 1;
1163 	brightonParamChange(synth->win, MODS_PANEL, 25, &event);
1164 	event.value = 0;
1165 	brightonParamChange(synth->win, MODS_PANEL, 24, &event);
1166 
1167 	return(0);
1168 }
1169 
1170 static int memSave = -1;
1171 static int bankHold = 0;
1172 
1173 static void
poly800Memory(guiSynth * synth,int fd,int chan,int c,int o,int v)1174 poly800Memory(guiSynth *synth, int fd, int chan, int c, int o, int v)
1175 {
1176 	brightonEvent event;
1177 
1178 	if (synth->flags & MEM_LOADING)
1179 		return;
1180 	if ((synth->flags & OPERATIONAL) == 0)
1181 		return;
1182 
1183 	/*
1184 	 * Saving memories requires that we take a peek at the split/double settings
1185 	 * and then select the memory location accordingly. These are not going to
1186 	 * be performance parameters so we only save a single memory at a time.
1187 	 */
1188 	if (c == 0) {
1189 		/*
1190 		 * This is not a doubeClick: Select write, then select two digits for
1191 		 * the location
1192 		if (brightonDoubleClick(dc) != 0)
1193 			poly800SaveMemory(synth);
1194 		 */
1195 
1196 		if (memSave < 0)
1197 			return;
1198 
1199 		if ((memSave = 1 - memSave) != 0)
1200 		{
1201 			poly800UpdateDisplayDec(synth, fd, chan, c, 0, -1);
1202 		} else {
1203 			/*
1204 			 * Put back original memory
1205 			 */
1206 			if (synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV] <= 0)
1207 				poly800UpdateDisplayDec(synth, fd, chan, c, 0,
1208 					synth->bank * 10 + synth->location);
1209 		}
1210 
1211 		return;
1212 	}
1213 
1214 	if (c == 1) {
1215 		/*
1216 		 * Enter digit:
1217 		 *	If memSave selected, display digits, when two save mem.
1218 		 *
1219 		 * 	If Bank hold is selected then single digit will load the memory.
1220 		 *
1221 		 * 	Otherwise two digits are required
1222 		 */
1223 		if (memSave) {
1224 			if (synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV] <= 0)
1225 			{
1226 				event.type = BRIGHTON_FLOAT;
1227 				event.value = o;
1228 				brightonParamChange(synth->win, MODS_PANEL,
1229 					DISPLAY_DEV, &event);
1230 			} else {
1231 				event.type = BRIGHTON_FLOAT;
1232 				event.value = o;
1233 				brightonParamChange(synth->win, MODS_PANEL,
1234 					DISPLAY_DEV + 1, &event);
1235 
1236 				synth->bank = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV];
1237 				synth->location = o;
1238 
1239 				saveMemory(synth, SYNTH_NAME, 0, mbh + synth->bank * 10 + o, 0);
1240 
1241 				memSave = 0;
1242 			}
1243 			return;
1244 		}
1245 
1246 		if (bankHold)
1247 		{
1248 			/* Load memory */
1249 			synth->location = o;
1250 
1251 			event.type = BRIGHTON_FLOAT;
1252 			event.value = o;
1253 			brightonParamChange(synth->win, MODS_PANEL,
1254 				DISPLAY_DEV + 1, &event);
1255 
1256 			loadMemoryShim(synth, mbh + synth->bank * 10 + synth->location);
1257 
1258 			/* Even though we have now set all the parameters we need to return
1259 			 * our Prog status */
1260 			event.type = BRIGHTON_FLOAT;
1261 			event.value = 1;
1262 			brightonParamChange(synth->win, MODS_PANEL, 24, &event);
1263 			event.value = 0;
1264 			brightonParamChange(synth->win, MODS_PANEL, 25, &event);
1265 
1266 			memSave = 0;
1267 
1268 			return;
1269 		}
1270 
1271 		if (synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 1] > 0)
1272 		{
1273 			event.type = BRIGHTON_FLOAT;
1274 			event.value = o;
1275 			brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV, &event);
1276 
1277 			event.type = BRIGHTON_FLOAT;
1278 			event.value = -1;
1279 			brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV+1, &event);
1280 			synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 1] = -1;
1281 		} else {
1282 			event.type = BRIGHTON_FLOAT;
1283 			event.value = o;
1284 			brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV+1, &event);
1285 
1286 			synth->bank = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV];
1287 			synth->location = o;
1288 
1289 			loadMemoryShim(synth, mbh + synth->bank * 10 + synth->location);
1290 
1291 			/* Even though we have now set all the parameters we need to return
1292 			 * our Prog status */
1293 			event.type = BRIGHTON_FLOAT;
1294 			event.value = 1;
1295 			brightonParamChange(synth->win, MODS_PANEL, 24, &event);
1296 			event.value = 0;
1297 			brightonParamChange(synth->win, MODS_PANEL, 25, &event);
1298 
1299 			memSave = 0;
1300 		}
1301 	}
1302 }
1303 
1304 static void
poly800ParamSelect(guiSynth * synth,int v)1305 poly800ParamSelect(guiSynth *synth, int v)
1306 {
1307 	brightonEvent event;
1308 
1309 	if (synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3] > 0)
1310 	{
1311 		/* First digit */
1312 		event.type = BRIGHTON_FLOAT;
1313 		event.value = v;
1314 		brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 2, &event);
1315 
1316 		event.type = BRIGHTON_FLOAT;
1317 		event.value = -1;
1318 		brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 3, &event);
1319 		synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3] = -1;
1320 	} else {
1321 		/* Second digit */
1322 		event.type = BRIGHTON_FLOAT;
1323 		event.value = v;
1324 		brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 3, &event);
1325 		poly800Select(synth, synth->sid, synth->midichannel,
1326 			synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] * 10
1327 				+ synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3], 0, 0);
1328 	}
1329 }
1330 
1331 static int
poly800ModCallback(brightonWindow * win,int panel,int index,float value)1332 poly800ModCallback(brightonWindow *win, int panel, int index, float value)
1333 {
1334 	guiSynth *synth = findSynth(global.synths, win);
1335 	int off = 24, on = 25;
1336 	brightonEvent event;
1337 
1338 	if (global.libtest)
1339 		printf("poly800ModCallback(%i, %f)\n", index, value);
1340 
1341 	synth->mem.param[ACTIVE_DEVS + index] = value;
1342 
1343 	switch (index) {
1344 		case 0:
1345 			memSave = 1;
1346 			poly800Memory(synth, synth->sid, synth->midichannel, 0, 0, 0);
1347 			/* Bank hold button */
1348 			bankHold = 1 - bankHold;
1349 
1350 			event.type = BRIGHTON_FLOAT;
1351 			event.value = bankHold;
1352 			brightonParamChange(win, MODS_PANEL, 20, &event);
1353 
1354 			break;
1355 		case 1:
1356 		case 2:
1357 		case 3:
1358 		case 4:
1359 		case 5:
1360 		case 6:
1361 		case 7:
1362 		case 8:
1363 			/* Digits, dispatch according to prog button */
1364 			if (synth->mem.param[ACTIVE_DEVS + 24] != 0)
1365 			{
1366 				/* Program selectors */
1367 				poly800Memory(synth, synth->sid, synth->midichannel,
1368 					1, index, 0);
1369 			} else {
1370 				/* Param selectors */
1371 				poly800ParamSelect(synth, index);
1372 			}
1373 			break;
1374 		case 21:
1375 			/* Write */
1376 			if (synth->mem.param[ACTIVE_DEVS + 24] == 0)
1377 			{
1378 				event.type = BRIGHTON_FLOAT;
1379 				event.value = 1;
1380 				brightonParamChange(win, MODS_PANEL, 24, &event);
1381 				event.value = 0;
1382 				brightonParamChange(win, MODS_PANEL, 25, &event);
1383 			}
1384 
1385 			poly800Memory(synth, synth->sid, synth->midichannel, 0, index, 0);
1386 			break;
1387 		case 9:
1388 			/* Prog button */
1389 			memSave = 1;
1390 			poly800Memory(synth, synth->sid, synth->midichannel, 0, 0, 0);
1391 
1392 			if (synth->mem.param[ACTIVE_DEVS + 24] == 0) {
1393 				on = 24; off = 25;
1394 			}
1395 
1396 			event.type = BRIGHTON_FLOAT;
1397 			event.value = 1;
1398 			brightonParamChange(win, MODS_PANEL, on, &event);
1399 			event.value = 0;
1400 			brightonParamChange(win, MODS_PANEL, off, &event);
1401 
1402 			break;
1403 		case 10:
1404 			/* Volume */
1405 			bristolMidiSendMsg(global.controlfd, synth->midichannel,
1406 				126, 2, (int) (value * C_RANGE_MIN_1));
1407 			break;
1408 		case 11:
1409 			/* Tune */
1410 			bristolMidiSendMsg(global.controlfd, synth->midichannel,
1411 				126, 1, (int) (value * C_RANGE_MIN_1));
1412 			break;
1413 		case 12:
1414 			/* Bend depth - make this glide */
1415 			bristolMidiSendRP(global.controlfd, synth->sid,
1416 				MIDI_RP_PW, (int) (value) + 1);
1417 			bristolMidiSendMsg(global.controlfd, synth->midichannel,
1418 				126, 6, (int) (value * C_RANGE_MIN_1 / 12));
1419 			break;
1420 		case 13:
1421 			/* Poly mode - cancel chord/hold */
1422 			bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
1423 				BRISTOL_HOLD|0);
1424 			bristolMidiSendMsg(global.controlfd, synth->sid,
1425 				BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0);
1426 			crl = 0;
1427 			break;
1428 		case 14:
1429 			/*
1430 			 * Clear the sustain setting and start chord learning
1431 			 */
1432 			bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
1433 				BRISTOL_HOLD|0);
1434 
1435 			/*
1436 			 * Chord. To configure it you pressed hold, then the notes in the
1437 			 * chord, then pressed chord. We can't really use this so will try
1438 			 * to get the logic to go Hold->Chord->notes->Chord/Hold
1439 			 */
1440 			if (brightonDoubleClick(dc))
1441 			{
1442 				printf("chord hold\n");
1443 				poly800ChordRelearn(synth, synth->sid, synth->midichannel,
1444 					0, 0, 1);
1445 				crl = 1;
1446 				break;
1447 			}
1448 
1449 			crl = 0;
1450 			/*
1451 			 * Otherwise it is to enable chording.
1452 			 */
1453 			bristolMidiSendMsg(global.controlfd, synth->sid,
1454 				BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 1);
1455 			break;
1456 		case 15:
1457 			/* Hold mode - sustain */
1458 			brightonDoubleClick(dc);
1459 			bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
1460 				BRISTOL_HOLD|1);
1461 			bristolMidiSendMsg(global.controlfd, synth->sid,
1462 				BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0);
1463 			break;
1464 		case ENTRY_POT:
1465 			memSave = 1;
1466 			poly800Memory(synth, synth->sid, synth->midichannel, 0, 0, 0);
1467 
1468 			if (synth->mem.param[ACTIVE_DEVS + 24] != 0)
1469 			{
1470 				event.type = BRIGHTON_FLOAT;
1471 				event.value = 0;
1472 				brightonParamChange(win, MODS_PANEL, 24, &event);
1473 				event.value = 1;
1474 				brightonParamChange(win, MODS_PANEL, 25, &event);
1475 			}
1476 
1477 			poly800EntryPot(synth, synth->sid, synth->midichannel, 0, 0, value);
1478 			break;
1479 		case 17:
1480 			/*
1481 			 * Inc
1482 			 * Get the current display value and move it up towards the limit.
1483 			 * Then convert this into an int and send it to the entry pot.
1484 			 */
1485 			event.type = BRIGHTON_FLOAT;
1486 			index = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] * 10
1487 				+ synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3];
1488 			value = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 4] * 10
1489 				+ synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 5] + 1;
1490 
1491 			if (value > poly800Range[index].max)
1492 				value = poly800Range[index].max;
1493 
1494 			event.value = (value - poly800Range[index].min)
1495 				/ (poly800Range[index].max - poly800Range[index].min);
1496 
1497 //printf("%i: min %f max %f now %f/%f\n", index,
1498 //poly800Range[index].min, poly800Range[index].max, value, event.value);
1499 			brightonParamChange(win, MODS_PANEL, ENTRY_POT, &event);
1500 			break;
1501 		case 16:
1502 			/* Dec */
1503 			event.type = BRIGHTON_FLOAT;
1504 			index = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 2] * 10
1505 				+ synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 3];
1506 			value = synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 4] * 10
1507 				+ synth->mem.param[ACTIVE_DEVS + DISPLAY_DEV + 5] - 1;
1508 
1509 			if (value < poly800Range[index].min)
1510 				value = poly800Range[index].min;
1511 
1512 			event.value = (value - poly800Range[index].min)
1513 				/ ((float) poly800Range[index].max - poly800Range[index].min);
1514 
1515 //printf("%i: min %f max %f now %f/%f\n", index,
1516 //poly800Range[index].min, poly800Range[index].max, value, event.value);
1517 			brightonParamChange(win, MODS_PANEL, ENTRY_POT, &event);
1518 			break;
1519 		case 22:
1520 			/* Mod */
1521 			if (!global.libtest)
1522 				bristolMidiSendControlMsg(global.controlfd,
1523 					synth->midichannel,
1524 					1,
1525 					((int) (value * C_RANGE_MIN_1)) >> 7);
1526 			break;
1527 		case 23:
1528 			/* Joystick X motion - pitchbend */
1529 			if (!global.libtest)
1530 				bristolMidiSendMsg(global.controlfd, synth->midichannel,
1531 					BRISTOL_EVENT_PITCH, 0, (int) (value * C_RANGE_MIN_1));
1532 			break;
1533 	}
1534 
1535 	return(0);
1536 }
1537 
1538 /*
1539  * For the sake of ease of use, links have been placed here to be called
1540  * by any of the devices created. They would be better in some other file,
1541  * perhaps with this as a dispatch.
1542  *
1543  * Param refers to the device index in the locations table given below.
1544  */
1545 static int
poly800Callback(brightonWindow * win,int panel,int index,float value)1546 poly800Callback(brightonWindow *win, int panel, int index, float value)
1547 {
1548 	guiSynth *synth = findSynth(global.synths, win);
1549 	int sendvalue;
1550 
1551 	if (global.libtest)
1552 		printf("poly800Callback(%i, %f)\n", index, value);
1553 
1554 	if (synth == 0)
1555 		return(0);
1556 
1557 	if (panel == MODS_PANEL)
1558 		return(poly800ModCallback(win, panel, index, value));
1559 
1560 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
1561 		return(0);
1562 
1563 	if (poly800App.resources[0].devlocn[index].to == 1)
1564 		sendvalue = value * C_RANGE_MIN_1;
1565 	else
1566 		sendvalue = value;
1567 
1568 	if (index < 100)
1569 		poly800Select(synth,
1570 			global.controlfd, synth->sid,
1571 			synth->dispatch[index].controller,
1572 			synth->dispatch[index].operator,
1573 			sendvalue);
1574 
1575 	return(0);
1576 }
1577 
1578 static void
p800Detune(guiSynth * synth,int fd,int chan,int c,int o,int v)1579 p800Detune(guiSynth *synth, int fd, int chan, int c, int o, int v)
1580 {
1581 	int value = v;
1582 
1583 	if (!global.libtest) {
1584 		bristolMidiSendNRP(global.controlfd, synth->sid,
1585 			BRISTOL_NRP_DETUNE, value / 50);
1586 	}
1587 
1588 	bristolMidiSendMsg(fd, synth->sid, 0, 3, value);
1589 	bristolMidiSendMsg(fd, synth->sid, 1, 3, value);
1590 }
1591 
1592 static int pmc = -1;
1593 
1594 static void
p800midichannel(guiSynth * synth,int fd,int chan,int c,int o,int v)1595 p800midichannel(guiSynth *synth, int fd, int chan, int c, int o, int v)
1596 {
1597 	if (global.libtest)
1598 		return;
1599 
1600 	if (synth->mem.param[88] != 0)
1601 		v = BRISTOL_CHAN_OMNI;
1602 	else
1603 		v = synth->mem.param[86] * 15;
1604 
1605 	if (v == pmc)
1606 		return;
1607 
1608 	bristolMidiSendMsg(global.controlfd, synth->sid,
1609 		127, 0, BRISTOL_MIDICHANNEL|v);
1610 
1611 	pmc = v;
1612 }
1613 
1614 static void
p800lfo(guiSynth * synth,int fd,int chan,int c,int o,int v)1615 p800lfo(guiSynth *synth, int fd, int chan, int c, int o, int v)
1616 {
1617 	/*
1618 	 * We have to configure the engine to generate one or more LFO but more
1619 	 * subtly we also have to tell the LFO not to synchronise to key_on.
1620 	 */
1621 	bristolMidiSendMsg(fd, synth->sid, 8, 1, v);
1622 	bristolMidiSendMsg(fd, synth->sid, 126, 11, v);
1623 }
1624 
1625 static void
p800filterEnv(guiSynth * synth,int fd,int chan,int c,int o,int v)1626 p800filterEnv(guiSynth *synth, int fd, int chan, int c, int o, int v)
1627 {
1628 	bristolMidiSendMsg(fd, synth->sid, 126, 12, v);
1629 	/* May have to change envelope triggering as well? */
1630 	bristolMidiSendMsg(fd, synth->sid, 6, 12, v);
1631 }
1632 
1633 static void
p800chorus(guiSynth * synth,int fd,int chan,int c,int o,int v)1634 p800chorus(guiSynth *synth, int fd, int chan, int c, int o, int v)
1635 {
1636 	if (synth->mem.param[48] <= 0.5)
1637 		bristolMidiSendMsg(fd, synth->sid, 100, 3, 0);
1638 	else
1639 		bristolMidiSendMsg(fd, synth->sid, 100, 3,
1640 			(int) (synth->mem.param[47] * C_RANGE_MIN_1));
1641 }
1642 
1643 static void
p800velocity(guiSynth * synth,int fd,int chan,int c,int o,int v)1644 p800velocity(guiSynth *synth, int fd, int chan, int c, int o, int v)
1645 {
1646 	int x = 0, y = 0, z = 0;
1647 
1648 	if (v & 0x01) x = 1;
1649 	if (v & 0x02) y = 1;
1650 	if (v & 0x04) z = 1;
1651 
1652 	bristolMidiSendMsg(fd, synth->sid, 4, 10, x);
1653 	bristolMidiSendMsg(fd, synth->sid, 5, 10, y);
1654 	bristolMidiSendMsg(fd, synth->sid, 6, 10, z);
1655 }
1656 
1657 static void
p800detune(guiSynth * synth,int fd,int chan,int c,int o,int v)1658 p800detune(guiSynth *synth, int fd, int chan, int c, int o, int v)
1659 {
1660 //printf("detune %i %i %i\n", c, o, v);
1661 	bristolMidiSendMsg(fd, synth->sid, 1, 0, 8192 + v / 2);
1662 }
1663 
1664 static void
p800waveform(guiSynth * synth,int fd,int chan,int c,int o,int v)1665 p800waveform(guiSynth *synth, int fd, int chan, int c, int o, int v)
1666 {
1667 //printf("waveform %i %i %i\n", c, o, v);
1668 	bristolMidiSendMsg(fd, synth->sid, c, 9, (int) (C_RANGE_MIN_1 - v));
1669 	bristolMidiSendMsg(fd, synth->sid, c, 10, v);
1670 }
1671 
1672 static void
p800octave(guiSynth * synth,int fd,int chan,int c,int o,int v)1673 p800octave(guiSynth *synth, int fd, int chan, int c, int o, int v)
1674 {
1675 	/*
1676 	 * We are delivered 0, 1 or 2, need to multiply by 12 notes
1677 	 */
1678 	if (c == 0)
1679 		bristolMidiSendMsg(fd, synth->sid, 0, 2, v * 12);
1680 	else
1681 		bristolMidiSendMsg(fd, synth->sid, 1, 2,
1682 			((int) (synth->mem.param[21] * 2)) * 12 +
1683 			(int) (synth->mem.param[31] * 12));
1684 }
1685 
1686 /*
1687  * Any location initialisation required to run the callbacks. For bristol, this
1688  * will connect to the engine, and give it some base parameters.
1689  * May need to generate some application specific menus.
1690  * Will also then make specific requests to some of the devices to alter their
1691  * rendering.
1692  */
1693 static int
poly800Init(brightonWindow * win)1694 poly800Init(brightonWindow *win)
1695 {
1696 	guiSynth *synth = findSynth(global.synths, win);
1697 	dispatcher *dispatch;
1698 	int i;
1699 
1700 	if (synth == 0)
1701 	{
1702 		synth = findSynth(global.synths, 0);
1703 		if (synth == 0)
1704 		{
1705 			printf("cannot init\n");
1706 			return(0);
1707 		}
1708 	}
1709 
1710 	synth->win = win;
1711 
1712 	printf("Initialise the poly800 link to bristol: %p\n", synth->win);
1713 
1714 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
1715 	synth->mem.count = DEVICE_COUNT;
1716 	synth->mem.active = ACTIVE_DEVS;
1717 	synth->dispatch = (dispatcher *)
1718 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
1719 	dispatch = synth->dispatch;
1720 
1721 	/*
1722 	 * We really want to have three connection mechanisms. These should be
1723 	 *	1. Unix named sockets.
1724 	 *	2. UDP sockets (actually implements TCP unfortunately).
1725 	 *	3. MIDI pipe.
1726 	 */
1727 	if (!global.libtest)
1728 	{
1729 		bcopy(&global, &manual, sizeof(guimain));
1730 		if ((synth->sid = initConnection(&global, synth)) < 0)
1731 			return(-1);
1732 
1733 		manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE;
1734 		manual.port = global.port;
1735 	}
1736 
1737 	for (i = 0; i < ACTIVE_DEVS; i++)
1738 	{
1739 		synth->dispatch[i].routine = NULL;
1740 		synth->dispatch[i].controller = i;
1741 		synth->dispatch[i].operator = i;
1742 	}
1743 
1744 	synth->dispatch[11].routine = (synthRoutine) p800octave;
1745 	synth->dispatch[12].routine = (synthRoutine) p800waveform;
1746 
1747 	synth->dispatch[21].routine = (synthRoutine) p800octave;
1748 	synth->dispatch[22].routine = (synthRoutine) p800waveform;
1749 	synth->dispatch[31].routine = (synthRoutine) p800octave;
1750 
1751 	synth->dispatch[32].routine = (synthRoutine) p800detune; /* DCO-2 */
1752 	synth->dispatch[38].routine = (synthRoutine) p800Detune; /* Global */
1753 
1754 	synth->dispatch[46].routine = (synthRoutine) p800filterEnv; /* Global */
1755 
1756 	synth->dispatch[47].routine = (synthRoutine) p800chorus; /* Global */
1757 	synth->dispatch[48].routine = (synthRoutine) p800chorus; /* Global */
1758 
1759 	synth->dispatch[57].routine = (synthRoutine) p800velocity;
1760 
1761 	synth->dispatch[85].routine = (synthRoutine) p800lfo;
1762 	synth->dispatch[86].routine = (synthRoutine) p800midichannel;
1763 	synth->dispatch[88].routine = (synthRoutine) p800midichannel;
1764 
1765 	for (; i < DEVICE_COUNT; i++)
1766 		synth->dispatch[i].routine = (synthRoutine) poly800MidiShim;
1767 
1768 	synth->dispatch[0].routine = (synthRoutine) poly800MidiNull;
1769 
1770 	/* Osc-1 settings */
1771 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 8192);
1772 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, 8192);
1773 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 0);
1774 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 8, 0); /* No 32' */
1775 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 11, 0); /* No tri */
1776 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 12, 0); /* No sin */
1777 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 15, 0); /* P800 type */
1778 
1779 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 8192);
1780 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 8, 0); /* No 32' */
1781 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 11, 0); /* No tri */
1782 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 12, 0); /* No sin */
1783 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 15, 0); /* P800 type */
1784 
1785 	/* Env settings */
1786 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 0, 0);
1787 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 16383);
1788 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 8, 0);
1789 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 11, 0);
1790 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 12, 1);
1791 
1792 	bristolMidiSendMsg(global.controlfd, synth->sid, 5, 0, 0);
1793 	bristolMidiSendMsg(global.controlfd, synth->sid, 5, 2, 16383);
1794 	bristolMidiSendMsg(global.controlfd, synth->sid, 5, 8, 0);
1795 	bristolMidiSendMsg(global.controlfd, synth->sid, 5, 11, 0);
1796 	bristolMidiSendMsg(global.controlfd, synth->sid, 5, 12, 1);
1797 
1798 	bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, 0);
1799 	bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, 16383);
1800 	bristolMidiSendMsg(global.controlfd, synth->sid, 6, 8, 0);
1801 	bristolMidiSendMsg(global.controlfd, synth->sid, 6, 9, 16383);
1802 	bristolMidiSendMsg(global.controlfd, synth->sid, 6, 11, 1);
1803 	/* Filter */
1804 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, 16383);
1805 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 4, 4);
1806 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 5, 16383);
1807 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 6, 0);
1808 
1809 	return(0);
1810 }
1811 
1812 /*
1813  * This will be called to make any routine specific parameters available.
1814  */
1815 static int
poly800Configure(brightonWindow * win)1816 poly800Configure(brightonWindow *win)
1817 {
1818 	guiSynth *synth = findSynth(global.synths, win);
1819 	brightonEvent event;
1820 
1821 	if (synth == 0)
1822 	{
1823 		printf("problems going operational\n");
1824 		return(-1);
1825 	}
1826 
1827 	if (synth->location == 0) {
1828 		synth->bank = 1;
1829 		synth->location = 1;
1830 	} else {
1831 		mbh = (synth->location / 100) * 100;
1832 		if ((synth->bank = synth->location / 10) > 10)
1833 			synth->bank = synth->bank % 10;
1834 		if (((synth->location = synth->location % 10) == 0)
1835 			|| (synth->location > 8))
1836 			synth->location = 1;
1837 	}
1838 
1839 	if (synth->flags & OPERATIONAL)
1840 		return(0);
1841 
1842 	printf("going operational\n");
1843 
1844 	synth->flags |= OPERATIONAL;
1845 	synth->keypanel = 1;
1846 	synth->keypanel2 = -1;
1847 	synth->transpose = 24;
1848 
1849 	brightonPut(win,
1850 		"bitmaps/blueprints/poly800shade.xpm", 0, 0, win->width, win->height);
1851 
1852 	/*
1853 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1854 	 * occurs on first paint, so we suppress the first paint, and then request
1855 	 * an expose here.
1856 	 */
1857 	event.type = BRIGHTON_EXPOSE;
1858 	event.intvalue = 1;
1859 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1860 	configureGlobals(synth);
1861 
1862 	/* Setup the displays */
1863 	event.value = 1;
1864 	brightonParamChange(synth->win, MODS_PANEL, 24, &event);
1865 	event.value = synth->bank;
1866 	brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV, &event);
1867 	event.value = synth->location;
1868 	brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 1, &event);
1869 	event.value = 1;
1870 	brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 2, &event);
1871 	brightonParamChange(synth->win, MODS_PANEL, DISPLAY_DEV + 3, &event);
1872 
1873 	/* Volume, tuning, bend */
1874 	event.value = 0.822646;
1875 	brightonParamChange(synth->win, MODS_PANEL, 10, &event);
1876 	event.value = 0.5;
1877 	brightonParamChange(synth->win, MODS_PANEL, 11, &event);
1878 	event.value = 0.05;
1879 	brightonParamChange(synth->win, MODS_PANEL, 12, &event);
1880 
1881 	loadMemoryShim(synth, mbh + synth->bank * 10 + synth->location);
1882 
1883 	/*
1884 	 * Go into Prog rather than Param mode
1885 	 */
1886 	event.value = 1;
1887 	brightonParamChange(synth->win, MODS_PANEL, 24, &event);
1888 	event.value = 0;
1889 	brightonParamChange(synth->win, MODS_PANEL, 25, &event);
1890 
1891 	bristolMidiSendRP(global.controlfd, synth->sid, MIDI_RP_PW, 8192);
1892 	bristolMidiSendMsg(global.controlfd, synth->midichannel,
1893 		BRISTOL_EVENT_PITCH, 0, 8192);
1894 
1895 	event.value = 2.0;
1896 	brightonParamChange(synth->win, MODS_PANEL, 12, &event);
1897 
1898 	dc = brightonGetDCTimer(2000000);
1899 
1900 	memSave = 0;
1901 
1902 	synth->loadMemory = (loadRoutine) p800loadMemory;
1903 
1904 	return(0);
1905 }
1906 
1907