Mercurial > sdl-ios-xcode
annotate src/cdrom/mint/SDL_syscdrom.c @ 1748:5e86e34453d4
------- Comment #1 From Max Horn 2006-04-17 03:08 [reply] -------
Created an attachment (id=106) [edit]
Patch for src/joystick/win32/SDL_mmjoystick.c
I am not even a Windows user, so take the following with a grain of salt:
SDL_mmjoystick.c has a function GetJoystickName which obtains the joystick
name by looking at the registry. The way it does that seems very fishy to me.
Namely, it uses the parameter "index" to construct a registry value name (BTW,
those variables used in the code are really badly named). The value of "index"
in turn equals the current value of "numdevs", as called from
SDL_SYS_JoystickInit.
I read through the MSDN docs at
<http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnarinput/html/msdn_extdirect.asp>,
and I believe the simple fix is to replace line 183 of said file
SYS_JoystickName[numdevs] = GetJoystickName(numdevs, joycaps.szRegKey);
by the following:
SYS_JoystickName[numdevs] = GetJoystickName(SYS_JoystickID[i],
joycaps.szRegKey);
However, that is only *hiding* the real issue. Problem is, the list of
joysticks as returned by windows may contains "gaps", and the code deals
incorrectly with that. Namely those gaps occur if joysticks are
removed/(re)added, as the reporter observed.
The attached patch fixes this and another (off-by-one) issue in the code. But
since I have no Windows machine, I can't even test-compile it, so use with
caution.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 29 Apr 2006 20:22:31 +0000 |
parents | 92947e3a18db |
children | 782fd950bd46 c121d94672cb a1b03ba2fcd0 |
rev | line source |
---|---|
724 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
727
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
724 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
22 #include "SDL_config.h" |
724 | 23 |
1635
92947e3a18db
Make sure code is only compiled if the appropriate subsystem is enabled
Sam Lantinga <slouken@libsdl.org>
parents:
1402
diff
changeset
|
24 #ifdef SDL_CDROM_MINT |
92947e3a18db
Make sure code is only compiled if the appropriate subsystem is enabled
Sam Lantinga <slouken@libsdl.org>
parents:
1402
diff
changeset
|
25 |
724 | 26 /* |
27 Atari MetaDOS CD-ROM functions | |
28 | |
29 Patrice Mandin | |
30 */ | |
31 | |
32 #include <errno.h> | |
33 | |
34 #include <cdromio.h> | |
35 #include <metados.h> | |
36 | |
37 #include "SDL_cdrom.h" | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
38 #include "../SDL_syscdrom.h" |
724 | 39 |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
40 /* Some ioctl() errno values which occur when the tray is empty */ |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
41 #ifndef ENOMEDIUM |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
42 #define ENOMEDIUM ENOENT |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
43 #endif |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
44 #define ERRNO_TRAYEMPTY(errno) \ |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
45 ((errno == EIO) || (errno == ENOENT) || \ |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
46 (errno == EINVAL) || (errno == ENOMEDIUM)) |
724 | 47 |
48 /* The maximum number of CD-ROM drives we'll detect */ | |
49 #define MAX_DRIVES 32 | |
50 | |
51 typedef struct { | |
52 unsigned char device[3]; /* Physical device letter + ':' + '\0' */ | |
53 metaopen_t metaopen; /* Infos on opened drive */ | |
54 } metados_drive_t; | |
55 | |
56 static metados_drive_t metados_drives[MAX_DRIVES]; | |
57 | |
58 /* The system-dependent CD control functions */ | |
59 static const char *SDL_SYS_CDName(int drive); | |
60 static int SDL_SYS_CDOpen(int drive); | |
61 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
62 static int SDL_SYS_CDioctl(int id, int command, void *arg); | |
63 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
64 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
65 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
66 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
67 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
68 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
69 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
70 | |
71 int SDL_SYS_CDInit(void) | |
72 { | |
73 metainit_t metainit={0,0,0,0}; | |
74 metaopen_t metaopen; | |
75 int i, handle; | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
76 struct cdrom_subchnl info; |
724 | 77 |
78 Metainit(&metainit); | |
79 if (metainit.version == NULL) { | |
80 #ifdef DEBUG_CDROM | |
81 fprintf(stderr, "MetaDOS not installed\n"); | |
82 #endif | |
83 return -1; | |
84 } | |
85 | |
86 if (metainit.drives_map == 0) { | |
87 #ifdef DEBUG_CDROM | |
88 fprintf(stderr, "No MetaDOS devices present\n"); | |
89 #endif | |
90 return -1; | |
91 } | |
92 | |
93 SDL_numcds = 0; | |
94 | |
95 for (i='A'; i<='Z'; i++) { | |
96 metados_drives[SDL_numcds].device[0] = 0; | |
97 metados_drives[SDL_numcds].device[1] = ':'; | |
98 metados_drives[SDL_numcds].device[2] = 0; | |
99 | |
100 if (metainit.drives_map & (1<<(i-'A'))) { | |
101 handle = Metaopen(i, &metaopen); | |
102 if (handle == 0) { | |
103 | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
104 info.cdsc_format = CDROM_MSF; |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
105 if ( (Metaioctl(i, METADOS_IOCTL_MAGIC, CDROMSUBCHNL, &info) == 0) || ERRNO_TRAYEMPTY(errno) ) { |
724 | 106 metados_drives[SDL_numcds].device[0] = i; |
107 ++SDL_numcds; | |
108 } | |
109 | |
110 Metaclose(i); | |
111 } | |
112 } | |
113 } | |
114 | |
115 /* Fill in our driver capabilities */ | |
116 SDL_CDcaps.Name = SDL_SYS_CDName; | |
117 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
118 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
119 | |
120 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
121 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
122 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
123 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
124 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
125 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
126 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
127 | |
128 return 0; | |
129 } | |
130 | |
131 void SDL_SYS_CDQuit(void) | |
132 { | |
133 SDL_numcds = 0; | |
134 } | |
135 | |
136 static const char *SDL_SYS_CDName(int drive) | |
137 { | |
138 return(metados_drives[drive].device); | |
139 } | |
140 | |
141 static int SDL_SYS_CDOpen(int drive) | |
142 { | |
143 int handle; | |
144 | |
145 handle = Metaopen(metados_drives[drive].device[0], &(metados_drives[drive].metaopen)); | |
146 if (handle == 0) { | |
147 return drive; | |
148 } | |
149 | |
150 return -1; | |
151 } | |
152 | |
153 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
154 { | |
155 Metaclose(metados_drives[cdrom->id].device[0]); | |
156 } | |
157 | |
158 static int SDL_SYS_CDioctl(int id, int command, void *arg) | |
159 { | |
160 int retval; | |
161 | |
162 retval = Metaioctl(metados_drives[id].device[0], METADOS_IOCTL_MAGIC, command, arg); | |
163 if ( retval < 0 ) { | |
164 SDL_SetError("ioctl() error: %s", strerror(errno)); | |
165 } | |
166 return(retval); | |
167 } | |
168 | |
169 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
170 { | |
171 int i,okay; | |
172 struct cdrom_tochdr toc; | |
173 struct cdrom_tocentry entry; | |
174 | |
175 /* Use standard ioctl() */ | |
176 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)<0) { | |
177 return -1; | |
178 } | |
179 | |
180 cdrom->numtracks = toc.cdth_trk1-toc.cdth_trk0+1; | |
181 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
182 cdrom->numtracks = SDL_MAX_TRACKS; | |
183 } | |
184 | |
185 /* Read all the track TOC entries */ | |
186 okay=1; | |
187 for ( i=0; i<=cdrom->numtracks; ++i ) { | |
188 if ( i == cdrom->numtracks ) { | |
189 cdrom->track[i].id = CDROM_LEADOUT; | |
190 } else { | |
191 cdrom->track[i].id = toc.cdth_trk0+i; | |
192 } | |
193 entry.cdte_track = cdrom->track[i].id; | |
194 entry.cdte_format = CDROM_MSF; | |
195 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, &entry) < 0 ) { | |
196 okay=0; | |
197 break; | |
198 } else { | |
199 if ( entry.cdte_ctrl & CDROM_DATA_TRACK ) { | |
200 cdrom->track[i].type = SDL_DATA_TRACK; | |
201 } else { | |
202 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
203 } | |
204 cdrom->track[i].offset = MSF_TO_FRAMES( | |
205 entry.cdte_addr.msf.minute, | |
206 entry.cdte_addr.msf.second, | |
207 entry.cdte_addr.msf.frame); | |
208 cdrom->track[i].length = 0; | |
209 if ( i > 0 ) { | |
210 cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset; | |
211 } | |
212 } | |
213 } | |
214 | |
215 return(okay ? 0 : -1); | |
216 } | |
217 | |
218 /* Get CD-ROM status */ | |
219 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
220 { | |
221 CDstatus status; | |
222 struct cdrom_tochdr toc; | |
223 struct cdrom_subchnl info; | |
224 | |
225 info.cdsc_format = CDROM_MSF; | |
226 if ( SDL_SYS_CDioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
227 if ( ERRNO_TRAYEMPTY(errno) ) { |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
228 status = CD_TRAYEMPTY; |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
229 } else { |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
230 status = CD_ERROR; |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
231 } |
724 | 232 } else { |
233 switch (info.cdsc_audiostatus) { | |
234 case CDROM_AUDIO_INVALID: | |
235 case CDROM_AUDIO_NO_STATUS: | |
236 /* Try to determine if there's a CD available */ | |
237 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)==0) { | |
238 status = CD_STOPPED; | |
239 } else { | |
240 status = CD_TRAYEMPTY; | |
241 } | |
242 break; | |
243 case CDROM_AUDIO_COMPLETED: | |
244 status = CD_STOPPED; | |
245 break; | |
246 case CDROM_AUDIO_PLAY: | |
247 status = CD_PLAYING; | |
248 break; | |
249 case CDROM_AUDIO_PAUSED: | |
250 /* Workaround buggy CD-ROM drive */ | |
251 if ( info.cdsc_trk == CDROM_LEADOUT ) { | |
252 status = CD_STOPPED; | |
253 } else { | |
254 status = CD_PAUSED; | |
255 } | |
256 break; | |
257 default: | |
258 status = CD_ERROR; | |
259 break; | |
260 } | |
261 } | |
262 if ( position ) { | |
263 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
264 *position = MSF_TO_FRAMES( | |
265 info.cdsc_absaddr.msf.minute, | |
266 info.cdsc_absaddr.msf.second, | |
267 info.cdsc_absaddr.msf.frame); | |
268 } else { | |
269 *position = 0; | |
270 } | |
271 } | |
272 return(status); | |
273 } | |
274 | |
275 /* Start play */ | |
276 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
277 { | |
278 struct cdrom_msf playtime; | |
279 | |
280 FRAMES_TO_MSF(start, | |
281 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); | |
282 FRAMES_TO_MSF(start+length, | |
283 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); | |
284 #ifdef DEBUG_CDROM | |
285 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | |
286 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, | |
287 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); | |
288 #endif | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
289 |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
290 return SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime); |
724 | 291 } |
292 | |
293 /* Pause play */ | |
294 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
295 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
296 return SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0); |
724 | 297 } |
298 | |
299 /* Resume play */ | |
300 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
301 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
302 return SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0); |
724 | 303 } |
304 | |
305 /* Stop play */ | |
306 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
307 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
308 return SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0); |
724 | 309 } |
310 | |
311 /* Eject the CD-ROM */ | |
312 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
313 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
314 return SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0); |
724 | 315 } |
1635
92947e3a18db
Make sure code is only compiled if the appropriate subsystem is enabled
Sam Lantinga <slouken@libsdl.org>
parents:
1402
diff
changeset
|
316 |
92947e3a18db
Make sure code is only compiled if the appropriate subsystem is enabled
Sam Lantinga <slouken@libsdl.org>
parents:
1402
diff
changeset
|
317 #endif /* SDL_CDROM_MINT */ |