]> icculus.org git repositories - btb/d2x.git/blob - arch/sdl/rbaudio.c
Merge branch 'master' into cmd-queue
[btb/d2x.git] / arch / sdl / rbaudio.c
1 /* $Id: rbaudio.c,v 1.9 2004-04-14 08:32:49 btb Exp $ */
2 /*
3  *
4  * SDL CD Audio functions
5  *
6  *
7  */
8
9 #ifdef HAVE_CONFIG_H
10 #include <conf.h>
11 #endif
12
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 #include <SDL.h>
17
18 #ifdef __linux__
19 #include <sys/ioctl.h>
20 #include <linux/cdrom.h>
21 #endif
22
23 #include "pstypes.h"
24 #include "error.h"
25 #include "args.h"
26 #include "rbaudio.h"
27
28 static SDL_CD *s_cd = NULL;
29 static int initialised = 0;
30
31 void RBAExit()
32 {
33         if (initialised)
34         {
35                 SDL_CDStop(s_cd);
36                 SDL_CDClose(s_cd);
37         }
38 }
39
40 void RBAInit()
41 {
42         if (initialised) return;
43         if (FindArg("-nocdrom")) return; 
44
45         if (SDL_Init(SDL_INIT_CDROM) < 0)
46         {
47                 Warning("SDL library initialisation failed: %s.",SDL_GetError());
48                 return;
49         }
50
51         if (SDL_CDNumDrives() == 0)
52         {
53                 Warning("No cdrom drives found!\n");
54                 return;
55         }
56         s_cd = SDL_CDOpen(0);
57         if (s_cd == NULL) {
58                 Warning("Could not open cdrom for redbook audio!\n");
59                 return;
60         }
61
62         SDL_CDStatus(s_cd); /* update the drive status */
63
64         atexit(RBAExit);
65         initialised = 1;
66 }
67
68 int RBAEnabled()
69 {
70         return 1;
71 }
72
73 void RBARegisterCD()
74 {
75
76 }
77
78 int RBAPlayTrack(int a)
79 {
80         if (!initialised) return -1;
81
82         if (CD_INDRIVE(SDL_CDStatus(s_cd)) ) {
83                 SDL_CDPlayTracks(s_cd, a-1, 0, 0, 0);
84         }
85         return a;
86 }
87
88 void RBAStop()
89 {
90         if (!initialised) return;
91         SDL_CDStop(s_cd);
92 }
93
94 void RBASetVolume(int volume)
95 {
96 #ifdef __linux__
97         int cdfile, level;
98         struct cdrom_volctrl volctrl;
99
100         if (!initialised) return;
101
102         cdfile = s_cd->id;
103         level = volume * 3;
104
105         if ((level<0) || (level>255)) {
106                 fprintf(stderr, "illegal volume value (allowed values 0-255)\n");
107                 return;
108         }
109
110         volctrl.channel0
111                 = volctrl.channel1
112                 = volctrl.channel2
113                 = volctrl.channel3
114                 = level;
115         if ( ioctl(cdfile, CDROMVOLCTRL, &volctrl) == -1 ) {
116                 fprintf(stderr, "CDROMVOLCTRL ioctl failed\n");
117                 return;
118         }
119 #endif
120 }
121
122 void RBAPause()
123 {
124         if (!initialised) return;
125         SDL_CDPause(s_cd);
126 }
127
128 int RBAResume()
129 {
130         if (!initialised) return -1;
131         SDL_CDResume(s_cd);
132         return 1;
133 }
134
135 int RBAGetNumberOfTracks()
136 {
137         if (!initialised) return -1;
138         SDL_CDStatus(s_cd);
139         return s_cd->numtracks;
140 }
141
142 // plays tracks first through last, inclusive
143 int RBAPlayTracks(int first, int last)
144 {
145         if (!initialised)
146                 return 0;
147
148         if (CD_INDRIVE(SDL_CDStatus(s_cd)))
149         {
150                 SDL_CDPlayTracks(s_cd, first - 1, 0, last - first + 1, 0);
151         }
152         return 1;
153 }
154
155 // return the track number currently playing.  Useful if RBAPlayTracks()
156 // is called.  Returns 0 if no track playing, else track number
157 int RBAGetTrackNum()
158 {
159         if (!initialised)
160                 return 0;
161
162         if (SDL_CDStatus(s_cd) != CD_PLAYING)
163                 return 0;
164
165         return s_cd->cur_track + 1;
166 }
167
168 int RBAPeekPlayStatus()
169 {
170         return (SDL_CDStatus(s_cd) == CD_PLAYING);
171 }
172
173 int CD_blast_mixer()
174 {
175         return 0;
176 }
177
178
179 static int cddb_sum(int n)
180 {
181         int ret;
182
183         /* For backward compatibility this algorithm must not change */
184
185         ret = 0;
186
187         while (n > 0) {
188                 ret = ret + (n % 10);
189                 n = n / 10;
190         }
191
192         return (ret);
193 }
194
195
196 uint32_t RBAGetDiscID()
197 {
198         int i, t = 0, n = 0;
199
200         if (!initialised)
201                 return 0;
202
203         /* For backward compatibility this algorithm must not change */
204
205         i = 0;
206
207         while (i < s_cd->numtracks) {
208                 n += cddb_sum(s_cd->track[i].offset / CD_FPS);
209                 i++;
210         }
211
212         t = (s_cd->track[s_cd->numtracks].offset / CD_FPS) -
213             (s_cd->track[0].offset / CD_FPS);
214
215         return ((n % 0xff) << 24 | t << 8 | s_cd->numtracks);
216 }