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/audio/mint/SDL_mintaudio.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/audio/mint/SDL_mintaudio.c')
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c new file mode 100644 index 0000000000..46ba690c3e --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c | |||
@@ -0,0 +1,215 @@ | |||
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 Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 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 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | Audio interrupt variables and callback function | ||
26 | |||
27 | Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #include <unistd.h> | ||
31 | |||
32 | #include <mint/osbind.h> | ||
33 | #include <mint/falcon.h> | ||
34 | #include <mint/mintbind.h> | ||
35 | #include <mint/cookie.h> | ||
36 | |||
37 | #include "SDL_audio.h" | ||
38 | #include "SDL_mintaudio.h" | ||
39 | #include "SDL_mintaudio_stfa.h" | ||
40 | |||
41 | /* The audio device */ | ||
42 | |||
43 | SDL_AudioDevice *SDL_MintAudio_device; | ||
44 | Uint8 *SDL_MintAudio_audiobuf[2]; /* Pointers to buffers */ | ||
45 | unsigned long SDL_MintAudio_audiosize; /* Length of audio buffer=spec->size */ | ||
46 | volatile unsigned short SDL_MintAudio_numbuf; /* Buffer to play */ | ||
47 | volatile unsigned short SDL_MintAudio_mutex; | ||
48 | volatile unsigned long SDL_MintAudio_clocktics; | ||
49 | cookie_stfa_t *SDL_MintAudio_stfa; | ||
50 | unsigned short SDL_MintAudio_hasfpu; | ||
51 | |||
52 | /* MiNT thread variables */ | ||
53 | SDL_bool SDL_MintAudio_mint_present; | ||
54 | SDL_bool SDL_MintAudio_quit_thread; | ||
55 | SDL_bool SDL_MintAudio_thread_finished; | ||
56 | long SDL_MintAudio_thread_pid; | ||
57 | |||
58 | /* The callback function, called by each driver whenever needed */ | ||
59 | |||
60 | void SDL_MintAudio_Callback(void) | ||
61 | { | ||
62 | Uint8 *buffer; | ||
63 | SDL_AudioDevice *audio = SDL_MintAudio_device; | ||
64 | |||
65 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
66 | SDL_memset(buffer, audio->spec.silence, audio->spec.size); | ||
67 | |||
68 | if (audio->paused) | ||
69 | return; | ||
70 | |||
71 | if (audio->convert.needed) { | ||
72 | int silence; | ||
73 | |||
74 | if ( audio->convert.src_format == AUDIO_U8 ) { | ||
75 | silence = 0x80; | ||
76 | } else { | ||
77 | silence = 0; | ||
78 | } | ||
79 | SDL_memset(audio->convert.buf, silence, audio->convert.len); | ||
80 | audio->spec.callback(audio->spec.userdata, | ||
81 | (Uint8 *)audio->convert.buf,audio->convert.len); | ||
82 | SDL_ConvertAudio(&audio->convert); | ||
83 | SDL_memcpy(buffer, audio->convert.buf, audio->convert.len_cvt); | ||
84 | } else { | ||
85 | audio->spec.callback(audio->spec.userdata, buffer, audio->spec.size); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* Add a new frequency/clock/predivisor to the current list */ | ||
90 | void SDL_MintAudio_AddFrequency(_THIS, Uint32 frequency, Uint32 clock, | ||
91 | Uint32 prediv, int gpio_bits) | ||
92 | { | ||
93 | int i, p; | ||
94 | |||
95 | if (MINTAUDIO_freqcount==MINTAUDIO_maxfreqs) { | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | /* Search where to insert the frequency (highest first) */ | ||
100 | for (p=0; p<MINTAUDIO_freqcount; p++) { | ||
101 | if (frequency > MINTAUDIO_frequencies[p].frequency) { | ||
102 | break; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* Put all following ones farer */ | ||
107 | if (MINTAUDIO_freqcount>0) { | ||
108 | for (i=MINTAUDIO_freqcount; i>p; i--) { | ||
109 | SDL_memcpy(&MINTAUDIO_frequencies[i], &MINTAUDIO_frequencies[i-1], sizeof(mint_frequency_t)); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | /* And insert new one */ | ||
114 | MINTAUDIO_frequencies[p].frequency = frequency; | ||
115 | MINTAUDIO_frequencies[p].masterclock = clock; | ||
116 | MINTAUDIO_frequencies[p].predivisor = prediv; | ||
117 | MINTAUDIO_frequencies[p].gpio_bits = gpio_bits; | ||
118 | |||
119 | MINTAUDIO_freqcount++; | ||
120 | } | ||
121 | |||
122 | /* Search for the nearest frequency */ | ||
123 | int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq) | ||
124 | { | ||
125 | int i; | ||
126 | |||
127 | /* Only 1 freq ? */ | ||
128 | if (MINTAUDIO_freqcount==1) { | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | /* Check the array */ | ||
133 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
134 | if (desired_freq >= ((MINTAUDIO_frequencies[i].frequency+ | ||
135 | MINTAUDIO_frequencies[i+1].frequency)>>1)) { | ||
136 | return i; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | /* Not in the array, give the latest */ | ||
141 | return MINTAUDIO_freqcount-1; | ||
142 | } | ||
143 | |||
144 | /* Check if FPU is present */ | ||
145 | void SDL_MintAudio_CheckFpu(void) | ||
146 | { | ||
147 | long cookie_fpu; | ||
148 | |||
149 | SDL_MintAudio_hasfpu = 0; | ||
150 | if (Getcookie(C__FPU, &cookie_fpu) != C_FOUND) { | ||
151 | return; | ||
152 | } | ||
153 | switch ((cookie_fpu>>16)&0xfffe) { | ||
154 | case 2: | ||
155 | case 4: | ||
156 | case 6: | ||
157 | case 8: | ||
158 | case 16: | ||
159 | SDL_MintAudio_hasfpu = 1; | ||
160 | break; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | /* The thread function, used under MiNT with xbios */ | ||
165 | int SDL_MintAudio_Thread(long param) | ||
166 | { | ||
167 | SndBufPtr pointers; | ||
168 | SDL_bool buffers_filled[2] = {SDL_FALSE, SDL_FALSE}; | ||
169 | |||
170 | SDL_MintAudio_thread_finished = SDL_FALSE; | ||
171 | while (!SDL_MintAudio_quit_thread) { | ||
172 | if (Buffptr(&pointers)!=0) | ||
173 | continue; | ||
174 | |||
175 | if (( (unsigned long)pointers.play>=(unsigned long)SDL_MintAudio_audiobuf[0]) | ||
176 | && ( (unsigned long)pointers.play<=(unsigned long)SDL_MintAudio_audiobuf[1])) | ||
177 | { | ||
178 | /* DMA is reading buffer #0, setup buffer #1 if not already done */ | ||
179 | if (!buffers_filled[1]) { | ||
180 | SDL_MintAudio_numbuf = 1; | ||
181 | SDL_MintAudio_Callback(); | ||
182 | Setbuffer(0, SDL_MintAudio_audiobuf[1], SDL_MintAudio_audiobuf[1] + SDL_MintAudio_audiosize); | ||
183 | buffers_filled[1]=SDL_TRUE; | ||
184 | buffers_filled[0]=SDL_FALSE; | ||
185 | } | ||
186 | } else { | ||
187 | /* DMA is reading buffer #1, setup buffer #0 if not already done */ | ||
188 | if (!buffers_filled[0]) { | ||
189 | SDL_MintAudio_numbuf = 0; | ||
190 | SDL_MintAudio_Callback(); | ||
191 | Setbuffer(0, SDL_MintAudio_audiobuf[0], SDL_MintAudio_audiobuf[0] + SDL_MintAudio_audiosize); | ||
192 | buffers_filled[0]=SDL_TRUE; | ||
193 | buffers_filled[1]=SDL_FALSE; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | usleep(100); | ||
198 | } | ||
199 | SDL_MintAudio_thread_finished = SDL_TRUE; | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | void SDL_MintAudio_WaitThread(void) | ||
204 | { | ||
205 | if (!SDL_MintAudio_mint_present) | ||
206 | return; | ||
207 | |||
208 | if (SDL_MintAudio_thread_finished) | ||
209 | return; | ||
210 | |||
211 | SDL_MintAudio_quit_thread = SDL_TRUE; | ||
212 | while (!SDL_MintAudio_thread_finished) { | ||
213 | Syield(); | ||
214 | } | ||
215 | } | ||