ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SIDPlayer/src/main_sdl.cpp
(Generate patch)

Comparing SIDPlayer/src/main_sdl.cpp (file contents):
Revision 1.4 by cebix, 2001-01-16T14:12:54Z vs.
Revision 1.11 by cebix, 2003-04-11T20:23:02Z

# Line 1 | Line 1
1   /*
2   *  main_sdl.cpp - SIDPlayer SDL main program
3   *
4 < *  SIDPlayer (C) Copyright 1996-2000 Christian Bauer
4 > *  SIDPlayer (C) Copyright 1996-2003 Christian Bauer
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 21 | Line 21
21   #include "sys.h"
22  
23   #include <SDL.h>
24 + #include <SDL/SDL_endian.h>
25 +
26   #include <stdio.h>
27   #include <stdlib.h>
28 + #include <errno.h>
29 +
30 + #ifdef __unix__
31 + #include <unistd.h>
32 + #include <sys/time.h>
33 + #endif
34  
35   #include "main.h"
36   #include "prefs.h"
# Line 30 | Line 38
38  
39  
40   /*
41 + *  Get current value of microsecond timer
42 + */
43 +
44 + uint64 GetTicks_usec(void)
45 + {
46 + #ifdef __unix__
47 +        struct timeval t;
48 +        gettimeofday(&t, NULL);
49 +        return uint64(t.tv_sec) * 1000000 + t.tv_usec;
50 + #else
51 +        return uint64(SDL_GetTicks()) * 1000;
52 + #endif
53 + }
54 +
55 +
56 + /*
57 + *  Delay by specified number of microseconds (<1 second)
58 + *  (adapted from SDL_Delay() source)
59 + */
60 +
61 + void Delay_usec(uint32 usec)
62 + {
63 + #ifdef __unix__
64 +        int was_error;
65 + #ifndef __linux__       /* Non-Linux implementations need to calculate time left */
66 +        uint64 then, now, elapsed;
67 + #endif
68 +        struct timeval tv;
69 +
70 +        /* Set the timeout interval - Linux only needs to do this once */
71 + #ifdef __linux__
72 +        tv.tv_sec = 0;
73 +        tv.tv_usec = usec;
74 + #else
75 +        then = GetTicks_usec();
76 + #endif
77 +        do {
78 +                errno = 0;
79 + #ifndef __linux__
80 +                /* Calculate the time interval left (in case of interrupt) */
81 +                now = GetTicks_usec();
82 +                elapsed = (now-then);
83 +                then = now;
84 +                if ( elapsed >= usec ) {
85 +                        break;
86 +                }
87 +                usec -= elapsed;
88 +                tv.tv_sec = 0;
89 +                tv.tv_usec = usec;
90 + #endif
91 +                was_error = select(0, NULL, NULL, NULL, &tv);
92 +        } while (was_error && (errno == EINTR));
93 + #else
94 +        SDL_Delay(usec / 1000);
95 + #endif
96 + }
97 +
98 +
99 + /*
100   *  Main program
101   */
102  
103   static void usage(const char *prg_name)
104   {
105 <        printf("\nUsage: %s [options] FILE [song_number]]\n", prg_name);
105 >        printf("Usage: %s [OPTION...] FILE [song_number]\n", prg_name);
106 >        PrefsPrintUsage();
107          exit(0);
108   }
109  
# Line 50 | Line 118 | int main(int argc, char **argv)
118          // Print banner
119          printf(
120                  PACKAGE " Version " VERSION "\n\n"
121 <                "Copyright (C) 1996-2000 Christian Bauer\n"
121 >                "Copyright (C) 1996-2003 Christian Bauer\n"
122                  "E-mail: Christian.Bauer@uni-mainz.de\n"
123                  "http://www.uni-mainz.de/~bauec002/\n\n"
124                  "This is free software with ABSOLUTELY NO WARRANTY.\n"
# Line 58 | Line 126 | int main(int argc, char **argv)
126                  "For details, see the file COPYING.\n\n"
127          );
128  
61        // Parse arguments
62        if (argc < 2)
63                usage(argv[0]);
64        char *file_name = argv[argc - 1];
65        int song = 0;
66        if (argc >= 3) {
67                bool only_numbers = true;
68                for (int i=0; i<strlen(file_name); i++)
69                        if (!isdigit(file_name[i])) {
70                                only_numbers = false;
71                                break;
72                        }
73                if (only_numbers) {
74                        song = atoi(file_name);
75                        file_name = argv[argc - 2];
76                }
77        }
78
129          // Initialize everything
130          if (SDL_Init(SDL_INIT_AUDIO) < 0) {
131                  fprintf(stderr, "Couldn't initialize SDL (%s)\n", SDL_GetError());
# Line 83 | Line 133 | int main(int argc, char **argv)
133          }
134          atexit(quit);
135          InitAll(argc, argv);
136 +        int32 speed = PrefsFindInt32("speed");
137 +
138 +        // Parse non-option arguments
139 +        const char *file_name = NULL;
140 +        int song = 0;
141 +        for (int i=1; i<argc; i++) {
142 +                if (strcmp(argv[i], "--help") == 0)
143 +                        usage(argv[0]);
144 +                else if (argv[i][0] == '-') {
145 +                        fprintf(stderr, "Unrecognized option '%s'\n", argv[i]);
146 +                        usage(argv[0]);
147 +                } else {
148 +                        if (file_name == NULL)
149 +                                file_name = argv[i];  // First non-option argument is file name
150 +                        else
151 +                                song = atoi(argv[i]); // Second non-option argument is song number
152 +                }
153 +        }
154 +        if (file_name == NULL)
155 +                usage(argv[0]);
156  
157          // Load given PSID file
158          if (!LoadPSIDFile(file_name)) {
# Line 97 | Line 167 | int main(int argc, char **argv)
167                  SelectSong(song - 1);
168          }
169  
170 +        SIDAdjustSpeed(speed); // SelectSong and LoadPSIDFile() reset this to 100%
171 +
172          // Print file information
173          printf("Module Name: %s\n", module_name);
174          printf("Author     : %s\n", author_name);
175          printf("Copyright  : %s\n\n", copyright_info);
176          printf("Playing song %d/%d\n", current_song + 1, number_of_songs);
177  
178 <        // Start replay and enter main loop
179 <        SIDAdjustSpeed(PrefsFindInt32("speed"));
180 <        SDL_PauseAudio(false);
181 <        while (true) {
182 <                SDL_Event e;
183 <                if (SDL_WaitEvent(&e)) {
184 <                        if (e.type == SDL_QUIT)
185 <                                break;
178 >        // Replay or output to file?
179 >        const char *outfile = PrefsFindString("outfile");
180 >        if (outfile) {
181 >
182 >                // Open file
183 >                SDL_RWops *f = SDL_RWFromFile(outfile, "wb");
184 >                if (f == NULL) {
185 >                        fprintf(stderr, "Can't open '%s' for writing (%s)\n", outfile, strerror(errno));
186 >                        exit(1);
187 >                }
188 >
189 >                // Get format information
190 >                int32 channels = (PrefsFindBool("stereo") ? 2 : 1);
191 >                int32 bits = (PrefsFindBool("audio16bit") ? 16 : 8);
192 >                int32 rate = PrefsFindInt32("samplerate");
193 >                int32 time = PrefsFindInt32("time");
194 >                int32 bytes_per_frame = channels * (bits / 8);
195 >                int32 bytes_per_second = rate * bytes_per_frame;
196 >                int32 data_length = time * bytes_per_second;
197 >
198 >                // Write header
199 >                SDL_WriteLE32(f, 0x46464952); // "RIFF"
200 >                SDL_WriteLE32(f, 36 + data_length);
201 >                SDL_WriteLE32(f, 0x45564157); // "WAVE"
202 >                SDL_WriteLE32(f, 0x20746D66); // "fmt "
203 >                SDL_WriteLE32(f, 16);
204 >                SDL_WriteLE16(f, 1);
205 >                SDL_WriteLE16(f, channels);
206 >                SDL_WriteLE32(f, rate);
207 >                SDL_WriteLE32(f, bytes_per_second);
208 >                SDL_WriteLE16(f, bytes_per_frame);
209 >                SDL_WriteLE16(f, bits);
210 >                SDL_WriteLE32(f, 0x61746164); // "data"
211 >                SDL_WriteLE32(f, data_length);
212 >
213 >                // Calculate sound and write to file
214 >                uint8 *buf = new uint8[bytes_per_second];
215 >                for (int i=0; i<time; i++) {
216 >                        SIDCalcBuffer(buf, bytes_per_second);
217 > #if SDL_BYTEORDER == SDL_BIG_ENDIAN
218 >                        if (bits > 8) {
219 >                                // WAV file is little-endian, swap audio data
220 >                                for (int b=0; b<bytes_per_second; b+=2) {
221 >                                        uint8 tmp = buf[b];
222 >                                        buf[b] = buf[b+1];
223 >                                        buf[b+1] = tmp;
224 >                                }
225 >                        }
226 > #endif
227 >                        SDL_RWwrite(f, buf, bytes_per_second, 1);
228 >                }
229 >                delete[] buf;
230 >
231 >                // Close file
232 >                SDL_RWclose(f);
233 >                printf("Output written to '%s'\n", outfile);
234 >
235 >        } else if (PrefsFindBool("cwsid")) {
236 >
237 >                // Catweasel output, requires manual timing
238 >                while (true) {
239 >                        SIDExecute();
240 >
241 >                        SDL_Event e;
242 >                        if (SDL_PollEvent(&e)) {
243 >                                if (e.type == SDL_QUIT)
244 >                                        break;
245 >                        }
246 >                }
247 >
248 >        } else {
249 >
250 >                // Start replay and enter main loop
251 >                SDL_PauseAudio(false);
252 >                while (true) {
253 >                        SDL_Event e;
254 >                        if (SDL_WaitEvent(&e)) {
255 >                                if (e.type == SDL_QUIT)
256 >                                        break;
257 >                        }
258                  }
259          }
260  
261 +        ExitAll();
262          return 0;
263   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines