amd64 fixes
[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         atexit(RBAExit);
62         initialised = 1;
63 }
64
65 int RBAEnabled()
66 {
67         return 1;
68 }
69
70 void RBARegisterCD()
71 {
72
73 }
74
75 int RBAPlayTrack(int a)
76 {
77         if (!initialised) return -1;
78
79         if (CD_INDRIVE(SDL_CDStatus(s_cd)) ) {
80                 SDL_CDPlayTracks(s_cd, a-1, 0, 0, 0);
81         }
82         return a;
83 }
84
85 void RBAStop()
86 {
87         if (!initialised) return;
88         SDL_CDStop(s_cd);
89 }
90
91 void RBASetVolume(int volume)
92 {
93 #ifdef __linux__
94         int cdfile, level;
95         struct cdrom_volctrl volctrl;
96
97         if (!initialised) return;
98
99         cdfile = s_cd->id;
100         level = volume * 3;
101
102         if ((level<0) || (level>255)) {
103                 fprintf(stderr, "illegal volume value (allowed values 0-255)\n");
104                 return;
105         }
106
107         volctrl.channel0
108                 = volctrl.channel1
109                 = volctrl.channel2
110                 = volctrl.channel3
111                 = level;
112         if ( ioctl(cdfile, CDROMVOLCTRL, &volctrl) == -1 ) {
113                 fprintf(stderr, "CDROMVOLCTRL ioctl failed\n");
114                 return;
115         }
116 #endif
117 }
118
119 void RBAPause()
120 {
121         if (!initialised) return;
122         SDL_CDPause(s_cd);
123 }
124
125 int RBAResume()
126 {
127         if (!initialised) return -1;
128         SDL_CDResume(s_cd);
129         return 1;
130 }
131
132 int RBAGetNumberOfTracks()
133 {
134         if (!initialised) return -1;
135         SDL_CDStatus(s_cd);
136         return s_cd->numtracks;
137 }
138
139 // plays tracks first through last, inclusive
140 int RBAPlayTracks(int first, int last)
141 {
142         if (!initialised)
143                 return 0;
144
145         if (CD_INDRIVE(SDL_CDStatus(s_cd)))
146         {
147                 SDL_CDPlayTracks(s_cd, first - 1, 0, last - first + 1, 0);
148         }
149         return 1;
150 }
151
152 // return the track number currently playing.  Useful if RBAPlayTracks()
153 // is called.  Returns 0 if no track playing, else track number
154 int RBAGetTrackNum()
155 {
156         if (!initialised)
157                 return 0;
158
159         if (SDL_CDStatus(s_cd) != CD_PLAYING)
160                 return 0;
161
162         return s_cd->cur_track + 1;
163 }
164
165 int RBAPeekPlayStatus()
166 {
167         return (SDL_CDStatus(s_cd) == CD_PLAYING);
168 }
169
170 int CD_blast_mixer()
171 {
172         return 0;
173 }
174
175
176 static int cddb_sum(int n)
177 {
178         int ret;
179
180         /* For backward compatibility this algorithm must not change */
181
182         ret = 0;
183
184         while (n > 0) {
185                 ret = ret + (n % 10);
186                 n = n / 10;
187         }
188
189         return (ret);
190 }
191
192
193 unsigned long RBAGetDiscID()
194 {
195         int i, t = 0, n = 0;
196
197         if (!initialised)
198                 return 0;
199
200         /* For backward compatibility this algorithm must not change */
201
202         i = 0;
203
204         while (i < s_cd->numtracks) {
205                 n += cddb_sum(s_cd->track[i].offset / CD_FPS);
206                 i++;
207         }
208
209         t = (s_cd->track[s_cd->numtracks].offset / CD_FPS) -
210             (s_cd->track[0].offset / CD_FPS);
211
212         return ((n % 0xff) << 24 | t << 8 | s_cd->numtracks);
213 }