Mercurial > sdl-ios-xcode
annotate src/cdrom/win32/SDL_syscdrom.c @ 1076:8d3b95ece376
[PATCH] SDL_GetVideoMode() do not find the best video mode
The current GetVideoMode() function stops at the first mode which has any
dimensions smaller than the one asked, and gives the previous in the list.
If I ask 336x224 with this list:
768x480 768x240 640x400 640x200 384x480 384x240 320x400 320x200
SDL will give me 640x400, because 640x200 as height smaller than what I
asked.
However the best mode is the smaller which has both dimensions bigger
than the one asked (384x240 in my example).
This patch fixes this, plus it does not rely on a sorted video mode list.
author | Patrice Mandin <patmandin@gmail.com> |
---|---|
date | Sun, 12 Jun 2005 16:12:55 +0000 |
parents | 34af7946130a |
children | c9b51268668f |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 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 | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
201
diff
changeset
|
20 slouken@libsdl.org |
0 | 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 #include <stdlib.h> | |
31 #include <stdio.h> | |
32 #include <windows.h> | |
33 #include <mmsystem.h> | |
34 | |
35 #include "SDL_error.h" | |
36 #include "SDL_cdrom.h" | |
37 #include "SDL_syscdrom.h" | |
38 | |
39 /* This really broken?? */ | |
40 #define BROKEN_MCI_PAUSE /* Pausing actually stops play -- Doh! */ | |
41 | |
42 /* The maximum number of CD-ROM drives we'll detect (Don't change!) */ | |
43 #define MAX_DRIVES 26 | |
44 | |
45 /* A list of available CD-ROM drives */ | |
46 static char *SDL_cdlist[MAX_DRIVES]; | |
47 static MCIDEVICEID SDL_mciID[MAX_DRIVES]; | |
48 #ifdef BROKEN_MCI_PAUSE | |
49 static int SDL_paused[MAX_DRIVES]; | |
50 #endif | |
904
34af7946130a
Date: Fri, 16 Jul 2004 17:25:45 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
51 static int SDL_CD_end_position; |
0 | 52 |
53 /* The system-dependent CD control functions */ | |
54 static const char *SDL_SYS_CDName(int drive); | |
55 static int SDL_SYS_CDOpen(int drive); | |
56 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
57 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
58 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
59 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
60 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
61 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
62 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
63 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
64 | |
65 | |
66 /* Add a CD-ROM drive to our list of valid drives */ | |
67 static void AddDrive(char *drive) | |
68 { | |
69 int i; | |
70 | |
71 if ( SDL_numcds < MAX_DRIVES ) { | |
72 /* Add this drive to our list */ | |
73 i = SDL_numcds; | |
74 SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); | |
75 if ( SDL_cdlist[i] == NULL ) { | |
76 SDL_OutOfMemory(); | |
77 return; | |
78 } | |
79 strcpy(SDL_cdlist[i], drive); | |
80 ++SDL_numcds; | |
81 #ifdef CDROM_DEBUG | |
82 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); | |
83 #endif | |
84 } | |
85 } | |
86 | |
87 int SDL_SYS_CDInit(void) | |
88 { | |
89 /* checklist: Drive 'A' - 'Z' */ | |
90 int i; | |
91 char drive[4]; | |
92 | |
93 /* Fill in our driver capabilities */ | |
94 SDL_CDcaps.Name = SDL_SYS_CDName; | |
95 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
96 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
97 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
98 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
99 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
100 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
101 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
102 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
103 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
104 | |
105 /* Scan the system for CD-ROM drives */ | |
106 for ( i='A'; i<='Z'; ++i ) { | |
107 sprintf(drive, "%c:\\", i); | |
108 if ( GetDriveType(drive) == DRIVE_CDROM ) { | |
109 AddDrive(drive); | |
110 } | |
111 } | |
112 memset(SDL_mciID, 0, sizeof(SDL_mciID)); | |
113 return(0); | |
114 } | |
115 | |
116 /* General ioctl() CD-ROM command function */ | |
117 static int SDL_SYS_CDioctl(int id, UINT msg, DWORD flags, void *arg) | |
118 { | |
119 MCIERROR mci_error; | |
120 | |
121 mci_error = mciSendCommand(SDL_mciID[id], msg, flags, (DWORD)arg); | |
122 if ( mci_error ) { | |
123 char error[256]; | |
124 | |
125 mciGetErrorString(mci_error, error, 256); | |
126 SDL_SetError("mciSendCommand() error: %s", error); | |
127 } | |
128 return(!mci_error ? 0 : -1); | |
129 } | |
130 | |
131 static const char *SDL_SYS_CDName(int drive) | |
132 { | |
133 return(SDL_cdlist[drive]); | |
134 } | |
135 | |
136 static int SDL_SYS_CDOpen(int drive) | |
137 { | |
138 MCI_OPEN_PARMS mci_open; | |
139 MCI_SET_PARMS mci_set; | |
140 char device[3]; | |
141 DWORD flags; | |
142 | |
143 /* Open the requested device */ | |
144 mci_open.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO; | |
145 device[0] = *SDL_cdlist[drive]; | |
146 device[1] = ':'; | |
147 device[2] = '\0'; | |
148 mci_open.lpstrElementName = device; | |
149 flags = | |
150 (MCI_OPEN_TYPE|MCI_OPEN_SHAREABLE|MCI_OPEN_TYPE_ID|MCI_OPEN_ELEMENT); | |
151 if ( SDL_SYS_CDioctl(0, MCI_OPEN, flags, &mci_open) < 0 ) { | |
152 flags &= ~MCI_OPEN_SHAREABLE; | |
153 if ( SDL_SYS_CDioctl(0, MCI_OPEN, flags, &mci_open) < 0 ) { | |
154 return(-1); | |
155 } | |
156 } | |
157 SDL_mciID[drive] = mci_open.wDeviceID; | |
158 | |
159 /* Set the minute-second-frame time format */ | |
160 mci_set.dwTimeFormat = MCI_FORMAT_MSF; | |
161 SDL_SYS_CDioctl(drive, MCI_SET, MCI_SET_TIME_FORMAT, &mci_set); | |
162 | |
163 #ifdef BROKEN_MCI_PAUSE | |
164 SDL_paused[drive] = 0; | |
165 #endif | |
166 return(drive); | |
167 } | |
168 | |
169 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
170 { | |
171 MCI_STATUS_PARMS mci_status; | |
172 int i, okay; | |
173 DWORD flags; | |
174 | |
175 okay = 0; | |
176 mci_status.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; | |
177 flags = MCI_STATUS_ITEM | MCI_WAIT; | |
178 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) == 0 ) { | |
179 cdrom->numtracks = mci_status.dwReturn; | |
180 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
181 cdrom->numtracks = SDL_MAX_TRACKS; | |
182 } | |
183 /* Read all the track TOC entries */ | |
184 flags = MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT; | |
185 for ( i=0; i<cdrom->numtracks; ++i ) { | |
186 cdrom->track[i].id = i+1; | |
187 mci_status.dwTrack = cdrom->track[i].id; | |
188 #ifdef MCI_CDA_STATUS_TYPE_TRACK | |
189 mci_status.dwItem = MCI_CDA_STATUS_TYPE_TRACK; | |
190 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, | |
191 &mci_status) < 0 ) { | |
192 break; | |
193 } | |
194 if ( mci_status.dwReturn == MCI_CDA_TRACK_AUDIO ) { | |
195 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
196 } else { | |
197 cdrom->track[i].type = SDL_DATA_TRACK; | |
198 } | |
199 #else | |
200 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
201 #endif | |
202 mci_status.dwItem = MCI_STATUS_POSITION; | |
203 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, | |
204 &mci_status) < 0 ) { | |
205 break; | |
206 } | |
207 cdrom->track[i].offset = MSF_TO_FRAMES( | |
208 MCI_MSF_MINUTE(mci_status.dwReturn), | |
209 MCI_MSF_SECOND(mci_status.dwReturn), | |
210 MCI_MSF_FRAME(mci_status.dwReturn)); | |
211 cdrom->track[i].length = 0; | |
212 if ( i > 0 ) { | |
213 cdrom->track[i-1].length = | |
214 cdrom->track[i].offset- | |
215 cdrom->track[i-1].offset; | |
216 } | |
217 } | |
218 if ( i == cdrom->numtracks ) { | |
201
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
219 mci_status.dwTrack = cdrom->track[i - 1].id; |
0 | 220 mci_status.dwItem = MCI_STATUS_LENGTH; |
221 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, | |
222 &mci_status) == 0 ) { | |
201
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
223 cdrom->track[i - 1].length = MSF_TO_FRAMES( |
0 | 224 MCI_MSF_MINUTE(mci_status.dwReturn), |
225 MCI_MSF_SECOND(mci_status.dwReturn), | |
201
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
226 MCI_MSF_FRAME(mci_status.dwReturn)) + 1; /* +1 to fix */ |
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
227 /* MCI last track length bug */ |
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
228 /* compute lead-out offset */ |
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
229 cdrom->track[i].offset = cdrom->track[i - 1].offset + |
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
230 cdrom->track[i - 1].length; |
0 | 231 cdrom->track[i].length = 0; |
232 okay = 1; | |
233 } | |
234 } | |
235 } | |
236 return(okay ? 0 : -1); | |
237 } | |
238 | |
239 /* Get CD-ROM status */ | |
240 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
241 { | |
242 CDstatus status; | |
243 MCI_STATUS_PARMS mci_status; | |
244 DWORD flags; | |
245 | |
246 flags = MCI_STATUS_ITEM | MCI_WAIT; | |
247 mci_status.dwItem = MCI_STATUS_MODE; | |
248 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) < 0 ) { | |
249 status = CD_ERROR; | |
250 } else { | |
251 switch (mci_status.dwReturn) { | |
252 case MCI_MODE_NOT_READY: | |
253 case MCI_MODE_OPEN: | |
254 status = CD_TRAYEMPTY; | |
255 break; | |
256 case MCI_MODE_STOP: | |
257 #ifdef BROKEN_MCI_PAUSE | |
258 if ( SDL_paused[cdrom->id] ) { | |
259 status = CD_PAUSED; | |
260 } else { | |
261 status = CD_STOPPED; | |
262 } | |
263 #else | |
264 status = CD_STOPPED; | |
265 #endif /* BROKEN_MCI_PAUSE */ | |
266 break; | |
267 case MCI_MODE_PLAY: | |
192
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
268 #ifdef BROKEN_MCI_PAUSE |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
269 if ( SDL_paused[cdrom->id] ) { |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
270 status = CD_PAUSED; |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
271 } else { |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
272 status = CD_PLAYING; |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
273 } |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
274 #else |
0 | 275 status = CD_PLAYING; |
192
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
276 #endif /* BROKEN_MCI_PAUSE */ |
0 | 277 break; |
278 case MCI_MODE_PAUSE: | |
279 status = CD_PAUSED; | |
280 break; | |
281 default: | |
282 status = CD_ERROR; | |
283 break; | |
284 } | |
285 } | |
286 if ( position ) { | |
287 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
288 mci_status.dwItem = MCI_STATUS_POSITION; | |
289 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, | |
290 &mci_status) == 0 ) { | |
291 *position = MSF_TO_FRAMES( | |
292 MCI_MSF_MINUTE(mci_status.dwReturn), | |
293 MCI_MSF_SECOND(mci_status.dwReturn), | |
294 MCI_MSF_FRAME(mci_status.dwReturn)); | |
295 } else { | |
296 *position = 0; | |
297 } | |
298 } else { | |
299 *position = 0; | |
300 } | |
301 } | |
302 return(status); | |
303 } | |
304 | |
305 /* Start play */ | |
306 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
307 { | |
308 MCI_PLAY_PARMS mci_play; | |
309 int m, s, f; | |
310 DWORD flags; | |
311 | |
312 flags = MCI_FROM | MCI_TO | MCI_NOTIFY; | |
313 mci_play.dwCallback = 0; | |
314 FRAMES_TO_MSF(start, &m, &s, &f); | |
315 mci_play.dwFrom = MCI_MAKE_MSF(m, s, f); | |
316 FRAMES_TO_MSF(start+length, &m, &s, &f); | |
317 mci_play.dwTo = MCI_MAKE_MSF(m, s, f); | |
904
34af7946130a
Date: Fri, 16 Jul 2004 17:25:45 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
318 SDL_CD_end_position = mci_play.dwTo; |
0 | 319 return(SDL_SYS_CDioctl(cdrom->id, MCI_PLAY, flags, &mci_play)); |
320 } | |
321 | |
322 /* Pause play */ | |
323 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
324 { | |
325 #ifdef BROKEN_MCI_PAUSE | |
326 SDL_paused[cdrom->id] = 1; | |
327 #endif | |
328 return(SDL_SYS_CDioctl(cdrom->id, MCI_PAUSE, MCI_WAIT, NULL)); | |
329 } | |
330 | |
331 /* Resume play */ | |
332 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
333 { | |
334 #ifdef BROKEN_MCI_PAUSE | |
335 MCI_STATUS_PARMS mci_status; | |
336 int okay; | |
337 int flags; | |
338 | |
339 okay = 0; | |
904
34af7946130a
Date: Fri, 16 Jul 2004 17:25:45 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
340 /* Play from the current play position to the end position set earlier */ |
0 | 341 flags = MCI_STATUS_ITEM | MCI_WAIT; |
342 mci_status.dwItem = MCI_STATUS_POSITION; | |
343 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) == 0 ) { | |
344 MCI_PLAY_PARMS mci_play; | |
345 | |
904
34af7946130a
Date: Fri, 16 Jul 2004 17:25:45 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
346 flags = MCI_FROM | MCI_TO | MCI_NOTIFY; |
0 | 347 mci_play.dwCallback = 0; |
348 mci_play.dwFrom = mci_status.dwReturn; | |
904
34af7946130a
Date: Fri, 16 Jul 2004 17:25:45 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
349 mci_play.dwTo = SDL_CD_end_position; |
0 | 350 if (SDL_SYS_CDioctl(cdrom->id,MCI_PLAY,flags,&mci_play) == 0) { |
351 okay = 1; | |
352 SDL_paused[cdrom->id] = 0; | |
353 } | |
354 } | |
355 return(okay ? 0 : -1); | |
356 #else | |
357 return(SDL_SYS_CDioctl(cdrom->id, MCI_RESUME, MCI_WAIT, NULL)); | |
358 #endif /* BROKEN_MCI_PAUSE */ | |
359 } | |
360 | |
361 /* Stop play */ | |
362 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
363 { | |
364 return(SDL_SYS_CDioctl(cdrom->id, MCI_STOP, MCI_WAIT, NULL)); | |
365 } | |
366 | |
367 /* Eject the CD-ROM */ | |
368 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
369 { | |
370 return(SDL_SYS_CDioctl(cdrom->id, MCI_SET, MCI_SET_DOOR_OPEN, NULL)); | |
371 } | |
372 | |
373 /* Close the CD-ROM handle */ | |
374 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
375 { | |
376 SDL_SYS_CDioctl(cdrom->id, MCI_CLOSE, MCI_WAIT, NULL); | |
377 } | |
378 | |
379 void SDL_SYS_CDQuit(void) | |
380 { | |
381 int i; | |
382 | |
383 if ( SDL_numcds > 0 ) { | |
384 for ( i=0; i<SDL_numcds; ++i ) { | |
385 free(SDL_cdlist[i]); | |
386 } | |
387 SDL_numcds = 0; | |
388 } | |
389 } |