diff options
author | Franklin Wei <git@fwei.tk> | 2017-01-21 15:18:31 -0500 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2017-12-23 21:01:26 -0500 |
commit | a855d6202536ff28e5aae4f22a0f31d8f5b325d0 (patch) | |
tree | 8c75f224dd64ed360505afa8843d016b0d75000b /apps/plugins/sdl/src/cdrom/SDL_cdrom.c | |
parent | 01c6dcf6c7b9bb1ad2fa0450f99bacc5f3d3e04b (diff) | |
download | rockbox-a855d6202536ff28e5aae4f22a0f31d8f5b325d0.tar.gz rockbox-a855d6202536ff28e5aae4f22a0f31d8f5b325d0.zip |
Port of Duke Nukem 3D
This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL
for Rockbox.
Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9
Diffstat (limited to 'apps/plugins/sdl/src/cdrom/SDL_cdrom.c')
-rw-r--r-- | apps/plugins/sdl/src/cdrom/SDL_cdrom.c | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/cdrom/SDL_cdrom.c b/apps/plugins/sdl/src/cdrom/SDL_cdrom.c new file mode 100644 index 0000000000..8f91bb1b34 --- /dev/null +++ b/apps/plugins/sdl/src/cdrom/SDL_cdrom.c | |||
@@ -0,0 +1,341 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* This is the CD-audio control API for Simple DirectMedia Layer */ | ||
25 | |||
26 | #include "SDL_cdrom.h" | ||
27 | #include "SDL_syscdrom.h" | ||
28 | |||
29 | #if !defined(__MACOS__) | ||
30 | #define CLIP_FRAMES 10 /* Some CD-ROMs won't go all the way */ | ||
31 | #endif | ||
32 | |||
33 | static int SDL_cdinitted = 0; | ||
34 | static SDL_CD *default_cdrom; | ||
35 | |||
36 | /* The system level CD-ROM control functions */ | ||
37 | struct CDcaps SDL_CDcaps = { | ||
38 | NULL, /* Name */ | ||
39 | NULL, /* Open */ | ||
40 | NULL, /* GetTOC */ | ||
41 | NULL, /* Status */ | ||
42 | NULL, /* Play */ | ||
43 | NULL, /* Pause */ | ||
44 | NULL, /* Resume */ | ||
45 | NULL, /* Stop */ | ||
46 | NULL, /* Eject */ | ||
47 | NULL, /* Close */ | ||
48 | }; | ||
49 | int SDL_numcds; | ||
50 | |||
51 | int SDL_CDROMInit(void) | ||
52 | { | ||
53 | int retval; | ||
54 | |||
55 | SDL_numcds = 0; | ||
56 | retval = SDL_SYS_CDInit(); | ||
57 | if ( retval == 0 ) { | ||
58 | SDL_cdinitted = 1; | ||
59 | } | ||
60 | default_cdrom = NULL; | ||
61 | return(retval); | ||
62 | } | ||
63 | |||
64 | /* Check to see if the CD-ROM subsystem has been initialized */ | ||
65 | static int CheckInit(int check_cdrom, SDL_CD **cdrom) | ||
66 | { | ||
67 | int okay; | ||
68 | |||
69 | okay = SDL_cdinitted; | ||
70 | if ( check_cdrom && (*cdrom == NULL) ) { | ||
71 | *cdrom = default_cdrom; | ||
72 | if ( *cdrom == NULL ) { | ||
73 | SDL_SetError("CD-ROM not opened"); | ||
74 | okay = 0; | ||
75 | } | ||
76 | } | ||
77 | if ( ! SDL_cdinitted ) { | ||
78 | SDL_SetError("CD-ROM subsystem not initialized"); | ||
79 | } | ||
80 | return(okay); | ||
81 | } | ||
82 | |||
83 | int SDL_CDNumDrives(void) | ||
84 | { | ||
85 | if ( ! CheckInit(0, NULL) ) { | ||
86 | return(-1); | ||
87 | } | ||
88 | return(SDL_numcds); | ||
89 | } | ||
90 | |||
91 | const char *SDL_CDName(int drive) | ||
92 | { | ||
93 | if ( ! CheckInit(0, NULL) ) { | ||
94 | return(NULL); | ||
95 | } | ||
96 | if ( drive >= SDL_numcds ) { | ||
97 | SDL_SetError("Invalid CD-ROM drive index"); | ||
98 | return(NULL); | ||
99 | } | ||
100 | if ( SDL_CDcaps.Name ) { | ||
101 | return(SDL_CDcaps.Name(drive)); | ||
102 | } else { | ||
103 | return(""); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | SDL_CD *SDL_CDOpen(int drive) | ||
108 | { | ||
109 | struct SDL_CD *cdrom; | ||
110 | |||
111 | if ( ! CheckInit(0, NULL) ) { | ||
112 | return(NULL); | ||
113 | } | ||
114 | if ( drive >= SDL_numcds ) { | ||
115 | SDL_SetError("Invalid CD-ROM drive index"); | ||
116 | return(NULL); | ||
117 | } | ||
118 | cdrom = (SDL_CD *)SDL_malloc(sizeof(*cdrom)); | ||
119 | if ( cdrom == NULL ) { | ||
120 | SDL_OutOfMemory(); | ||
121 | return(NULL); | ||
122 | } | ||
123 | SDL_memset(cdrom, 0, sizeof(*cdrom)); | ||
124 | cdrom->id = SDL_CDcaps.Open(drive); | ||
125 | if ( cdrom->id < 0 ) { | ||
126 | SDL_free(cdrom); | ||
127 | return(NULL); | ||
128 | } | ||
129 | default_cdrom = cdrom; | ||
130 | return(cdrom); | ||
131 | } | ||
132 | |||
133 | CDstatus SDL_CDStatus(SDL_CD *cdrom) | ||
134 | { | ||
135 | CDstatus status; | ||
136 | int i; | ||
137 | Uint32 position; | ||
138 | |||
139 | /* Check if the CD-ROM subsystem has been initialized */ | ||
140 | if ( ! CheckInit(1, &cdrom) ) { | ||
141 | return(CD_ERROR); | ||
142 | } | ||
143 | |||
144 | /* Get the current status of the drive */ | ||
145 | cdrom->numtracks = 0; | ||
146 | cdrom->cur_track = 0; | ||
147 | cdrom->cur_frame = 0; | ||
148 | status = SDL_CDcaps.Status(cdrom, &i); | ||
149 | position = (Uint32)i; | ||
150 | cdrom->status = status; | ||
151 | |||
152 | /* Get the table of contents, if there's a CD available */ | ||
153 | if ( CD_INDRIVE(status) ) { | ||
154 | if ( SDL_CDcaps.GetTOC(cdrom) < 0 ) { | ||
155 | status = CD_ERROR; | ||
156 | } | ||
157 | /* If the drive is playing, get current play position */ | ||
158 | if ( (status == CD_PLAYING) || (status == CD_PAUSED) ) { | ||
159 | for ( i=1; cdrom->track[i].offset <= position; ++i ) { | ||
160 | /* Keep looking */; | ||
161 | } | ||
162 | #ifdef DEBUG_CDROM | ||
163 | fprintf(stderr, "Current position: %d, track = %d (offset is %d)\n", | ||
164 | position, i-1, cdrom->track[i-1].offset); | ||
165 | #endif | ||
166 | cdrom->cur_track = i-1; | ||
167 | position -= cdrom->track[cdrom->cur_track].offset; | ||
168 | cdrom->cur_frame = position; | ||
169 | } | ||
170 | } | ||
171 | return(status); | ||
172 | } | ||
173 | |||
174 | int SDL_CDPlayTracks(SDL_CD *cdrom, | ||
175 | int strack, int sframe, int ntracks, int nframes) | ||
176 | { | ||
177 | int etrack, eframe; | ||
178 | int start, length; | ||
179 | |||
180 | /* Check if the CD-ROM subsystem has been initialized */ | ||
181 | if ( ! CheckInit(1, &cdrom) ) { | ||
182 | return(CD_ERROR); | ||
183 | } | ||
184 | |||
185 | /* Determine the starting and ending tracks */ | ||
186 | if ( (strack < 0) || (strack >= cdrom->numtracks) ) { | ||
187 | SDL_SetError("Invalid starting track"); | ||
188 | return(CD_ERROR); | ||
189 | } | ||
190 | if ( ! ntracks && ! nframes ) { | ||
191 | etrack = cdrom->numtracks; | ||
192 | eframe = 0; | ||
193 | } else { | ||
194 | etrack = strack+ntracks; | ||
195 | if ( etrack == strack ) { | ||
196 | eframe = sframe + nframes; | ||
197 | } else { | ||
198 | eframe = nframes; | ||
199 | } | ||
200 | } | ||
201 | if ( etrack > cdrom->numtracks ) { | ||
202 | SDL_SetError("Invalid play length"); | ||
203 | return(CD_ERROR); | ||
204 | } | ||
205 | |||
206 | /* Skip data tracks and verify frame offsets */ | ||
207 | while ( (strack <= etrack) && | ||
208 | (cdrom->track[strack].type == SDL_DATA_TRACK) ) { | ||
209 | ++strack; | ||
210 | } | ||
211 | if ( sframe >= (int)cdrom->track[strack].length ) { | ||
212 | SDL_SetError("Invalid starting frame for track %d", strack); | ||
213 | return(CD_ERROR); | ||
214 | } | ||
215 | while ( (etrack > strack) && | ||
216 | (cdrom->track[etrack-1].type == SDL_DATA_TRACK) ) { | ||
217 | --etrack; | ||
218 | } | ||
219 | if ( eframe > (int)cdrom->track[etrack].length ) { | ||
220 | SDL_SetError("Invalid ending frame for track %d", etrack); | ||
221 | return(CD_ERROR); | ||
222 | } | ||
223 | |||
224 | /* Determine start frame and play length */ | ||
225 | start = (cdrom->track[strack].offset+sframe); | ||
226 | length = (cdrom->track[etrack].offset+eframe)-start; | ||
227 | #ifdef CLIP_FRAMES | ||
228 | /* I've never seen this necessary, but xmcd does it.. */ | ||
229 | length -= CLIP_FRAMES; /* CLIP_FRAMES == 10 */ | ||
230 | #endif | ||
231 | if ( length < 0 ) { | ||
232 | return(0); | ||
233 | } | ||
234 | |||
235 | /* Play! */ | ||
236 | #ifdef DEBUG_CDROM | ||
237 | fprintf(stderr, "Playing %d frames at offset %d\n", length, start); | ||
238 | #endif | ||
239 | return(SDL_CDcaps.Play(cdrom, start, length)); | ||
240 | } | ||
241 | |||
242 | int SDL_CDPlay(SDL_CD *cdrom, int sframe, int length) | ||
243 | { | ||
244 | /* Check if the CD-ROM subsystem has been initialized */ | ||
245 | if ( ! CheckInit(1, &cdrom) ) { | ||
246 | return(CD_ERROR); | ||
247 | } | ||
248 | |||
249 | return(SDL_CDcaps.Play(cdrom, sframe, length)); | ||
250 | } | ||
251 | |||
252 | int SDL_CDPause(SDL_CD *cdrom) | ||
253 | { | ||
254 | CDstatus status; | ||
255 | int retval; | ||
256 | |||
257 | /* Check if the CD-ROM subsystem has been initialized */ | ||
258 | if ( ! CheckInit(1, &cdrom) ) { | ||
259 | return(CD_ERROR); | ||
260 | } | ||
261 | |||
262 | status = SDL_CDcaps.Status(cdrom, NULL); | ||
263 | switch (status) { | ||
264 | case CD_PLAYING: | ||
265 | retval = SDL_CDcaps.Pause(cdrom); | ||
266 | break; | ||
267 | default: | ||
268 | retval = 0; | ||
269 | break; | ||
270 | } | ||
271 | return(retval); | ||
272 | } | ||
273 | |||
274 | int SDL_CDResume(SDL_CD *cdrom) | ||
275 | { | ||
276 | CDstatus status; | ||
277 | int retval; | ||
278 | |||
279 | /* Check if the CD-ROM subsystem has been initialized */ | ||
280 | if ( ! CheckInit(1, &cdrom) ) { | ||
281 | return(CD_ERROR); | ||
282 | } | ||
283 | |||
284 | status = SDL_CDcaps.Status(cdrom, NULL); | ||
285 | switch (status) { | ||
286 | case CD_PAUSED: | ||
287 | retval = SDL_CDcaps.Resume(cdrom); | ||
288 | default: | ||
289 | retval = 0; | ||
290 | break; | ||
291 | } | ||
292 | return(retval); | ||
293 | } | ||
294 | |||
295 | int SDL_CDStop(SDL_CD *cdrom) | ||
296 | { | ||
297 | CDstatus status; | ||
298 | int retval; | ||
299 | |||
300 | /* Check if the CD-ROM subsystem has been initialized */ | ||
301 | if ( ! CheckInit(1, &cdrom) ) { | ||
302 | return(CD_ERROR); | ||
303 | } | ||
304 | |||
305 | status = SDL_CDcaps.Status(cdrom, NULL); | ||
306 | switch (status) { | ||
307 | case CD_PLAYING: | ||
308 | case CD_PAUSED: | ||
309 | retval = SDL_CDcaps.Stop(cdrom); | ||
310 | default: | ||
311 | retval = 0; | ||
312 | break; | ||
313 | } | ||
314 | return(retval); | ||
315 | } | ||
316 | |||
317 | int SDL_CDEject(SDL_CD *cdrom) | ||
318 | { | ||
319 | /* Check if the CD-ROM subsystem has been initialized */ | ||
320 | if ( ! CheckInit(1, &cdrom) ) { | ||
321 | return(CD_ERROR); | ||
322 | } | ||
323 | return(SDL_CDcaps.Eject(cdrom)); | ||
324 | } | ||
325 | |||
326 | void SDL_CDClose(SDL_CD *cdrom) | ||
327 | { | ||
328 | /* Check if the CD-ROM subsystem has been initialized */ | ||
329 | if ( ! CheckInit(1, &cdrom) ) { | ||
330 | return; | ||
331 | } | ||
332 | SDL_CDcaps.Close(cdrom); | ||
333 | SDL_free(cdrom); | ||
334 | default_cdrom = NULL; | ||
335 | } | ||
336 | |||
337 | void SDL_CDROMQuit(void) | ||
338 | { | ||
339 | SDL_SYS_CDQuit(); | ||
340 | SDL_cdinitted = 0; | ||
341 | } | ||