Mercurial > sdl-ios-xcode
annotate src/cdrom/mint/SDL_syscdrom.c @ 1551:02e19471a694
Fixed bug #4
[Note: I'm applying this patch since it's a cleaner version of what's already implemented, and supports this controller on older kernels. I'll ask to make sure this doesn't break on the new kernels where it's no longer necessary]
Date: Mon, 21 Mar 2005 09:41:11 -0500
From: Chris Nelson
Subject: SDL Patch
Hey, Ryan.
I submitted the following patch about a year ago. It's just a simple
patch for the linux port, to make multiple joysticks each appear to SDL
as their own device, if they are on the same USB port (specifically,
these guys
<http://www.consoleplus.co.uk/product_info.php?pName=super-joybox-5-quad-joypad-converter>,
which allow 4 Playstation2 controllers to be accessed via a single USB
port). Without this patch, SDL pretty much drops the ball, and reports
that there are 4 joysticks available when less than that number are
plugged in.
My work built upon the work of another person with the same device. When
I submitted the patch to the list, he tested it, but it didn't work for
him, so the patch was never accepted. Maybe about 3 times in the past
year, I've tried to email the guy, to see if he couldn't run my new
version, complete with debug code to diagnose the problem he was having.
He never got back to me.
So, I'm attaching the patch. I wish I knew why it didn't work for him,
but I've been using it for the last year with no problems. Let me know
if you need any more information, or have any ideas as to how I could
test it. I'd like to see it in the tree, but I want to make sure it works.
-Chris
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 19 Mar 2006 06:31:34 +0000 |
parents | d910939febfa |
children | 92947e3a18db |
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 |
24 /* | |
25 Atari MetaDOS CD-ROM functions | |
26 | |
27 Patrice Mandin | |
28 */ | |
29 | |
30 #include <errno.h> | |
31 | |
32 #include <cdromio.h> | |
33 #include <metados.h> | |
34 | |
35 #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
|
36 #include "../SDL_syscdrom.h" |
724 | 37 |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
38 /* 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
|
39 #ifndef ENOMEDIUM |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
40 #define ENOMEDIUM ENOENT |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
41 #endif |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
42 #define ERRNO_TRAYEMPTY(errno) \ |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
43 ((errno == EIO) || (errno == ENOENT) || \ |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
44 (errno == EINVAL) || (errno == ENOMEDIUM)) |
724 | 45 |
46 /* The maximum number of CD-ROM drives we'll detect */ | |
47 #define MAX_DRIVES 32 | |
48 | |
49 typedef struct { | |
50 unsigned char device[3]; /* Physical device letter + ':' + '\0' */ | |
51 metaopen_t metaopen; /* Infos on opened drive */ | |
52 } metados_drive_t; | |
53 | |
54 static metados_drive_t metados_drives[MAX_DRIVES]; | |
55 | |
56 /* The system-dependent CD control functions */ | |
57 static const char *SDL_SYS_CDName(int drive); | |
58 static int SDL_SYS_CDOpen(int drive); | |
59 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
60 static int SDL_SYS_CDioctl(int id, int command, void *arg); | |
61 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
62 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
63 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
64 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
65 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
66 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
67 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
68 | |
69 int SDL_SYS_CDInit(void) | |
70 { | |
71 metainit_t metainit={0,0,0,0}; | |
72 metaopen_t metaopen; | |
73 int i, handle; | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
74 struct cdrom_subchnl info; |
724 | 75 |
76 Metainit(&metainit); | |
77 if (metainit.version == NULL) { | |
78 #ifdef DEBUG_CDROM | |
79 fprintf(stderr, "MetaDOS not installed\n"); | |
80 #endif | |
81 return -1; | |
82 } | |
83 | |
84 if (metainit.drives_map == 0) { | |
85 #ifdef DEBUG_CDROM | |
86 fprintf(stderr, "No MetaDOS devices present\n"); | |
87 #endif | |
88 return -1; | |
89 } | |
90 | |
91 SDL_numcds = 0; | |
92 | |
93 for (i='A'; i<='Z'; i++) { | |
94 metados_drives[SDL_numcds].device[0] = 0; | |
95 metados_drives[SDL_numcds].device[1] = ':'; | |
96 metados_drives[SDL_numcds].device[2] = 0; | |
97 | |
98 if (metainit.drives_map & (1<<(i-'A'))) { | |
99 handle = Metaopen(i, &metaopen); | |
100 if (handle == 0) { | |
101 | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
102 info.cdsc_format = CDROM_MSF; |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
103 if ( (Metaioctl(i, METADOS_IOCTL_MAGIC, CDROMSUBCHNL, &info) == 0) || ERRNO_TRAYEMPTY(errno) ) { |
724 | 104 metados_drives[SDL_numcds].device[0] = i; |
105 ++SDL_numcds; | |
106 } | |
107 | |
108 Metaclose(i); | |
109 } | |
110 } | |
111 } | |
112 | |
113 /* Fill in our driver capabilities */ | |
114 SDL_CDcaps.Name = SDL_SYS_CDName; | |
115 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
116 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
117 | |
118 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
119 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
120 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
121 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
122 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
123 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
124 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
125 | |
126 return 0; | |
127 } | |
128 | |
129 void SDL_SYS_CDQuit(void) | |
130 { | |
131 SDL_numcds = 0; | |
132 } | |
133 | |
134 static const char *SDL_SYS_CDName(int drive) | |
135 { | |
136 return(metados_drives[drive].device); | |
137 } | |
138 | |
139 static int SDL_SYS_CDOpen(int drive) | |
140 { | |
141 int handle; | |
142 | |
143 handle = Metaopen(metados_drives[drive].device[0], &(metados_drives[drive].metaopen)); | |
144 if (handle == 0) { | |
145 return drive; | |
146 } | |
147 | |
148 return -1; | |
149 } | |
150 | |
151 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
152 { | |
153 Metaclose(metados_drives[cdrom->id].device[0]); | |
154 } | |
155 | |
156 static int SDL_SYS_CDioctl(int id, int command, void *arg) | |
157 { | |
158 int retval; | |
159 | |
160 retval = Metaioctl(metados_drives[id].device[0], METADOS_IOCTL_MAGIC, command, arg); | |
161 if ( retval < 0 ) { | |
162 SDL_SetError("ioctl() error: %s", strerror(errno)); | |
163 } | |
164 return(retval); | |
165 } | |
166 | |
167 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
168 { | |
169 int i,okay; | |
170 struct cdrom_tochdr toc; | |
171 struct cdrom_tocentry entry; | |
172 | |
173 /* Use standard ioctl() */ | |
174 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)<0) { | |
175 return -1; | |
176 } | |
177 | |
178 cdrom->numtracks = toc.cdth_trk1-toc.cdth_trk0+1; | |
179 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
180 cdrom->numtracks = SDL_MAX_TRACKS; | |
181 } | |
182 | |
183 /* Read all the track TOC entries */ | |
184 okay=1; | |
185 for ( i=0; i<=cdrom->numtracks; ++i ) { | |
186 if ( i == cdrom->numtracks ) { | |
187 cdrom->track[i].id = CDROM_LEADOUT; | |
188 } else { | |
189 cdrom->track[i].id = toc.cdth_trk0+i; | |
190 } | |
191 entry.cdte_track = cdrom->track[i].id; | |
192 entry.cdte_format = CDROM_MSF; | |
193 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, &entry) < 0 ) { | |
194 okay=0; | |
195 break; | |
196 } else { | |
197 if ( entry.cdte_ctrl & CDROM_DATA_TRACK ) { | |
198 cdrom->track[i].type = SDL_DATA_TRACK; | |
199 } else { | |
200 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
201 } | |
202 cdrom->track[i].offset = MSF_TO_FRAMES( | |
203 entry.cdte_addr.msf.minute, | |
204 entry.cdte_addr.msf.second, | |
205 entry.cdte_addr.msf.frame); | |
206 cdrom->track[i].length = 0; | |
207 if ( i > 0 ) { | |
208 cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset; | |
209 } | |
210 } | |
211 } | |
212 | |
213 return(okay ? 0 : -1); | |
214 } | |
215 | |
216 /* Get CD-ROM status */ | |
217 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
218 { | |
219 CDstatus status; | |
220 struct cdrom_tochdr toc; | |
221 struct cdrom_subchnl info; | |
222 | |
223 info.cdsc_format = CDROM_MSF; | |
224 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
|
225 if ( ERRNO_TRAYEMPTY(errno) ) { |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
226 status = CD_TRAYEMPTY; |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
227 } else { |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
228 status = CD_ERROR; |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
229 } |
724 | 230 } else { |
231 switch (info.cdsc_audiostatus) { | |
232 case CDROM_AUDIO_INVALID: | |
233 case CDROM_AUDIO_NO_STATUS: | |
234 /* Try to determine if there's a CD available */ | |
235 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)==0) { | |
236 status = CD_STOPPED; | |
237 } else { | |
238 status = CD_TRAYEMPTY; | |
239 } | |
240 break; | |
241 case CDROM_AUDIO_COMPLETED: | |
242 status = CD_STOPPED; | |
243 break; | |
244 case CDROM_AUDIO_PLAY: | |
245 status = CD_PLAYING; | |
246 break; | |
247 case CDROM_AUDIO_PAUSED: | |
248 /* Workaround buggy CD-ROM drive */ | |
249 if ( info.cdsc_trk == CDROM_LEADOUT ) { | |
250 status = CD_STOPPED; | |
251 } else { | |
252 status = CD_PAUSED; | |
253 } | |
254 break; | |
255 default: | |
256 status = CD_ERROR; | |
257 break; | |
258 } | |
259 } | |
260 if ( position ) { | |
261 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
262 *position = MSF_TO_FRAMES( | |
263 info.cdsc_absaddr.msf.minute, | |
264 info.cdsc_absaddr.msf.second, | |
265 info.cdsc_absaddr.msf.frame); | |
266 } else { | |
267 *position = 0; | |
268 } | |
269 } | |
270 return(status); | |
271 } | |
272 | |
273 /* Start play */ | |
274 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
275 { | |
276 struct cdrom_msf playtime; | |
277 | |
278 FRAMES_TO_MSF(start, | |
279 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); | |
280 FRAMES_TO_MSF(start+length, | |
281 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); | |
282 #ifdef DEBUG_CDROM | |
283 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | |
284 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, | |
285 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); | |
286 #endif | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
287 |
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
288 return SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime); |
724 | 289 } |
290 | |
291 /* Pause play */ | |
292 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
293 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
294 return SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0); |
724 | 295 } |
296 | |
297 /* Resume play */ | |
298 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
299 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
300 return SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0); |
724 | 301 } |
302 | |
303 /* Stop play */ | |
304 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
305 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
306 return SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0); |
724 | 307 } |
308 | |
309 /* Eject the CD-ROM */ | |
310 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
311 { | |
727
cb1208fcd946
Update MiNT CD-ROM driver
Patrice Mandin <patmandin@gmail.com>
parents:
724
diff
changeset
|
312 return SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0); |
724 | 313 } |