added an old version of mikmod for dos
[dosdemo] / libs / oldmik / src / mdriver.c
1 /*
2
3 Name:
4 MDRIVER.C
5
6 Description:
7 These routines are used to access the available soundcard drivers.
8
9 Portability:
10 All systems - all compilers
11
12 */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include "mikmod.h"
16
17 DRIVER *firstdriver=NULL,*md_driver;
18
19 UWORD md_device         =0;
20 UWORD md_mixfreq        =44100;
21 UWORD md_mode           =0;
22 UWORD md_dmabufsize     =8192;
23 UBYTE md_numchn         =0;
24 UBYTE md_bpm            =125;
25
26 static void dummyplay(void)
27 {
28 }
29
30 void (*md_player)(void)=dummyplay;
31
32 static FILE *sl_fp;
33 static SWORD sl_old;
34 static UWORD sl_infmt;
35 static UWORD sl_outfmt;
36 static SWORD sl_buffer[1024];
37
38 static BOOL isplaying=0;
39
40
41 void SL_Init(FILE *fp,UWORD infmt,UWORD outfmt)
42 {
43         sl_old=0;
44         sl_fp=fp;
45         sl_infmt=infmt;
46         sl_outfmt=outfmt;
47 }
48
49
50 void SL_Exit(void)
51 {
52 }
53
54
55 void SL_Load(void *buffer,ULONG length)
56 {
57         SBYTE *bptr=(SBYTE *)buffer;
58         SWORD *wptr=(SWORD *)buffer;
59         UWORD stodo;
60         int t;
61
62         /* compute number of samples to load */
63         if(sl_outfmt & SF_16BITS) length>>=1;
64
65         while(length){
66
67                 stodo=(length<1024) ? length : 1024;
68
69                 if(sl_infmt&SF_16BITS){
70                         fread(sl_buffer,sizeof(SWORD),stodo,sl_fp);
71 #ifdef MM_BIG_ENDIAN
72                         if(!(sl_infmt&SF_BIG_ENDIAN))
73                                 swab((char *)sl_buffer,(char *)sl_buffer,stodo<<1);
74 #else
75                         /* assume machine is little endian by default */
76                         if(sl_infmt&SF_BIG_ENDIAN)
77                                 swab((char *)sl_buffer,(char *)sl_buffer,stodo<<1);
78 #endif
79                 }
80                 else{
81                         SBYTE *s;
82                         SWORD *d;
83
84                         fread(sl_buffer,sizeof(SBYTE),stodo,sl_fp);
85
86                         s=(SBYTE *)sl_buffer;
87                         d=sl_buffer;
88                         s+=stodo;
89                         d+=stodo;
90
91                         for(t=0;t<stodo;t++){
92                                 s--;
93                                 d--;
94                                 *d=(*s)<<8;
95                         }
96                 }
97
98                 if(sl_infmt & SF_DELTA){
99                         for(t=0;t<stodo;t++){
100                                 sl_buffer[t]+=sl_old;
101                                 sl_old=sl_buffer[t];
102                         }
103                 }
104
105                 if((sl_infmt^sl_outfmt) & SF_SIGNED){
106                         for(t=0;t<stodo;t++){
107                                 sl_buffer[t]^=0x8000;
108                         }
109                 }
110
111                 if(sl_outfmt & SF_16BITS){
112                         for(t=0;t<stodo;t++) *(wptr++)=sl_buffer[t];
113                 }
114                 else{
115                         for(t=0;t<stodo;t++) *(bptr++)=sl_buffer[t]>>8;
116                 }
117
118                 length-=stodo;
119         }
120 }
121
122
123 void MD_InfoDriver(void)
124 {
125         int t;
126         DRIVER *l;
127
128         /* list all registered devicedrivers: */
129
130         for(t=1,l=firstdriver; l!=NULL; l=l->next, t++){
131                 printf("%d. %s\n",t,l->Version);
132         }
133 }
134
135
136 void MD_RegisterDriver(DRIVER *drv)
137 {
138         if(firstdriver==NULL){
139                 firstdriver=drv;
140                 drv->next=NULL;
141         }
142         else{
143                 drv->next=firstdriver;
144                 firstdriver=drv;
145         }
146 }
147
148
149 SWORD MD_SampleLoad(FILE *fp,ULONG size,ULONG reppos,ULONG repend,UWORD flags)
150 {
151         SWORD result=md_driver->SampleLoad(fp,size,reppos,repend,flags);
152         SL_Exit();
153         return result;
154 }
155
156
157 void MD_SampleUnLoad(SWORD handle)
158 {
159         md_driver->SampleUnLoad(handle);
160 }
161
162
163 BOOL MD_Init(void)
164 {
165         UWORD t;
166
167         /* if md_device==0, try to find a device number */
168
169         if(md_device==0){
170
171                 for(t=1,md_driver=firstdriver; md_driver!=NULL; md_driver=md_driver->next, t++){
172                         if(md_driver->IsPresent()) break;
173                 }
174
175                 if(md_driver==NULL){
176                         myerr="You don't have any of the supported sound-devices";
177                         return 0;
178                 }
179
180                 md_device=t;
181         }
182
183         /* if n>0 use that driver */
184
185         for(t=1,md_driver=firstdriver; md_driver!=NULL && t!=md_device; md_driver=md_driver->next, t++);
186
187         if(md_driver==NULL){
188                 myerr="Device number out of range";
189                 return 0;
190         }
191
192         return(md_driver->Init());
193 }
194
195
196 void MD_Exit(void)
197 {
198         md_driver->Exit();
199 }
200
201
202 void MD_PlayStart(void)
203 {
204         /* safety valve, prevents entering
205            playstart twice: */
206
207         if(isplaying) return;
208         md_driver->PlayStart();
209         isplaying=1;
210 }
211
212
213 void MD_PlayStop(void)
214 {
215         /* safety valve, prevents calling playStop when playstart
216            hasn't been called: */
217
218         if(isplaying){
219                 isplaying=0;
220                 md_driver->PlayStop();
221         }
222 }
223
224
225 void MD_SetBPM(UBYTE bpm)
226 {
227         md_bpm=bpm;
228 }
229
230
231 void MD_RegisterPlayer(void (*player)(void))
232 {
233         md_player=player;
234 }
235
236
237 void MD_Update(void)
238 {
239         if(isplaying) md_driver->Update();
240 }
241
242
243 void MD_VoiceSetVolume(UBYTE voice,UBYTE vol)
244 {
245         md_driver->VoiceSetVolume(voice,vol);
246 }
247
248
249 void MD_VoiceSetFrequency(UBYTE voice,ULONG frq)
250 {
251         md_driver->VoiceSetFrequency(voice,frq);
252 }
253
254
255 void MD_VoiceSetPanning(UBYTE voice,ULONG pan)
256 {
257         md_driver->VoiceSetPanning(voice,pan);
258 }
259
260
261 void MD_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags)
262 {
263         md_driver->VoicePlay(voice,handle,start,size,reppos,repend,flags);
264 }