sdltest.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <time.h>
00005 #include <sys/time.h>
00006 #include <math.h>
00007 #include <signal.h>
00008 #include <memory.h>
00009 #include <SDL.h>
00010 
00011 #include <vorbis/vorbisfile.h>
00012 
00013 struct music_file {
00014     struct music_file *next;
00015     char *name;
00016     char *buf;
00017     int size;
00018 };
00019 struct music_file *music_files;
00020 
00021 struct music_file *
00022 get_music_file (char *name)
00023 {
00024     struct music_file *mp;
00025     FILE *inf;
00026     int togo, offset;
00027     OggVorbis_File vf;
00028     int ret;
00029     int bs;
00030     char fullname[1000];
00031     int chop;
00032 
00033     for (mp = music_files; mp; mp = mp->next) {
00034         if (xstrcasecmp (name, mp->name) == 0)
00035             return (mp);
00036     }
00037 
00038     sprintf (fullname, "/home/pace/ogg/%s.ogg", name);
00039 
00040     fprintf (stderr, "opening music file `%s'", fullname);
00041 
00042     if ((inf = fopen(fullname, "rb")) == NULL) {
00043         fprintf(stderr, "can't open music file `%s'", fullname);
00044         return NULL;
00045     }
00046 
00047     if ((mp = calloc (1, sizeof *mp)) == NULL) {
00048         fprintf (stderr, "out of memory\n");
00049         exit (1);
00050     }
00051 
00052     if ((mp->name = strdup (name)) == NULL) {
00053         fprintf (stderr, "out of memory\n");
00054         exit (1);
00055     }
00056 
00057     mp->next = music_files;
00058     music_files = mp;
00059 
00060     if (ov_open (inf, &vf, NULL, 0) < 0) {
00061         fprintf(stderr, "ERROR: Failed to open input as vorbis\n");
00062         goto bad;
00063     }
00064 
00065     if (ov_info(&vf, 0)->channels != 1) {
00066         fprintf (stderr, "ERROR: ogg file must be mono\n");
00067         goto bad;
00068     }
00069 
00070         mp->size = ov_pcm_total(&vf, 0); /* output size in bytes */
00071 
00072     if ((mp->buf = calloc (1, mp->size)) == NULL) {
00073         fprintf (stderr, "out of memory\n");
00074         exit (1);
00075     }
00076 
00077     togo = mp->size;
00078     offset = 0;
00079 
00080     while (togo > 0) {
00081         if ((ret = ov_read (&vf, mp->buf + offset,
00082                     togo, 0, 1, 0, &bs)) < 0)
00083             break;
00084 
00085         offset += ret;
00086         togo -= ret;
00087     }
00088 
00089     ov_clear(&vf); /* closes inf */
00090 
00091     chop = 2 * 11025;
00092     if (mp->size > chop)
00093         mp->size -= chop;
00094 
00095     return (mp);
00096 bad:
00097     fclose (inf);
00098     return (mp);
00099 }
00100 
00101 SDL_Surface *sur;
00102 
00103 
00104 double
00105 get_time (void)
00106 {
00107     struct timeval tv;
00108     gettimeofday (&tv, NULL);
00109     return (tv.tv_sec + tv.tv_usec / 1e6);
00110 }
00111 
00112 void
00113 intr (int sig)
00114 {
00115     SDL_Quit ();
00116     exit (0);
00117 }
00118 
00119 int have_audio;
00120 
00121 SDL_AudioSpec audio_desired, audio_obtained;
00122 
00123 struct audio_chunk {
00124     struct audio_chunk *next;
00125     unsigned char *data;
00126     int size;
00127     int loop;
00128 };
00129 
00130 struct audio_chunk *cur_chunk, **cur_chunk_tailp = &cur_chunk;
00131 int cur_offset;
00132 
00133 void
00134 audio_callback (void *userdata, Uint8 *stream, int len)
00135 {
00136     int togo, thistime;
00137 
00138     togo = len;
00139 
00140     while (togo && cur_chunk) {
00141         thistime = cur_chunk->size - cur_offset;
00142         if (thistime > togo)
00143             thistime = togo;
00144         memcpy (stream, cur_chunk->data + cur_offset, thistime);
00145 
00146         stream += thistime;
00147         togo -= thistime;
00148         cur_offset += thistime;
00149 
00150         if (cur_offset >= cur_chunk->size) {
00151             if (cur_chunk->loop == 0) {
00152                 if ((cur_chunk = cur_chunk->next) == NULL)
00153                     cur_chunk_tailp = &cur_chunk;
00154             }
00155             cur_offset = 0;
00156         }
00157     }
00158 
00159     memset (stream, audio_obtained.silence, togo);
00160 }
00161 
00162 void
00163 play (struct audio_chunk *new_chunk)
00164 {
00165     if (have_audio == 0)
00166         return;
00167     SDL_LockAudio ();
00168     *cur_chunk_tailp = new_chunk;
00169     SDL_UnlockAudio ();
00170 }
00171 
00172 void
00173 test_news (void)
00174 {
00175     struct audio_chunk *cp;
00176     FILE *f;
00177 
00178     cp = calloc (1, sizeof *cp);
00179     cp->data = malloc (1000 * 1000);
00180 
00181     if ((f = fopen ("/l/baris/gamedat/unews.cdr", "rb")) == NULL) {
00182         fprintf (stderr, "can't open unews.cdr\n");
00183         exit (1);
00184     }
00185 
00186     cp->size = fread (cp->data, 1, 1000 * 1000, f);
00187 
00188     fclose (f);
00189 
00190     play (cp);
00191 }
00192 
00193 void
00194 test_music (void)
00195 {
00196     struct music_file *mp;
00197     struct audio_chunk *cp;
00198 
00199     if ((mp = get_music_file ("SOVTYP")) == NULL) {
00200         fprintf (stderr, "can't find music file\n");
00201         exit (1);
00202     }
00203 
00204     if (mp->buf == NULL || mp->size == 0) {
00205         fprintf (stderr, "can't get music\n");
00206         exit (1);
00207     }
00208 
00209     cp = calloc (1, sizeof *cp);
00210     cp->data = (void *)mp->buf;
00211     cp->size = mp->size;
00212     cp->loop = 1;
00213     play (cp);
00214 }
00215 
00216 int
00217 main ()
00218 {
00219     SDL_Rect r;
00220     SDL_Event ev;
00221 
00222     if (SDL_Init (SDL_INIT_VIDEO) < 0) {
00223         fprintf (stderr, "SDL_Init error\n");
00224         exit (1);
00225     }
00226 
00227 
00228     if (SDL_InitSubSystem (SDL_INIT_AUDIO < 0)) {
00229         printf ("no audio\n");
00230     } else {
00231         printf ("audio initialized\n");
00232         have_audio = 1;
00233     }
00234 
00235     if ((sur = SDL_SetVideoMode (320, 200, 24, SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL) {
00236         fprintf (stderr, "error in SDL_SetVideoMode\n");
00237         exit (1);
00238     }
00239 
00240     SDL_EnableUNICODE (1);
00241 
00242     audio_desired.freq = 11025;
00243     audio_desired.format = AUDIO_U8;
00244     audio_desired.channels = 1;
00245     audio_desired.samples = 8192;
00246     audio_desired.callback = audio_callback;
00247 
00248     if (SDL_OpenAudio (&audio_desired, &audio_obtained) < 0) {
00249         fprintf (stderr, "error in SDL_OpenAudio\n");
00250         exit (1);
00251     }
00252 
00253     test_music ();
00254     SDL_PauseAudio (0);
00255 
00256     while (1) {
00257         while (SDL_PollEvent (&ev)) {
00258             switch (ev.type) {
00259             case SDL_QUIT:
00260                 exit (0);
00261                 break;
00262             case SDL_KEYDOWN:
00263                 printf ("got key %d\n", ev.key.keysym.unicode);
00264                 break;
00265 
00266                 /* ignore these events */
00267             case SDL_KEYUP:
00268             case SDL_ACTIVEEVENT:
00269             case SDL_MOUSEMOTION:
00270                 break;
00271             default:
00272                 printf ("got uknown event %d\n", ev.type);
00273                 break;
00274             }
00275         }
00276 
00277         r.x = 0; r.y = 0; r.w = 320; r.h = 200;
00278         SDL_FillRect (sur, &r, 0);
00279 
00280         r.x = 160 + 120 * cos (get_time () * .5 * M_PI);
00281         r.y = 100;
00282         r.w = 20;
00283         r.h = 20;
00284         SDL_FillRect (sur, &r, 0xff0000);
00285     
00286         SDL_Flip (sur);
00287 
00288         usleep (33 * 1000);
00289 
00290     }
00291 
00292     return (0);
00293 }
00294 

Generated on Fri Sep 28 00:35:46 2007 for raceintospace by  doxygen 1.5.3