SDL_cdrom.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public
  13.     License along with this library; if not, write to the Free
  14.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15.     Sam Lantinga
  16.     slouken@libsdl.org
  17. */
  18. #ifdef SAVE_RCSID
  19. static char rcsid =
  20.  "@(#) $Id: SDL_cdrom.c,v 1.4 2002/04/22 21:38:02 wmay Exp $";
  21. #endif
  22. /* This is the CD-audio control API for Simple DirectMedia Layer */
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include "SDL_error.h"
  27. #include "SDL_cdrom.h"
  28. #include "SDL_syscdrom.h"
  29. #if !defined(macintosh)
  30. #define CLIP_FRAMES 10 /* Some CD-ROMs won't go all the way */
  31. #endif
  32. static int SDL_cdinitted = 0;
  33. static SDL_CD *default_cdrom;
  34. /* The system level CD-ROM control functions */
  35. struct CDcaps SDL_CDcaps = {
  36. NULL, /* Name */
  37. NULL, /* Open */
  38. NULL, /* GetTOC */
  39. NULL, /* Status */
  40. NULL, /* Play */
  41. NULL, /* Pause */
  42. NULL, /* Resume */
  43. NULL, /* Stop */
  44. NULL, /* Eject */
  45. NULL, /* Close */
  46. };
  47. int SDL_numcds;
  48. int SDL_CDROMInit(void)
  49. {
  50. int retval;
  51. SDL_numcds = 0;
  52. retval = SDL_SYS_CDInit();
  53. if ( retval == 0 ) {
  54. SDL_cdinitted = 1;
  55. }
  56. default_cdrom = NULL;
  57. return(retval);
  58. }
  59. /* Check to see if the CD-ROM subsystem has been initialized */
  60. static int CheckInit(int check_cdrom, SDL_CD **cdrom)
  61. {
  62. int okay;
  63. okay = SDL_cdinitted;
  64. if ( check_cdrom && (*cdrom == NULL) ) {
  65. *cdrom = default_cdrom;
  66. if ( *cdrom == NULL ) {
  67. SDL_SetError("CD-ROM not opened");
  68. okay = 0;
  69. }
  70. }
  71. if ( ! SDL_cdinitted ) {
  72. SDL_SetError("CD-ROM subsystem not initialized");
  73. }
  74. return(okay);
  75. }
  76. int SDL_CDNumDrives(void)
  77. {
  78. if ( ! CheckInit(0, NULL) ) {
  79. return(-1);
  80. }
  81. return(SDL_numcds);
  82. }
  83. const char *SDL_CDName(int drive)
  84. {
  85. if ( ! CheckInit(0, NULL) ) {
  86. return(NULL);
  87. }
  88. if ( drive >= SDL_numcds ) {
  89. SDL_SetError("Invalid CD-ROM drive index");
  90. return(NULL);
  91. }
  92. if ( SDL_CDcaps.Name ) {
  93. return(SDL_CDcaps.Name(drive));
  94. } else {
  95. return("");
  96. }
  97. }
  98. SDL_CD *SDL_CDOpen(int drive)
  99. {
  100. struct SDL_CD *cdrom;
  101. if ( ! CheckInit(0, NULL) ) {
  102. return(NULL);
  103. }
  104. if ( drive >= SDL_numcds ) {
  105. SDL_SetError("Invalid CD-ROM drive index");
  106. return(NULL);
  107. }
  108. cdrom = (SDL_CD *)malloc(sizeof(*cdrom));
  109. if ( cdrom == NULL ) {
  110. SDL_OutOfMemory();
  111. return(NULL);
  112. }
  113. memset(cdrom, 0, sizeof(*cdrom));
  114. cdrom->id = SDL_CDcaps.Open(drive);
  115. if ( cdrom->id < 0 ) {
  116. free(cdrom);
  117. return(NULL);
  118. }
  119. default_cdrom = cdrom;
  120. return(cdrom);
  121. }
  122. CDstatus SDL_CDStatus(SDL_CD *cdrom)
  123. {
  124. CDstatus status;
  125. int i;
  126. Uint32 position;
  127. /* Check if the CD-ROM subsystem has been initialized */
  128. if ( ! CheckInit(1, &cdrom) ) {
  129. return(CD_ERROR);
  130. }
  131. /* Get the current status of the drive */
  132. cdrom->numtracks = 0;
  133. cdrom->cur_track = 0;
  134. cdrom->cur_frame = 0;
  135. status = SDL_CDcaps.Status(cdrom, &i);
  136. position = (Uint32)i;
  137. cdrom->status = status;
  138. /* Get the table of contents, if there's a CD available */
  139. if ( CD_INDRIVE(status) ) {
  140. if ( SDL_CDcaps.GetTOC(cdrom) < 0 ) {
  141. status = CD_ERROR;
  142. }
  143. /* If the drive is playing, get current play position */
  144. if ( (status == CD_PLAYING) || (status == CD_PAUSED) ) {
  145. for ( i=1; cdrom->track[i].offset <= position; ++i ) {
  146. /* Keep looking */;
  147. }
  148. #ifdef DEBUG_CDROM
  149.   fprintf(stderr, "Current position: %d, track = %d (offset is %d)n",
  150. position, i-1, cdrom->track[i-1].offset);
  151. #endif
  152. cdrom->cur_track = i-1;
  153. position -= cdrom->track[cdrom->cur_track].offset;
  154. cdrom->cur_frame = position;
  155. }
  156. }
  157. return(status);
  158. }
  159. int SDL_CDPlayTracks(SDL_CD *cdrom,
  160. int strack, int sframe, int ntracks, int nframes)
  161. {
  162. int etrack, eframe;
  163. int start, length;
  164. /* Check if the CD-ROM subsystem has been initialized */
  165. if ( ! CheckInit(1, &cdrom) ) {
  166. return(CD_ERROR);
  167. }
  168. /* Determine the starting and ending tracks */
  169. if ( (strack < 0) || (strack >= cdrom->numtracks) ) {
  170. SDL_SetError("Invalid starting track");
  171. return(CD_ERROR);
  172. }
  173. if ( ! ntracks && ! nframes ) {
  174. etrack = cdrom->numtracks;
  175. eframe = 0;
  176. } else {
  177. etrack = strack+ntracks;
  178. if ( etrack == strack ) {
  179. eframe = sframe + nframes;
  180. } else {
  181. eframe = nframes;
  182. }
  183. }
  184. if ( etrack > cdrom->numtracks ) {
  185. SDL_SetError("Invalid play length");
  186. return(CD_ERROR);
  187. }
  188. /* Skip data tracks and verify frame offsets */
  189. while ( (strack <= etrack) &&
  190. (cdrom->track[strack].type == SDL_DATA_TRACK) ) {
  191. ++strack;
  192. }
  193. if ( sframe >= (int)cdrom->track[strack].length ) {
  194. SDL_SetError("Invalid starting frame for track %d", strack);
  195. return(CD_ERROR);
  196. }
  197. while ( (etrack > strack) &&
  198. (cdrom->track[etrack-1].type == SDL_DATA_TRACK) ) {
  199. --etrack;
  200. }
  201. if ( eframe > (int)cdrom->track[etrack].length ) {
  202. SDL_SetError("Invalid ending frame for track %d", etrack);
  203. return(CD_ERROR);
  204. }
  205. /* Determine start frame and play length */
  206. start = (cdrom->track[strack].offset+sframe);
  207. length = (cdrom->track[etrack].offset+eframe)-start;
  208. #ifdef CLIP_FRAMES
  209. /* I've never seen this necessary, but xmcd does it.. */
  210. length -= CLIP_FRAMES; /* CLIP_FRAMES == 10 */
  211. #endif
  212. if ( length < 0 ) {
  213. return(0);
  214. }
  215. /* Play! */
  216. #ifdef DEBUG_CDROM
  217.   fprintf(stderr, "Playing %d frames at offset %dn", length, start);
  218. #endif
  219. return(SDL_CDcaps.Play(cdrom, start, length));
  220. }
  221. int SDL_CDPlay(SDL_CD *cdrom, int sframe, int length)
  222. {
  223. /* Check if the CD-ROM subsystem has been initialized */
  224. if ( ! CheckInit(1, &cdrom) ) {
  225. return(CD_ERROR);
  226. }
  227. return(SDL_CDcaps.Play(cdrom, sframe, length));
  228. }
  229. int SDL_CDPause(SDL_CD *cdrom)
  230. {
  231. CDstatus status;
  232. int retval;
  233. /* Check if the CD-ROM subsystem has been initialized */
  234. if ( ! CheckInit(1, &cdrom) ) {
  235. return(CD_ERROR);
  236. }
  237. status = SDL_CDcaps.Status(cdrom, NULL);
  238. switch (status) {
  239. case CD_PLAYING:
  240. retval = SDL_CDcaps.Pause(cdrom);
  241. break;
  242. default:
  243. retval = 0;
  244. break;
  245. }
  246. return(retval);
  247. }
  248. int SDL_CDResume(SDL_CD *cdrom)
  249. {
  250. CDstatus status;
  251. int retval;
  252. /* Check if the CD-ROM subsystem has been initialized */
  253. if ( ! CheckInit(1, &cdrom) ) {
  254. return(CD_ERROR);
  255. }
  256. status = SDL_CDcaps.Status(cdrom, NULL);
  257. switch (status) {
  258. case CD_PAUSED:
  259. retval = SDL_CDcaps.Resume(cdrom);
  260. default:
  261. retval = 0;
  262. break;
  263. }
  264. return(retval);
  265. }
  266. int SDL_CDStop(SDL_CD *cdrom)
  267. {
  268. CDstatus status;
  269. int retval;
  270. /* Check if the CD-ROM subsystem has been initialized */
  271. if ( ! CheckInit(1, &cdrom) ) {
  272. return(CD_ERROR);
  273. }
  274. status = SDL_CDcaps.Status(cdrom, NULL);
  275. switch (status) {
  276. case CD_PLAYING:
  277. case CD_PAUSED:
  278. retval = SDL_CDcaps.Stop(cdrom);
  279. default:
  280. retval = 0;
  281. break;
  282. }
  283. return(retval);
  284. }
  285. int SDL_CDEject(SDL_CD *cdrom)
  286. {
  287. /* Check if the CD-ROM subsystem has been initialized */
  288. if ( ! CheckInit(1, &cdrom) ) {
  289. return(CD_ERROR);
  290. }
  291. return(SDL_CDcaps.Eject(cdrom));
  292. }
  293. void SDL_CDClose(SDL_CD *cdrom)
  294. {
  295. /* Check if the CD-ROM subsystem has been initialized */
  296. if ( ! CheckInit(1, &cdrom) ) {
  297. return;
  298. }
  299. SDL_CDcaps.Close(cdrom);
  300. free(cdrom);
  301. default_cdrom = NULL;
  302. }
  303. void SDL_CDROMQuit(void)
  304. {
  305. SDL_SYS_CDQuit();
  306. SDL_cdinitted = 0;
  307. }