Mercurial > sdl-ios-xcode
comparison src/cdrom/os2/SDL_syscdrom.c @ 1190:173c063d4f55
OS/2 port!
This was mostly, if not entirely, written by "Doodle" and "Caetano":
doodle@scenergy.dfmk.hu
daniel@caetano.eng.br
--ryan.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Wed, 23 Nov 2005 07:29:56 +0000 |
parents | |
children | c9b51268668f |
comparison
equal
deleted
inserted
replaced
1189:c96b326b90ba | 1190:173c063d4f55 |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997-2004 Sam Lantinga | |
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 */ | |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Functions for system-level CD-ROM audio control */ | |
29 | |
30 #define INCL_MCIOS2 | |
31 #include <os2.h> | |
32 #include <os2me.h> | |
33 #include <stdio.h> | |
34 #include <stdlib.h> | |
35 #include <string.h> | |
36 | |
37 #include "SDL_error.h" | |
38 #include "SDL_cdrom.h" | |
39 #include "SDL_syscdrom.h" | |
40 | |
41 /* Size of MCI result buffer (in bytes) */ | |
42 #define MCI_CMDRETBUFSIZE 128 | |
43 | |
44 /* The maximum number of CD-ROM drives we'll detect */ | |
45 #define MAX_DRIVES 16 | |
46 | |
47 /* A list of available CD-ROM drives */ | |
48 static char *SDL_cdlist[MAX_DRIVES]; | |
49 //static dev_t SDL_cdmode[MAX_DRIVES]; | |
50 | |
51 /* The system-dependent CD control functions */ | |
52 static const char *SDL_SYS_CDName(int drive); | |
53 static int SDL_SYS_CDOpen(int drive); | |
54 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
55 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
56 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
57 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
58 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
59 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
60 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
61 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
62 | |
63 /* MCI Timing Functions */ | |
64 #define MCI_MMTIMEPERSECOND 3000 | |
65 #define FRAMESFROMMM(mmtime) (((mmtime)*CD_FPS)/MCI_MMTIMEPERSECOND) | |
66 | |
67 | |
68 /* Ready for MCI CDAudio Devices */ | |
69 int SDL_SYS_CDInit(void) | |
70 { | |
71 int i; /* generig counter */ | |
72 MCI_SYSINFO_PARMS msp; /* Structure to MCI SysInfo parameters */ | |
73 CHAR SysInfoRet[MCI_CMDRETBUFSIZE]; /* Buffer for MCI Command result */ | |
74 | |
75 /* Fill in our driver capabilities */ | |
76 SDL_CDcaps.Name = SDL_SYS_CDName; | |
77 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
78 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
79 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
80 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
81 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
82 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
83 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
84 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
85 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
86 | |
87 /* Get the number of CD ROMs in the System */ | |
88 /* Clean SysInfo structure */ | |
89 memset(&msp, 0x00, sizeof(MCI_SYSINFO_PARMS)); | |
90 /* Prepare structure to Ask Numer of Audio CDs */ | |
91 msp.usDeviceType = MCI_DEVTYPE_CD_AUDIO; /* CD Audio Type */ | |
92 msp.pszReturn = (PSZ)&SysInfoRet; /* Return Structure */ | |
93 msp.ulRetSize = MCI_CMDRETBUFSIZE; /* Size of ret struct */ | |
94 if (LOUSHORT(mciSendCommand(0,MCI_SYSINFO, MCI_SYSINFO_QUANTITY | MCI_WAIT, (PVOID)&msp, 0)) != MCIERR_SUCCESS) return(CD_ERROR); | |
95 SDL_numcds = atoi(SysInfoRet); | |
96 if (SDL_numcds > MAX_DRIVES) SDL_numcds = MAX_DRIVES; /* Limit maximum CD number */ | |
97 | |
98 /* Get and Add their system name to the SDL_cdlist */ | |
99 msp.pszReturn = (PSZ)&SysInfoRet; /* Return Structure */ | |
100 msp.ulRetSize = MCI_CMDRETBUFSIZE; /* Size of ret struct */ | |
101 msp.usDeviceType = MCI_DEVTYPE_CD_AUDIO; /* CD Audio Type */ | |
102 for (i=0; i<SDL_numcds; i++) | |
103 { | |
104 msp.ulNumber = i+1; | |
105 mciSendCommand(0,MCI_SYSINFO, MCI_SYSINFO_NAME | MCI_WAIT,&msp, 0); | |
106 SDL_cdlist[i] = (char *)malloc(strlen(SysInfoRet)+1); | |
107 if ( SDL_cdlist[i] == NULL ) | |
108 { | |
109 SDL_OutOfMemory(); | |
110 return(-1); | |
111 } | |
112 strcpy(SDL_cdlist[i], SysInfoRet); | |
113 } | |
114 return(0); | |
115 } | |
116 | |
117 /* Return CDAudio System Dependent Device Name - Ready for MCI*/ | |
118 static const char *SDL_SYS_CDName(int drive) | |
119 { | |
120 return(SDL_cdlist[drive]); | |
121 } | |
122 | |
123 /* Open CDAudio Device - Ready for MCI */ | |
124 static int SDL_SYS_CDOpen(int drive) | |
125 { | |
126 MCI_OPEN_PARMS mop; | |
127 MCI_SET_PARMS msp; | |
128 MCI_GENERIC_PARMS mgp; | |
129 | |
130 /* Open the device */ | |
131 mop.hwndCallback = (HWND)NULL; // None | |
132 mop.usDeviceID = (USHORT)NULL; // Will be returned. | |
133 mop.pszDeviceType = (PSZ)SDL_cdlist[drive]; // CDAudio Device | |
134 if (LOUSHORT(mciSendCommand(0,MCI_OPEN,MCI_WAIT,&mop, 0)) != MCIERR_SUCCESS) return(CD_ERROR); | |
135 /* Set time format */ | |
136 msp.hwndCallback = (HWND)NULL; // None | |
137 msp.ulTimeFormat = MCI_FORMAT_MSF; // Minute : Second : Frame structure | |
138 msp.ulSpeedFormat = (ULONG)NULL; // No change | |
139 msp.ulAudio = (ULONG)NULL; // No Channel | |
140 msp.ulLevel = (ULONG)NULL; // No Volume | |
141 msp.ulOver = (ULONG)NULL; // No Delay | |
142 msp.ulItem = (ULONG)NULL; // No item | |
143 msp.ulValue = (ULONG)NULL; // No value for item flag | |
144 if (LOUSHORT(mciSendCommand(mop.usDeviceID,MCI_SET,MCI_WAIT | MCI_SET_TIME_FORMAT,&msp, 0)) == MCIERR_SUCCESS) return (mop.usDeviceID); | |
145 /* Error setting time format? - Close opened device */ | |
146 mgp.hwndCallback = (HWND)NULL; // None | |
147 mciSendCommand(mop.usDeviceID,MCI_CLOSE,MCI_WAIT,&mgp, 0); | |
148 return(CD_ERROR); | |
149 } | |
150 | |
151 /* Get CD Table Of Contents - Ready for MCI */ | |
152 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
153 { | |
154 MCI_TOC_PARMS mtp; | |
155 MCI_STATUS_PARMS msp; | |
156 MCI_TOC_REC * mtr; | |
157 INT i; | |
158 | |
159 /* Correction because MCI cannot read TOC while CD is playing (it'll stop!) */ | |
160 if (cdrom->status == CD_PLAYING || cdrom->status == CD_PAUSED) return 0; | |
161 | |
162 /* Get Number of Tracks */ | |
163 msp.hwndCallback = (HWND)NULL; /* None */ | |
164 msp.ulReturn = (ULONG)NULL; /* We want this information */ | |
165 msp.ulItem = MCI_STATUS_NUMBER_OF_TRACKS; | |
166 msp.ulValue = (ULONG)NULL; /* No additional information */ | |
167 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,&msp, 0)) != MCIERR_SUCCESS) return(CD_ERROR); | |
168 cdrom->numtracks = msp.ulReturn; | |
169 if ( cdrom->numtracks > SDL_MAX_TRACKS ) | |
170 { | |
171 cdrom->numtracks = SDL_MAX_TRACKS; | |
172 } | |
173 /* Alocate space for TOC data */ | |
174 mtr = (MCI_TOC_REC *)malloc(cdrom->numtracks*sizeof(MCI_TOC_REC)); | |
175 if ( mtr == NULL ) | |
176 { | |
177 SDL_OutOfMemory(); | |
178 return(-1); | |
179 } | |
180 /* Get TOC from CD */ | |
181 mtp.pBuf = mtr; | |
182 mtp.ulBufSize = cdrom->numtracks*sizeof(MCI_TOC_REC); | |
183 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_GETTOC,MCI_WAIT,&mtp, 0)) != MCIERR_SUCCESS) | |
184 { | |
185 SDL_OutOfMemory(); | |
186 free(mtr); | |
187 return(CD_ERROR); | |
188 } | |
189 /* Fill SDL Tracks Structure */ | |
190 for (i=0; i<cdrom->numtracks; i++) | |
191 { | |
192 /* Set Track ID */ | |
193 cdrom->track[i].id = (mtr+i)->TrackNum; | |
194 /* Set Track Type */ | |
195 msp.hwndCallback = (HWND)NULL; /* None */ | |
196 msp.ulReturn = (ULONG)NULL; /* We want this information */ | |
197 msp.ulItem = MCI_CD_STATUS_TRACK_TYPE; | |
198 msp.ulValue = (ULONG)((mtr+i)->TrackNum); /* Track Number? */ | |
199 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_TRACK | MCI_STATUS_ITEM,&msp, 0)) != MCIERR_SUCCESS) | |
200 { | |
201 free(mtr); | |
202 return (CD_ERROR); | |
203 } | |
204 if (msp.ulReturn==MCI_CD_TRACK_AUDIO) cdrom->track[i].type = SDL_AUDIO_TRACK; | |
205 else cdrom->track[i].type = SDL_DATA_TRACK; | |
206 /* Set Track Length - values from MCI are in MMTIMEs - 3000 MMTIME = 1 second */ | |
207 cdrom->track[i].length = FRAMESFROMMM((mtr+i)->ulEndAddr - (mtr+i)->ulStartAddr); | |
208 /* Set Track Offset */ | |
209 cdrom->track[i].offset = FRAMESFROMMM((mtr+i)->ulStartAddr); | |
210 } | |
211 free(mtr); | |
212 return(0); | |
213 } | |
214 | |
215 | |
216 /* Get CD-ROM status - Ready for MCI */ | |
217 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
218 { | |
219 CDstatus status; | |
220 MCI_STATUS_PARMS msp; | |
221 | |
222 /* Get Status from MCI */ | |
223 msp.hwndCallback = (HWND)NULL; /* None */ | |
224 msp.ulReturn = (ULONG)NULL; /* We want this information */ | |
225 msp.ulItem = MCI_STATUS_MODE; | |
226 msp.ulValue = (ULONG)NULL; /* No additional information */ | |
227 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,&msp, 0)) != MCIERR_SUCCESS) status = CD_ERROR; | |
228 else | |
229 { | |
230 switch(msp.ulReturn) | |
231 { | |
232 case MCI_MODE_NOT_READY: | |
233 status = CD_TRAYEMPTY; | |
234 break; | |
235 case MCI_MODE_PAUSE: | |
236 status = CD_PAUSED; | |
237 break; | |
238 case MCI_MODE_PLAY: | |
239 status = CD_PLAYING; | |
240 break; | |
241 case MCI_MODE_STOP: | |
242 status = CD_STOPPED; | |
243 break; | |
244 /* These cases should not occour */ | |
245 case MCI_MODE_RECORD: | |
246 case MCI_MODE_SEEK: | |
247 default: | |
248 status = CD_ERROR; | |
249 break; | |
250 } | |
251 } | |
252 | |
253 /* Determine position */ | |
254 if (position != NULL) /* The SDL $&$&%# CDROM call sends NULL pointer here! */ | |
255 { | |
256 if ((status == CD_PLAYING) || (status == CD_PAUSED)) | |
257 { | |
258 /* Get Position */ | |
259 msp.hwndCallback = (HWND)NULL; /* None */ | |
260 msp.ulReturn = (ULONG)NULL; /* We want this information */ | |
261 msp.ulItem = MCI_STATUS_POSITION; | |
262 msp.ulValue = (ULONG)NULL; /* No additiona info */ | |
263 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,&msp, 0)) != MCIERR_SUCCESS) return (CD_ERROR); | |
264 /* Convert from MSF (format selected in the Open process) to Frames (format that will be returned) */ | |
265 *position = MSF_TO_FRAMES(MSF_MINUTE(msp.ulReturn),MSF_SECOND(msp.ulReturn),MSF_FRAME(msp.ulReturn)); | |
266 } | |
267 else *position = 0; | |
268 } | |
269 return(status); | |
270 } | |
271 | |
272 /* Start play - Ready for MCI */ | |
273 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
274 { | |
275 MCI_GENERIC_PARMS mgp; | |
276 MCI_STATUS_PARMS msp; | |
277 MCI_PLAY_PARMS mpp; | |
278 ULONG min,sec,frm; | |
279 | |
280 /* Start MSF */ | |
281 FRAMES_TO_MSF(start, &min, &sec, &frm); | |
282 MSF_MINUTE(mpp.ulFrom) = min; | |
283 MSF_SECOND(mpp.ulFrom) = sec; | |
284 MSF_FRAME(mpp.ulFrom) = frm; | |
285 /* End MSF */ | |
286 FRAMES_TO_MSF(start+length, &min, &sec, &frm); | |
287 MSF_MINUTE(mpp.ulTo) = min; | |
288 MSF_SECOND(mpp.ulTo) = sec; | |
289 MSF_FRAME(mpp.ulTo) = frm; | |
290 #ifdef DEBUG_CDROM | |
291 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | |
292 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, | |
293 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); | |
294 #endif | |
295 /* Verifies if it is paused first... and if it is, unpause before stopping it. */ | |
296 msp.hwndCallback = (HWND)NULL; /* None */ | |
297 msp.ulReturn = (ULONG)NULL; /* We want this information */ | |
298 msp.ulItem = MCI_STATUS_MODE; | |
299 msp.ulValue = (ULONG)NULL; /* No additional information */ | |
300 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,&msp, 0)) == MCIERR_SUCCESS) | |
301 { | |
302 if (msp.ulReturn == MCI_MODE_PAUSE) | |
303 { | |
304 mgp.hwndCallback = (HWND)NULL; // None | |
305 mciSendCommand(cdrom->id,MCI_RESUME,NULL,&mgp, 0); | |
306 } | |
307 } | |
308 /* Now play it. */ | |
309 mpp.hwndCallback = (HWND)NULL; // We do not want the info. temp | |
310 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_PLAY,MCI_FROM | MCI_TO,&mpp, 0)) == MCIERR_SUCCESS) return 0; | |
311 return (CD_ERROR); | |
312 } | |
313 | |
314 /* Pause play - Ready for MCI */ | |
315 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
316 { | |
317 MCI_GENERIC_PARMS mgp; | |
318 | |
319 mgp.hwndCallback = (HWND)NULL; // None | |
320 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_PAUSE,MCI_WAIT,&mgp, 0)) == MCIERR_SUCCESS) return 0; | |
321 return(CD_ERROR); | |
322 } | |
323 | |
324 /* Resume play - Ready for MCI */ | |
325 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
326 { | |
327 MCI_GENERIC_PARMS mgp; | |
328 | |
329 mgp.hwndCallback = (HWND)NULL; // None | |
330 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_RESUME,MCI_WAIT,&mgp, 0)) == MCIERR_SUCCESS) return 0; | |
331 return(CD_ERROR); | |
332 } | |
333 | |
334 /* Stop play - Ready for MCI */ | |
335 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
336 { | |
337 MCI_GENERIC_PARMS mgp; | |
338 MCI_STATUS_PARMS msp; | |
339 | |
340 /* Verifies if it is paused first... and if it is, unpause before stopping it. */ | |
341 msp.hwndCallback = (HWND)NULL; /* None */ | |
342 msp.ulReturn = (ULONG)NULL; /* We want this information */ | |
343 msp.ulItem = MCI_STATUS_MODE; | |
344 msp.ulValue = (ULONG)NULL; /* No additional information */ | |
345 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,&msp, 0)) == MCIERR_SUCCESS) | |
346 { | |
347 if (msp.ulReturn == MCI_MODE_PAUSE) | |
348 { | |
349 mgp.hwndCallback = (HWND)NULL; // None | |
350 mciSendCommand(cdrom->id,MCI_RESUME,NULL,&mgp, 0); | |
351 } | |
352 } | |
353 /* Now stops the media */ | |
354 mgp.hwndCallback = (HWND)NULL; // None | |
355 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STOP,MCI_WAIT,&mgp, 0)) == MCIERR_SUCCESS) return 0; | |
356 return(CD_ERROR); | |
357 } | |
358 | |
359 /* Eject the CD-ROM - Ready for MCI */ | |
360 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
361 { | |
362 MCI_SET_PARMS msp; | |
363 | |
364 msp.hwndCallback = (HWND)NULL; // None | |
365 msp.ulTimeFormat = (ULONG)NULL; // No change | |
366 msp.ulSpeedFormat = (ULONG)NULL; // No change | |
367 msp.ulAudio = (ULONG)NULL; // No Channel | |
368 msp.ulLevel = (ULONG)NULL; // No Volume | |
369 msp.ulOver = (ULONG)NULL; // No Delay | |
370 msp.ulItem = (ULONG)NULL; // No item | |
371 msp.ulValue = (ULONG)NULL; // No value for item flag | |
372 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_SET,MCI_WAIT | MCI_SET_DOOR_OPEN,&msp, 0)) == MCIERR_SUCCESS) return 0; | |
373 return(CD_ERROR); | |
374 } | |
375 | |
376 /* Close the CD-ROM handle - Ready for MCI */ | |
377 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
378 { | |
379 MCI_GENERIC_PARMS mgp; | |
380 | |
381 mgp.hwndCallback = (HWND)NULL; // None | |
382 mciSendCommand(cdrom->id,MCI_CLOSE,MCI_WAIT,&mgp, 0); | |
383 } | |
384 | |
385 /* Finalize CDROM Subsystem - Ready for MCI */ | |
386 void SDL_SYS_CDQuit(void) | |
387 { | |
388 int i; | |
389 | |
390 if ( SDL_numcds > 0 ) | |
391 { | |
392 for ( i=0; i<SDL_numcds; ++i ) | |
393 { | |
394 free(SDL_cdlist[i]); | |
395 } | |
396 SDL_numcds = 0; | |
397 } | |
398 } | |
399 |