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  * Fast timer events.
24  *
25  * Devices are registered for fast timers, the callback should occur on the
26  * clock cycle.
27  */
28 #include "brightoninternals.h"
29 
30 #define _BRIGHTON_FT_GO 0x0001
31 #define _BRIGHTON_FT_ON 0x0002
32 
33 #define _BRIGHTON_FT_COUNT 128
34 
35 static struct {
36 	struct {
37 		brightonWindow *win;
38 		int panel;
39 		int index;
40 	} ftl[_BRIGHTON_FT_COUNT];
41 	int tick, duty;
42 	int current;
43 	int in, out, total;
44 	int flags;
45 } brightonFTL;
46 
47 static void
brightonScanTimerList(int ms)48 brightonScanTimerList(int ms)
49 {
50 	brightonEvent event;
51 
52 //printf("ScanFastTimerList(%i): %i/%i\n", ms, brightonFTL.tick, brightonFTL.duty);
53 	if (brightonFTL.total == 0)
54 		return;
55 
56 	if ((brightonFTL.current += ms) >= brightonFTL.tick)
57 	{
58 		event.command = BRIGHTON_FAST_TIMER;
59 
60 		if (brightonFTL.flags & _BRIGHTON_FT_ON)
61 		{
62 			/* Previous led is still on */
63 			event.value = 0;
64 
65 			brightonParamChange(
66 				brightonFTL.ftl[brightonFTL.out].win,
67 				brightonFTL.ftl[brightonFTL.out].panel,
68 				brightonFTL.ftl[brightonFTL.out].index,
69 				&event);
70 		}
71 
72 		if (++brightonFTL.out >= brightonFTL.total)
73 			brightonFTL.out = 0;
74 
75 		brightonFTL.current = 0;
76 		brightonFTL.flags |= _BRIGHTON_FT_ON;
77 
78 		/*
79 		 * Send ON event
80 		 */
81 		event.value = 1.0;
82 
83 		brightonParamChange(
84 			brightonFTL.ftl[brightonFTL.out].win,
85 			brightonFTL.ftl[brightonFTL.out].panel,
86 			brightonFTL.ftl[brightonFTL.out].index,
87 			&event);
88 	} else {
89 		if ((brightonFTL.current >= brightonFTL.duty)
90 			&& (brightonFTL.flags & _BRIGHTON_FT_ON))
91 		{
92 			brightonFTL.flags &= ~_BRIGHTON_FT_ON;
93 			/*
94 			 * Send OFF event
95 			 */
96 			event.command = BRIGHTON_FAST_TIMER;
97 			event.value = 0;
98 
99 			brightonParamChange(
100 				brightonFTL.ftl[brightonFTL.out].win,
101 				brightonFTL.ftl[brightonFTL.out].panel,
102 				brightonFTL.ftl[brightonFTL.out].index,
103 				&event);
104 		}
105 	}
106 }
107 
108 static int
brightonFTRegister(brightonWindow * win,int panel,int index)109 brightonFTRegister(brightonWindow *win, int panel, int index)
110 {
111 //printf("Req: %i %i/%i\n", brightonFTL.in, panel, index);
112 
113 	if (brightonFTL.in >= _BRIGHTON_FT_COUNT)
114 		return(-1);
115 
116 	brightonFTL.ftl[brightonFTL.in].win = win;
117 	brightonFTL.ftl[brightonFTL.in].panel = panel;
118 	brightonFTL.ftl[brightonFTL.in++].index = index;
119 
120 	return(++brightonFTL.total);
121 }
122 
123 static int
brightonFTDegister(brightonWindow * win,int panel,int index,int id)124 brightonFTDegister(brightonWindow *win, int panel, int index, int id)
125 {
126 	brightonFTL.flags = 0;
127 	brightonFTL.in = 0;
128 	brightonFTL.out = 0;
129 	brightonFTL.total = 0;
130 	brightonFTL.current = 0;
131 
132 	return(-1);
133 }
134 
135 int
brightonFastTimer(brightonWindow * win,int panel,int index,int command,int ms)136 brightonFastTimer(brightonWindow *win, int panel, int index, int command, int ms)
137 {
138 //printf("brightonFastTimer(%i, %i)\n", command, ms);
139 	switch (command) {
140 		case BRIGHTON_FT_CLOCK:
141 			if (brightonFTL.flags & _BRIGHTON_FT_GO)
142 				brightonScanTimerList(ms);
143 			break;
144 		case BRIGHTON_FT_TICKTIME:
145 			brightonFTL.tick = ms;
146 			break;
147 		case BRIGHTON_FT_DUTYCYCLE:
148 			brightonFTL.duty = ms;
149 			break;
150 		case BRIGHTON_FT_START:
151 			if (brightonFTL.flags & _BRIGHTON_FT_GO)
152 				brightonFTL.flags &= ~_BRIGHTON_FT_GO;
153 			else
154 				brightonFTL.flags |= _BRIGHTON_FT_GO;
155 			break;
156 		case BRIGHTON_FT_STOP:
157 		default:
158 			brightonFTL.flags &= ~_BRIGHTON_FT_GO;
159 			brightonFTL.out = 0;
160 			brightonFTL.current = 0;
161 			break;
162 		case BRIGHTON_FT_REQ:
163 			return(brightonFTRegister(win, panel, index));
164 		case BRIGHTON_FT_CANCEL:
165 			return(brightonFTDegister(win, panel, index, command));
166 		case BRIGHTON_FT_STEP:
167 			break;
168 	}
169 
170 	return(0);
171 }
172 
173