2 * Allegro Sound library support routines
17 extern int digi_timer_rate;
19 char allegro_error[80]="";
21 #define TIMERS_PER_SECOND 1193181L
22 #define MSEC_TO_TIMER(x) ((long)(x) * (TIMERS_PER_SECOND / 1000))
24 static struct { /* list of active callbacks */
28 } my_int_queue[MAX_TIMERS];
29 static int find_timer_slot(void (*proc)())
33 for (x=0; x<MAX_TIMERS; x++)
34 if (my_int_queue[x].proc == proc)
39 int install_int_ex(void (*proc)(), long speed)
43 if (!timer_installed) {
44 /* we are not alive yet: flag this callback to be started later */
45 if (waiting_list_size >= MAX_TIMERS)
48 waiting_list[waiting_list_size].proc = proc;
49 waiting_list[waiting_list_size].speed = speed;
54 x = find_timer_slot(proc); /* find the handler position */
56 if (x < 0) /* if not there, find free slot */
57 x = find_timer_slot(NULL);
59 if (x < 0) /* are there any free slots? */
62 if (proc != my_int_queue[x].proc) { /* add new entry */
63 my_int_queue[x].counter = speed;
64 my_int_queue[x].proc = proc;
66 else { /* alter speed of existing entry */
67 my_int_queue[x].counter -= my_int_queue[x].speed;
68 my_int_queue[x].counter += speed;
71 my_int_queue[x].speed = speed;
75 int install_int(void (*proc)(), long speed)
77 return install_int_ex(proc, MSEC_TO_TIMER(speed));
79 void remove_int(void (*proc)())
81 int x = find_timer_slot(proc);
84 my_int_queue[x].proc = NULL;
85 my_int_queue[x].speed = 0;
86 my_int_queue[x].counter = 0;
90 void allg_snd_timer() {
92 for (x=0; x<MAX_TIMERS; x++) {
93 my_int_queue[x].counter -= digi_timer_rate;
94 while ((my_int_queue[x].proc) && (my_int_queue[x].counter <= 0)) {
95 my_int_queue[x].counter += my_int_queue[x].speed;
96 my_int_queue[x].proc();
101 END_OF_FUNCTION(allg_snd_timer)
103 void _add_exit_func(void (*func)()) {
106 void _remove_exit_func(void (*func)()) {
108 void _unlock_dpmi_data(void *addr, int size)
110 unsigned long baseaddr;
113 __dpmi_get_segment_base_address(_go32_my_ds(), &baseaddr);
115 mem.address = baseaddr + (unsigned long)addr;
118 __dpmi_unlock_linear_region(&mem );
123 _go32_dpmi_seginfo old;
124 _go32_dpmi_seginfo new;
127 //added/killed on 10/27/98 by adb. moved to comm/irq.c
128 //-killed- struct oldirq saveirq={-1};
130 //-killed- int _install_irq(int intnum, int (*func)()) {
131 //-killed- if (saveirq.intnum != -1)
133 //-killed- saveirq.intnum=intnum;
134 //-killed- saveirq.new.pm_offset = (int)func;
135 //-killed- saveirq.new.pm_selector = _my_cs();
136 //-killed- _go32_dpmi_get_protected_mode_interrupt_vector(intnum, &saveirq.old);
137 //-killed- _go32_dpmi_allocate_iret_wrapper(&saveirq.new);
138 //-killed- _go32_dpmi_set_protected_mode_interrupt_vector(intnum, &saveirq.new);
142 //-killed- void _remove_irq(int intnum) {
143 //-killed- _go32_dpmi_set_protected_mode_interrupt_vector(intnum, &saveirq.old);
144 //-killed- _go32_dpmi_free_iret_wrapper(&saveirq.new);
145 //-killed- saveirq.intnum = -1;
147 //end this section kill - adb
149 static unsigned char *conv_delta(unsigned char *data, unsigned char *dataend) {
151 unsigned long delta = 0;
155 while ((p < dataend) && !(*p & 0x80)) {
156 delta += *(p++) << shift;
161 delta += (*(p++) & 0x7f) << shift;
165 while ((delta > 0) || (shift == 0)) {
166 *(--p) = (delta & 127) | shift;
174 * read a MIDI type variabele length number
176 static unsigned char *read_var(unsigned char *data, unsigned char *dataend,
177 unsigned long *value) {
180 while ((data < dataend) && (*data & 0x80))
181 v = (v << 7) + (*(data++) & 0x7f);
184 v = (v << 7) + *(data++);
185 if (value) *value = v;
189 static int trans_data(unsigned char *data, int size) {
190 static int cmdlen[7]={3,3,3,3,2,2,3};
191 unsigned char *dataend = data + size;
194 while (data < dataend) {
195 if (!(data = conv_delta(data, dataend)))
199 return 1; /* need something after delta */
202 return 1; /* invalid command */
204 data += cmdlen[((*data) >> 4) - 8];
205 } else if (*data == 0xff) {
209 if (!(data = read_var(data, dataend, &v)))
212 } else /* sysex -> error */
215 return (data != dataend); /* processed as many as received? */
219 * load HMP file into Allegro MIDI structure by translating the deltas
220 * and adding tempo information
222 MIDI *load_hmp(char *filename) {
223 static unsigned char hmp_tempo[7] =
224 {0x00, 0xff, 0x51, 0x03, 0x0f, 0x42, 0x40};
234 removeext(filename, buf);
236 if ((midi = load_midi(buf)))
238 if (!(fp = cfopen(filename, "rb")))
241 midi = malloc(sizeof(MIDI)); /* get some memory */
247 for (c=0; c<MIDI_TRACKS; c++) {
248 midi->track[c].data = NULL;
249 midi->track[c].len = 0;
252 if ((cfread(buf, 1, 8, fp) != 8) || (memcmp(buf, "HMIMIDIP", 8)))
255 if (cfseek(fp, 0x30, SEEK_SET))
258 if (cfread(&num_tracks, 4, 1, fp) != 1)
261 if ((num_tracks < 1) || (num_tracks > MIDI_TRACKS))
264 midi->divisions = 120;
266 if (cfseek(fp, 0x308, SEEK_SET))
269 for (c=0; c<num_tracks; c++) { /* read each track */
270 if ((cfseek(fp, 4, SEEK_CUR)) || (cfread(&data, 4, 1, fp) != 1))
275 if (c == 0) /* track 0: reserve length for tempo */
276 data += sizeof(hmp_tempo);
278 midi->track[c].len = data;
280 if (!(p = midi->track[c].data = malloc(data))) /* allocate memory */
283 if (c == 0) { /* track 0: add tempo */
284 memcpy(p, hmp_tempo, sizeof(hmp_tempo));
285 p += sizeof(hmp_tempo);
286 data -= sizeof(hmp_tempo);
288 /* finally, read track data */
289 if ((cfseek(fp, 4, SEEK_CUR)) || (cfread(p, data, 1, fp) != 1))
292 if (trans_data(p, data)) /* translate deltas hmp -> midi */
306 char *pack_fgets(char *p, int max, PACKFILE *f) {
314 for (c=0; c<max-1; c++) {
318 else if (p[c] == '\n')
330 char *get_extension(const char *s) {
332 if ((p = strrchr(s, '.')))
336 char *get_filename(const char *s) {
338 if ((p = strrchr(s, '\\')))
340 if ((p = strrchr(s, '/')))
344 long file_size(const char *n) {
350 void put_backslash(char *n) {
352 if(((p=strchr(n,0))>=p) && (*(p-1)!='/') && (*(p-1)!='\\')
353 && (*(p-1)!=':')) { *(p++)='/'; *p=0;}
356 void allg_snd_init() {
357 if (LOCK_VARIABLE(my_int_queue) ||
358 LOCK_VARIABLE(digi_timer_rate) ||
359 LOCK_VARIABLE(retrace_count) ||
360 LOCK_FUNCTION(allg_snd_timer))
361 Error("Error locking sound timer");
362 timer_set_function(allg_snd_timer);
365 // return true if using the digmid driver
366 int allegro_using_digmid() {
367 return get_config_int("sound", "midi_card", MIDI_AUTODETECT) == MIDI_DIGMID;