Mercurial > hg > xmms-sid
comparison src/xs_sidplay1.cc @ 73:2bc607888f53
Added libsidplay2 module, lots of reworking of internals, sidplay1 support
now works with the new framework! Getting libsidplay2 support working
shouldn't be too far now...
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 14 Sep 2003 03:14:01 +0000 |
parents | e3b205a6bc7e |
children | 8cb66a3f75f7 |
comparison
equal
deleted
inserted
replaced
72:e3b205a6bc7e | 73:2bc607888f53 |
---|---|
17 | 17 |
18 You should have received a copy of the GNU General Public License | 18 You should have received a copy of the GNU General Public License |
19 along with this program; if not, write to the Free Software | 19 along with this program; if not, write to the Free Software |
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21 */ | 21 */ |
22 #include "xmms-sid.h" | |
23 | |
22 #ifdef HAVE_SIDPLAY1 | 24 #ifdef HAVE_SIDPLAY1 |
25 | |
26 extern "C" { | |
23 #include "xs_sidplay1.h" | 27 #include "xs_sidplay1.h" |
24 | 28 #include <stdio.h> |
25 extern "C" { | 29 #include <xmms/titlestring.h> |
26 #include <xmms/title.h> | 30 #include "xs_config.h" |
31 #include "xs_support.h" | |
32 #include "xs_length.h" | |
27 } | 33 } |
28 | 34 |
29 #include <sidplay/player.h> | 35 #include <sidplay/player.h> |
30 #include <sidplay/myendian.h> | 36 #include <sidplay/myendian.h> |
31 #include <sidplay/fformat.h> | 37 #include <sidplay/fformat.h> |
32 | 38 |
33 | 39 |
34 void xs_sidplay1_close(t_xs_status *myStatus) | 40 typedef struct { |
35 { | 41 emuEngine *currEng; |
36 if (!myStatus) return; | 42 emuConfig currConfig; |
37 | 43 sidTune *currTune; |
38 if (!myStatus->currEng) | 44 } t_xs_sidplay1; |
39 delete (emuEngine *) myStatus->currEng; | 45 |
40 | 46 |
41 if (!myStatus->currConf) | 47 /* |
42 free(myStatus->currConf); | 48 * We need to 'export' all this pseudo-C++ crap |
43 | 49 */ |
44 free(myStatus); | 50 extern "C" { |
45 } | 51 |
46 | 52 gboolean xs_sidplay1_isourfile(gchar *pcFileName) |
47 | 53 { |
48 gboolean xs_sidplay1_init(t_xs_status *myStatus) | 54 /* Try to detect via libSIDPlay's detection routine, if required */ |
49 { | 55 sidTune *testTune = new sidTune(pcFileName); |
50 if (!myStatus) return FALSE; | 56 |
51 | 57 if (!testTune) return FALSE; |
52 myStatus->currEng = (void *) new emuEngine; | 58 if (!testTune->getStatus()) |
53 if (!myStatus->currEng) | |
54 { | 59 { |
55 xs_sidplay1_close(myStatus); | 60 delete testTune; |
56 return FALSE; | 61 return FALSE; |
57 } | 62 } |
58 | 63 |
59 myStatus->currConf = calloc(1, sizeof(struct emuConfig)); | 64 delete testTune; |
60 if (!myStatus->currConf) | 65 return TRUE; |
66 } | |
67 | |
68 | |
69 void xs_sidplay1_close(t_xs_status *myStatus) | |
70 { | |
71 t_xs_sidplay1 *myPlayer; | |
72 | |
73 /* Check pointer */ | |
74 if (!myStatus) return; | |
75 | |
76 /* Free internals */ | |
77 xs_sidplay1_deletesid(myStatus); | |
78 | |
79 myPlayer = (t_xs_sidplay1 *) myStatus->player; | |
80 | |
81 if (myPlayer->currEng) delete myPlayer->currEng; | |
82 | |
83 free(myPlayer); | |
84 myStatus->player = NULL; | |
85 | |
86 /* Miscellaneous */ | |
87 free(myStatus->currFileName); | |
88 myStatus->currFileName = NULL; | |
89 } | |
90 | |
91 | |
92 gboolean xs_sidplay1_init(t_xs_status *myStatus) | |
93 { | |
94 t_xs_sidplay1 *myPlayer; | |
95 | |
96 /* Check pointer */ | |
97 if (!myStatus) return FALSE; | |
98 | |
99 /* Allocate internal structures */ | |
100 myPlayer = (t_xs_sidplay1 *) g_malloc0(sizeof(t_xs_sidplay1)); | |
101 if (!myPlayer) return FALSE; | |
102 | |
103 /* Initialize engine */ | |
104 myPlayer->currEng = new emuEngine(); | |
105 if (!myPlayer->currEng) | |
61 { | 106 { |
62 xs_sidplay1_close(myStatus); | 107 XSERR("Could not initialize libSIDPlay1 emulation engine\n"); |
108 free(myPlayer); | |
63 return FALSE; | 109 return FALSE; |
64 } | 110 } |
65 | 111 |
112 /* Verify endianess */ | |
113 if (!myPlayer->currEng->verifyEndianess()) | |
114 { | |
115 XSERR("Endianess verification failed\n"); | |
116 free(myPlayer); | |
117 return FALSE; | |
118 } | |
119 | |
120 myStatus->player = myPlayer; | |
66 return TRUE; | 121 return TRUE; |
67 } | 122 } |
68 | 123 |
69 | 124 |
70 gboolean xs_sidplay1_initsong(t_xs_status *myStatus) | 125 gboolean xs_sidplay1_initsong(t_xs_status *myStatus) |
71 { | 126 { |
72 if ((!myStatus->currTune) || (!((sidTune *)myStatus->currTune)->getStatus())) return FALSE; | 127 t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player; |
128 | |
129 if (!myPlayer) return FALSE; | |
130 | |
131 if ((!myPlayer->currTune) || (!myPlayer->currTune->getStatus())) return FALSE; | |
73 | 132 |
74 return sidEmuInitializeSong( | 133 return sidEmuInitializeSong( |
75 (emuEngine *) myStatus->currEngine, | 134 *myPlayer->currEng, |
76 (sidTune *) myStatus->currTune, | 135 *myPlayer->currTune, |
77 myStatus->currSong); | 136 myStatus->currSong); |
78 } | 137 } |
79 | 138 |
80 | 139 |
81 void xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, gint audioBufSize) | 140 gboolean xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, gint audioBufSize) |
82 { | 141 { |
142 t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player; | |
143 | |
144 if (!myPlayer) return FALSE; | |
145 | |
83 sidEmuFillBuffer( | 146 sidEmuFillBuffer( |
84 (emuEngine *) myStatus->currEngine, | 147 *myPlayer->currEng, |
85 (sidTune *) myStatus->currTune, | 148 *myPlayer->currTune, |
86 audioBuffer, | 149 audioBuffer, |
87 audioBufSize); | 150 audioBufSize); |
151 | |
152 return TRUE; | |
88 } | 153 } |
89 | 154 |
90 | 155 |
91 gboolean xs_sidplay1_loadsid(t_xs_status *myStatus, gchar *pcFileName) | 156 gboolean xs_sidplay1_loadsid(t_xs_status *myStatus, gchar *pcFileName) |
92 { | 157 { |
158 t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player; | |
93 sidTune *newTune; | 159 sidTune *newTune; |
94 sidTuneInfo tuneInfo; | 160 sidTuneInfo tuneInfo; |
95 | 161 |
96 /* Try to get the tune */ | 162 /* Try to get the tune */ |
97 if (!pcFileName) return FALSE; | 163 if (!pcFileName) return FALSE; |
98 newTune = new sidTune(pcFileName); | 164 newTune = new sidTune(pcFileName); |
99 if (newTune == NULL) return FALSE; | 165 if (!newTune) return FALSE; |
100 | 166 |
101 /* Get current configuration */ | 167 /* Get current configuration */ |
102 myStatus->currEngine.getConfig(myStatus->currConf); | 168 myPlayer->currEng->getConfig(myPlayer->currConfig); |
103 | 169 |
104 /* Configure channels and stuff */ | 170 /* Configure channels and stuff */ |
105 switch (xs_cfg.fmtChannels) { | 171 switch (xs_cfg.fmtChannels) { |
106 | 172 |
107 case XS_CHN_AUTOPAN: | 173 case XS_CHN_AUTOPAN: |
108 myStatus->currConf.channels = SIDEMU_STEREO; | 174 myPlayer->currConfig.channels = SIDEMU_STEREO; |
109 myStatus->currConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING; | 175 myPlayer->currConfig.autoPanning = SIDEMU_CENTEREDAUTOPANNING; |
110 myStatus->currConf.volumeControl = SIDEMU_FULLPANNING; | 176 myPlayer->currConfig.volumeControl = SIDEMU_FULLPANNING; |
111 break; | 177 break; |
112 | 178 |
113 case XS_CHN_STEREO: | 179 case XS_CHN_STEREO: |
114 myStatus->currConf.channels = SIDEMU_STEREO; | 180 myPlayer->currConfig.channels = SIDEMU_STEREO; |
115 myStatus->currConf.autoPanning = SIDEMU_NONE; | 181 myPlayer->currConfig.autoPanning = SIDEMU_NONE; |
116 myStatus->currConf.volumeControl = SIDEMU_NONE; | 182 myPlayer->currConfig.volumeControl = SIDEMU_NONE; |
117 break; | 183 break; |
118 | 184 |
119 case XS_CHN_MONO: | 185 case XS_CHN_MONO: |
120 default: | 186 default: |
121 myStatus->currConf.channels = SIDEMU_MONO; | 187 myPlayer->currConfig.channels = SIDEMU_MONO; |
122 myStatus->currConf.autoPanning = SIDEMU_NONE; | 188 myPlayer->currConfig.autoPanning = SIDEMU_NONE; |
123 myStatus->currConf.volumeControl = SIDEMU_NONE; | 189 myPlayer->currConfig.volumeControl = SIDEMU_NONE; |
124 break; | 190 break; |
125 } | 191 } |
126 | 192 |
127 | 193 |
128 /* Memory mode settings */ | 194 /* Memory mode settings */ |
129 switch (xs_cfg.memoryMode) { | 195 switch (xs_cfg.memoryMode) { |
130 case XS_MPU_BANK_SWITCHING: | 196 case XS_MPU_BANK_SWITCHING: |
131 myStatus->currConf.memoryMode = MPU_BANK_SWITCHING; | 197 myPlayer->currConfig.memoryMode = MPU_BANK_SWITCHING; |
132 break; | 198 break; |
133 | 199 |
134 case XS_MPU_TRANSPARENT_ROM: | 200 case XS_MPU_TRANSPARENT_ROM: |
135 myStatus->currConf.memoryMode = MPU_TRANSPARENT_ROM; | 201 myPlayer->currConfig.memoryMode = MPU_TRANSPARENT_ROM; |
136 break; | 202 break; |
137 | 203 |
138 case XS_MPU_PLAYSID_ENVIRONMENT: | 204 case XS_MPU_PLAYSID_ENVIRONMENT: |
139 myStatus->currConf.memoryMode = MPU_PLAYSID_ENVIRONMENT; | 205 myPlayer->currConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT; |
140 break; | 206 break; |
141 | 207 |
142 default: | 208 default: |
143 myStatus->currConf.memoryMode = MPU_BANK_SWITCHING; | 209 myPlayer->currConfig.memoryMode = MPU_BANK_SWITCHING; |
144 break; | 210 break; |
145 } | 211 } |
146 | 212 |
147 | 213 |
148 /* Clockspeed settings */ | 214 /* Clockspeed settings */ |
149 switch (xs_cfg.clockSpeed) { | 215 switch (xs_cfg.clockSpeed) { |
150 case XS_CLOCK_NTSC: | 216 case XS_CLOCK_NTSC: |
151 myStatus->currConf.clockSpeed = SIDTUNE_CLOCK_NTSC; | 217 myPlayer->currConfig.clockSpeed = SIDTUNE_CLOCK_NTSC; |
152 break; | 218 break; |
153 | 219 |
154 case XS_CLOCK_PAL: | 220 case XS_CLOCK_PAL: |
155 default: | 221 default: |
156 myStatus->currConf.clockSpeed = SIDTUNE_CLOCK_PAL; | 222 myPlayer->currConfig.clockSpeed = SIDTUNE_CLOCK_PAL; |
157 break; | 223 break; |
158 } | 224 } |
159 | 225 |
160 | 226 |
161 /* Configure rest of the emulation */ | 227 /* Configure rest of the emulation */ |
162 myStatus->currConf.bitsPerSample = xs_cfg.fmtBitsPerSample; | 228 myPlayer->currConfig.bitsPerSample = xs_cfg.fmtBitsPerSample; |
163 myStatus->currConf.frequency = xs_cfg.fmtFrequency; | 229 myPlayer->currConfig.frequency = xs_cfg.fmtFrequency; |
164 #ifdef HAVE_UNSIGNEDPCM | 230 #ifdef HAVE_UNSIGNEDPCM |
165 myStatus->currConf.sampleFormat = SIDEMU_UNSIGNED_PCM; | 231 myPlayer->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; |
166 #else | 232 #else |
167 myStatus->currConf.sampleFormat = SIDEMU_SIGNED_PCM; | 233 myPlayer->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; |
168 #endif | 234 #endif |
169 myStatus->currConf.mos8580 = xs_cfg.mos8580; | 235 myPlayer->currConfig.mos8580 = xs_cfg.mos8580; |
170 myStatus->currConf.emulateFilter = xs_cfg.emulateFilters; | 236 myPlayer->currConfig.emulateFilter = xs_cfg.emulateFilters; |
171 myStatus->currConf.filterFs = xs_cfg.filterFs; | 237 myPlayer->currConfig.filterFs = xs_cfg.filterFs; |
172 myStatus->currConf.filterFm = xs_cfg.filterFm; | 238 myPlayer->currConfig.filterFm = xs_cfg.filterFm; |
173 myStatus->currConf.filterFt = xs_cfg.filterFt; | 239 myPlayer->currConfig.filterFt = xs_cfg.filterFt; |
174 | 240 |
175 /* Now set the emulator configuration */ | 241 /* Now set the emulator configuration */ |
176 myStatus->currEngine.setConfig(myStatus->currConf); | 242 myPlayer->currEng->setConfig(myPlayer->currConfig); |
177 | 243 |
178 /* Initialize status information */ | 244 /* Initialize status information */ |
179 newTune->getInfo(tuneInfo); | 245 newTune->getInfo(tuneInfo); |
180 if (!newTune) return FALSE; | |
181 | 246 |
182 myStatus->isPlaying = TRUE; | 247 myStatus->isPlaying = TRUE; |
183 myStatus->isError = FALSE; | 248 myStatus->isError = FALSE; |
184 myStatus->currSong = tuneInfo.startSong; | 249 myStatus->currSong = tuneInfo.startSong; |
185 myStatus->nSongs = tuneInfo.songs; | 250 myStatus->nSongs = tuneInfo.songs; |
186 myStatus->currTune = newTune; | 251 myPlayer->currTune = newTune; |
187 myStatus->currFileName = g_strdup(pcFileName); | 252 myStatus->currFileName = g_strdup(pcFileName); |
188 | 253 |
189 return TRUE; | 254 return TRUE; |
190 } | 255 } |
191 | 256 |
192 | 257 |
258 /* | |
259 * Delete tune | |
260 */ | |
261 void xs_sidplay1_deletesid(t_xs_status *myStatus) | |
262 { | |
263 t_xs_sidplay1 *myPlayer; | |
264 | |
265 if (!myStatus) return; | |
266 | |
267 myPlayer = (t_xs_sidplay1 *) myStatus->player; | |
268 if (!myPlayer) return; | |
269 | |
270 if (myPlayer->currTune) | |
271 delete myPlayer->currTune; | |
272 } | |
273 | |
274 | |
275 gint xs_sidplay1_gettunespeed(t_xs_status *myStatus) | |
276 { | |
277 return 0; | |
278 } | |
279 | |
280 /* | |
281 * Return song information | |
282 */ | |
283 #include "xs_sidplay_info.h" | |
284 | |
285 void xs_sidplay1_getsidinfo(gchar *songFileName, gchar **songTitle, gint *songLength) | |
286 { | |
287 sidTuneInfo tuneInfo; | |
288 sidTune *testTune; | |
289 gint tmpInt; | |
290 | |
291 /* Check if the tune exists and is readable */ | |
292 testTune = new sidTune(songFileName); | |
293 if (!testTune) return; | |
294 if (!testTune->getStatus()) | |
295 { | |
296 delete testTune; | |
297 return; | |
298 } | |
299 | |
300 /* Get general tune information */ | |
301 testTune->getInfo(tuneInfo); | |
302 delete testTune; | |
303 | |
304 /* Get titlestring */ | |
305 *songTitle = xs_make_filetitle(songFileName, &tuneInfo, tuneInfo.startSong); | |
306 | |
307 /* Get song length (in milliseconds), negative if no known length */ | |
308 tmpInt = xs_songlen_get(songFileName, tuneInfo.startSong); | |
309 if (tmpInt >= 0) | |
310 *songLength = (tmpInt * 1000); | |
311 else | |
312 *songLength = -1; | |
313 } | |
314 | |
315 | |
316 } /* extern "C" */ | |
193 #endif /* HAVE_SIDPLAY1 */ | 317 #endif /* HAVE_SIDPLAY1 */ |