Some "cast to pointer from integer of different size" warnings removed.
[AROS-Contrib.git] / MultiMedia / play / sdlfunc.c
blobb1098776e7806ebc76fceac10d51fb3a322de82e
1 /*
2 2004/09/10 - Joseph Fenton, added calculation of
3 samples per frame.
4 */
6 #include "externs.h"
8 static SDL_Surface *screen;
9 static SDL_Overlay *yuv;
10 static SDL_Rect rect;
12 int silence, bytes_in_buffer = 0;
14 static unsigned char *audioport_buffer = NULL;
15 static volatile unsigned long samples_played = 0;
17 extern int use_audio, audio_sample_rate, audio_channels, frame_width, frame_height;
19 #ifndef min
20 #define min(a,b) ((a) > (b) ? (b) : (a))
21 #endif
23 void os_delay(int msec)
25 SDL_Delay(msec);
28 static unsigned long starttick = 0;
30 unsigned long get_elapsed_samples(void)
32 if(use_audio)
33 return samples_played;
34 else
35 return (SDL_GetTicks() - starttick);
38 void start_audio(void)
40 if(use_audio)
41 SDL_PauseAudio(0);
44 void stop_audio(void)
46 if(use_audio)
47 SDL_PauseAudio(1);
50 int write_audio(char *buffer, int len)
52 if( (bytes_in_buffer+len) <= AUDIOPORT_BUFFERSIZE) {
53 SDL_LockAudio();
55 memcpy(audioport_buffer+bytes_in_buffer, buffer, len);
57 bytes_in_buffer += len;
59 SDL_UnlockAudio();
61 return len;
63 else if (bytes_in_buffer < AUDIOPORT_BUFFERSIZE) {
64 // XXX controllare questo codice, non mi convince
65 fprintf(stderr, "Written in buffer %d bytes, trashed remaining %d bytes\n",
66 AUDIOPORT_BUFFERSIZE - bytes_in_buffer,
67 len - (AUDIOPORT_BUFFERSIZE - bytes_in_buffer) );
68 SDL_LockAudio();
70 memcpy(audioport_buffer+bytes_in_buffer,
71 buffer, AUDIOPORT_BUFFERSIZE - bytes_in_buffer);
73 bytes_in_buffer = AUDIOPORT_BUFFERSIZE;
74 SDL_UnlockAudio();
76 return AUDIOPORT_BUFFERSIZE - bytes_in_buffer;
79 fprintf(stderr, "Audio port BUFFER full!!!!\n");
81 return -1;
84 void my_audio_callback(void *userdata, Uint8 *stream, int len)
86 int amount;
88 if (bytes_in_buffer > 0) {
90 if(bytes_in_buffer>len)
91 amount = len;
92 else
93 amount = bytes_in_buffer;
95 SDL_MixAudio(stream, audioport_buffer, amount,
96 SDL_MIX_MAXVOLUME);
98 samples_played += ((amount/audio_channels)/2);
100 // memcpy(stream, audioport_buffer, amount);
102 if(amount < bytes_in_buffer) {
103 bytes_in_buffer -= amount;
104 memcpy(audioport_buffer, audioport_buffer + amount, bytes_in_buffer);
105 } else {
106 if(amount < len) {
107 memset(stream+amount, silence, len - amount);
109 bytes_in_buffer = 0;
112 } else {
113 memset(stream, silence, len);
118 void init_system(char *title)
120 int sdlflags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
122 if(use_audio)
123 sdlflags |= SDL_INIT_AUDIO;
125 if(verbose)
126 fprintf(stderr, "SDL initialization...\n");
128 if(debugging)
129 SDL_Delay(2000);
131 if(SDL_Init(sdlflags) < 0) {
132 fprintf(stderr, "Unable to open SDL.");
133 exit(-1);
136 atexit(SDL_Quit);
138 if(verbose)
139 fprintf(stderr, " Open the window %d,%d\n", frame_width, frame_height);
141 if(debugging)
142 SDL_Delay(2000);
144 if(!(screen = SDL_SetVideoMode(frame_width, frame_height, 0, SDL_RESIZABLE))) {
145 fprintf(stderr, "Unable to open SDL window: %s.\n", SDL_GetError());
146 exit(-2);
149 if(verbose)
150 fprintf(stderr, " Overlay creation....");
152 if(debugging)
153 SDL_Delay(2000);
155 if ( !(yuv = SDL_CreateYUVOverlay(frame_width, frame_height,
156 SDL_YV12_OVERLAY, screen)) ) {
157 fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
158 exit(-3);
161 printf(" Created %dx%dx%d %s %s overlay\n",yuv->w,yuv->h,yuv->planes,
162 yuv->hw_overlay?"hardware":"software",
163 yuv->format==SDL_YV12_OVERLAY?"YV12":
164 yuv->format==SDL_IYUV_OVERLAY?"IYUV":
165 yuv->format==SDL_YUY2_OVERLAY?"YUY2":
166 yuv->format==SDL_UYVY_OVERLAY?"UYVY":
167 yuv->format==SDL_YVYU_OVERLAY?"YVYU":
168 "Unknown");
170 if(debugging)
171 SDL_Delay(2000);
173 if(use_audio) {
174 SDL_AudioSpec desired;
175 unsigned long samples_per_frame;
177 if(verbose)
178 fprintf(stderr, " Opening audio...\n");
180 if(debugging)
181 SDL_Delay(2000);
183 samples_per_frame = (unsigned long) ((double)audio_sample_rate / frame_rate + 0.5);
184 desired.freq = audio_sample_rate;
185 desired.channels = audio_channels;
186 desired.samples = samples_per_frame;
188 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
189 desired.format = AUDIO_S16LSB;
190 #else
191 desired.format = AUDIO_S16MSB;
192 #endif
194 desired.callback = my_audio_callback;
196 if(SDL_OpenAudio(&desired, NULL) < 0) {
197 fprintf(stderr, "Unable to open audio: %s.\n", SDL_GetError());
198 exit(-4);
201 if(debugging)
202 SDL_Delay(2000);
204 if(!(audioport_buffer = malloc(AUDIOPORT_BUFFERSIZE))) {
205 fprintf(stderr, "No memory for the audio buffer!\n");
206 exit(-5);
210 use_audio = 1;
212 silence = desired.silence;
214 SDL_PauseAudio(1);
217 starttick = SDL_GetTicks();
219 SDL_WM_SetCaption(title, NULL);
221 rect.x = 0;
222 rect.y = 0;
223 rect.w = screen->w;
224 rect.h = screen->h;
226 if(debugging)
227 SDL_Delay(2000);
229 if(verbose)
230 fprintf(stderr, "SDL initialized.\n");
232 if(debugging)
233 SDL_Delay(2000);
236 void handle_events(void)
238 SDL_Event event;
239 static int fullscreen = 0;
240 static int paused = 0;
242 do {
243 if(paused)
244 SDL_WaitEvent(NULL);
246 while (SDL_PollEvent(&event)) {
247 switch (event.type) {
248 #ifdef WIN32
249 // per qualche strano motivo win genera questo evento quasi a raffica...
250 case 204:
251 break;
252 #endif
253 case SDL_MOUSEBUTTONUP:
254 case SDL_MOUSEBUTTONDOWN:
255 break;
256 case SDL_KEYUP:
257 case SDL_MOUSEMOTION:
258 break;
259 case SDL_KEYDOWN:
260 switch(event.key.keysym.sym) {
261 case SDLK_q:
262 terminate_app:
263 if(benchmark_mode)
264 print_benchmark_result();
265 else
266 fprintf(stderr, "\nTerminated by user request.\n");
267 exit(0);
268 case SDLK_p:
269 paused ^= 1;
271 if(paused) {
272 if(verbose)
273 fprintf(stderr, "\nEntering pause mode.\n");
274 stop_audio();
276 else {
277 if(verbose)
278 fprintf(stderr, "\nExiting pause mode.\n");
279 start_audio();
282 sample_frame = get_elapsed_samples();
284 break;
285 case SDLK_SPACE:
286 SDL_FreeYUVOverlay(yuv);
288 rect.x = 0;
290 if(fullscreen) {
291 if(verbose)
292 fprintf(stderr, "\nEntering windowed mode...\n");
294 screen = SDL_SetVideoMode(frame_width, frame_height,
295 0 , SDL_RESIZABLE);
296 fullscreen = 0;
298 rect.y = 0;
299 rect.h = screen->h;
301 else {
302 if(verbose)
303 fprintf(stderr, "\nEntering fullscreen mode..\n");
305 screen = SDL_SetVideoMode(800, 600,
306 32 , SDL_FULLSCREEN|SDL_SWSURFACE);
308 fullscreen = 1;
310 rect.h = min(screen->h, (screen->w * frame_height)/frame_width);
312 if(rect.h < screen->h) {
313 rect.y = (screen->h - rect.h) / 2;
317 rect.w=screen->w;
319 if(!screen) {
320 fprintf(stderr, "Impossible to switch to %s mode.\n",
321 fullscreen ? "fullscreen" : "windowed");
322 exit(0);
325 if(!(yuv = SDL_CreateYUVOverlay(frame_width, frame_height,
326 SDL_YV12_OVERLAY, screen))) {
327 fprintf(stderr, "Impossible to recreate video overlay!\n");
328 exit(0);
331 if(verbose)
332 fprintf(stderr, "Setting rectangle to (%d,%d) %dx%d\n",
333 rect.x, rect.y, rect.w, rect.h);
334 break;
336 break;
337 case SDL_QUIT:
338 goto terminate_app;
340 case SDL_VIDEORESIZE:
341 SDL_FreeYUVOverlay(yuv);
343 screen=SDL_SetVideoMode(event.resize.w, event.resize.h,
344 0 , SDL_RESIZABLE);
346 if(!screen) {
347 fprintf(stderr, "Non riesco a ridimensionare la finestra!\n");
348 return;
351 if(!(yuv = SDL_CreateYUVOverlay(frame_width, frame_height,
352 SDL_YV12_OVERLAY, screen))) {
353 fprintf(stderr, "Errore nell'inizializzazione dell'overlay!\n");
354 return;
357 rect.w=event.resize.w;
358 rect.h=event.resize.h;
359 break;
362 } while(paused);
364 return;
367 void display_picture(AVPicture *picture)
369 if(yuv && !SDL_LockYUVOverlay(yuv) ) {
371 if(yuv->pitches[0] == picture->linesize[0]) {
372 int size = yuv->pitches[0] * yuv->h;
374 memcpy(yuv->pixels[0], picture->data[0], size);
375 size /= 4;
376 memcpy(yuv->pixels[2], picture->data[1], size);
377 memcpy(yuv->pixels[1], picture->data[2], size);
379 else {
380 register unsigned char *y1,*y2,*y3,*i1,*i2,*i3;
381 int i;
382 y1 = yuv->pixels[0];
383 y3 = yuv->pixels[1]; // invertiti xche' avevo i colori sballati!
384 y2 = yuv->pixels[2];
386 i1=picture->data[0];
387 i2=picture->data[1];
388 i3=picture->data[2];
390 for (i = 0; i<(yuv->h/2); i++) {
391 memcpy(y1,i1,yuv->pitches[0]);
392 i1+=picture->linesize[0];
393 y1+=yuv->pitches[0];
394 memcpy(y1,i1,yuv->pitches[0]);
396 memcpy(y2,i2,yuv->pitches[1]);
397 memcpy(y3,i3,yuv->pitches[2]);
399 y1+=yuv->pitches[0];
400 y2+=yuv->pitches[1];
401 y3+=yuv->pitches[2];
402 i1+=picture->linesize[0];
403 i2+=picture->linesize[1];
404 i3+=picture->linesize[2];
407 SDL_UnlockYUVOverlay(yuv);
410 SDL_DisplayYUVOverlay(yuv, &rect);