Mercurial > sdl-ios-xcode
annotate src/cdrom/mint/SDL_syscdrom.c @ 1554:0ca607a5d173
Fixed bug #84
Date: Sun, 23 Oct 2005 16:39:03 +0200
From: "A. Schmid" <sahib@phreaker.net>
Subject: [SDL] no software surfaces with svgalib driver?
Hi,
I noticed that the SDL (1.2.9) svgalib driver only makes use of linear
addressable (framebuffer) video modes. On older systems (like one of
mine), linear addressable modes are often not available.
Especially for cards with VESA VBE < 2.0 the svgalib vesa driver is
unusable, since VESA only supports framebuffering for VBE 2.0 and later.
The changes necessary to add support for software surfaces seem to be
relatively small. I only had to hack src/video/svga/SDL_svgavideo.c (see
attached patch). The code worked fine for me, but it is no more than a
proof of concept and should be reviewed (probably has a memory leak when
switching modes). It also uses the vgagl library (included in the
svgalib package) and needs to be linked against it.
-Alex
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 19 Mar 2006 12:04:40 +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 } |