comparison src/xs_sidplay2.cc @ 660:b0743dc9165d

Change tabs to 4 spaces, everywhere.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 02 Apr 2008 22:10:05 +0300
parents acaba070cf49
children 0126579b6652
comparison
equal deleted inserted replaced
659:04ea91a61225 660:b0743dc9165d
37 #include <sidplay/builders/hardsid.h> 37 #include <sidplay/builders/hardsid.h>
38 #endif 38 #endif
39 39
40 40
41 typedef struct { 41 typedef struct {
42 sidplay2 *currEng; 42 sidplay2 *currEng;
43 sidbuilder *currBuilder; 43 sidbuilder *currBuilder;
44 sid2_config_t currConfig; 44 sid2_config_t currConfig;
45 SidTune *currTune; 45 SidTune *currTune;
46 guint8 *buf; 46 guint8 *buf;
47 size_t bufSize; 47 size_t bufSize;
48 } xs_sidplay2_t; 48 } xs_sidplay2_t;
49 49
50 50
51 /* We need to 'export' all this pseudo-C++ crap */ 51 /* We need to 'export' all this pseudo-C++ crap */
52 extern "C" { 52 extern "C" {
53 53
54 54
55 /* Return song information 55 /* Return song information
56 */ 56 */
57 #define TFUNCTION xs_sidplay2_getinfo 57 #define TFUNCTION xs_sidplay2_getinfo
58 #define TFUNCTION2 xs_sidplay2_updateinfo 58 #define TFUNCTION2 xs_sidplay2_updateinfo
59 #define TTUNEINFO SidTuneInfo 59 #define TTUNEINFO SidTuneInfo
60 #define TTUNE SidTune 60 #define TTUNE SidTune
61 #define TENGINE xs_sidplay2_t 61 #define TENGINE xs_sidplay2_t
62 #include "xs_sidplay.h" 62 #include "xs_sidplay.h"
63 63
64 64
65 /* Check if we can play the given file 65 /* Check if we can play the given file
66 */ 66 */
67 gboolean xs_sidplay2_probe(xs_file_t *f) 67 gboolean xs_sidplay2_probe(xs_file_t *f)
68 { 68 {
69 gchar tmpBuf[4]; 69 gchar tmpBuf[4];
70 70
71 if (!f) return FALSE; 71 if (!f) return FALSE;
72 72
73 if (xs_fread(tmpBuf, sizeof(gchar), 4, f) != 4) 73 if (xs_fread(tmpBuf, sizeof(gchar), 4, f) != 4)
74 return FALSE; 74 return FALSE;
75 75
76 if (!strncmp(tmpBuf, "PSID", 4) || !strncmp(tmpBuf, "RSID", 4)) 76 if (!strncmp(tmpBuf, "PSID", 4) || !strncmp(tmpBuf, "RSID", 4))
77 return TRUE; 77 return TRUE;
78 else 78 else
79 return FALSE; 79 return FALSE;
80 } 80 }
81 81
82 82
83 /* Initialize SIDPlay2 83 /* Initialize SIDPlay2
84 */ 84 */
85 gboolean xs_sidplay2_init(xs_status_t * myStatus) 85 gboolean xs_sidplay2_init(xs_status_t * myStatus)
86 { 86 {
87 gint tmpFreq, i; 87 gint tmpFreq, i;
88 xs_sidplay2_t *myEngine; 88 xs_sidplay2_t *myEngine;
89 sid_filter_t tmpFilter; 89 sid_filter_t tmpFilter;
90 t_xs_sid2_filter *f; 90 t_xs_sid2_filter *f;
91 assert(myStatus); 91 assert(myStatus);
92 92
93 /* Allocate internal structures */ 93 /* Allocate internal structures */
94 myEngine = (xs_sidplay2_t *) g_malloc0(sizeof(xs_sidplay2_t)); 94 myEngine = (xs_sidplay2_t *) g_malloc0(sizeof(xs_sidplay2_t));
95 myStatus->sidEngine = myEngine; 95 myStatus->sidEngine = myEngine;
96 if (!myEngine) return FALSE; 96 if (!myEngine) return FALSE;
97 97
98 /* Initialize the engine */ 98 /* Initialize the engine */
99 myEngine->currEng = new sidplay2; 99 myEngine->currEng = new sidplay2;
100 if (!myEngine->currEng) { 100 if (!myEngine->currEng) {
101 xs_error("[SIDPlay2] Could not initialize emulation engine.\n"); 101 xs_error("[SIDPlay2] Could not initialize emulation engine.\n");
102 return FALSE; 102 return FALSE;
103 } 103 }
104 104
105 /* Get current configuration */ 105 /* Get current configuration */
106 myEngine->currConfig = myEngine->currEng->config(); 106 myEngine->currConfig = myEngine->currEng->config();
107 107
108 /* Configure channels and stuff */ 108 /* Configure channels and stuff */
109 switch (myStatus->audioChannels) { 109 switch (myStatus->audioChannels) {
110 110
111 case XS_CHN_AUTOPAN: 111 case XS_CHN_AUTOPAN:
112 myEngine->currConfig.playback = sid2_stereo; 112 myEngine->currConfig.playback = sid2_stereo;
113 break; 113 break;
114 114
115 case XS_CHN_STEREO: 115 case XS_CHN_STEREO:
116 myEngine->currConfig.playback = sid2_stereo; 116 myEngine->currConfig.playback = sid2_stereo;
117 break; 117 break;
118 118
119 case XS_CHN_MONO: 119 case XS_CHN_MONO:
120 default: 120 default:
121 myEngine->currConfig.playback = sid2_mono; 121 myEngine->currConfig.playback = sid2_mono;
122 myStatus->audioChannels = XS_CHN_MONO; 122 myStatus->audioChannels = XS_CHN_MONO;
123 break; 123 break;
124 } 124 }
125 125
126 126
127 /* Memory mode settings */ 127 /* Memory mode settings */
128 switch (xs_cfg.memoryMode) { 128 switch (xs_cfg.memoryMode) {
129 case XS_MPU_BANK_SWITCHING: 129 case XS_MPU_BANK_SWITCHING:
130 myEngine->currConfig.environment = sid2_envBS; 130 myEngine->currConfig.environment = sid2_envBS;
131 break; 131 break;
132 132
133 case XS_MPU_TRANSPARENT_ROM: 133 case XS_MPU_TRANSPARENT_ROM:
134 myEngine->currConfig.environment = sid2_envTP; 134 myEngine->currConfig.environment = sid2_envTP;
135 break; 135 break;
136 136
137 case XS_MPU_PLAYSID_ENVIRONMENT: 137 case XS_MPU_PLAYSID_ENVIRONMENT:
138 myEngine->currConfig.environment = sid2_envPS; 138 myEngine->currConfig.environment = sid2_envPS;
139 break; 139 break;
140 140
141 case XS_MPU_REAL: 141 case XS_MPU_REAL:
142 default: 142 default:
143 myEngine->currConfig.environment = sid2_envR; 143 myEngine->currConfig.environment = sid2_envR;
144 xs_cfg.memoryMode = XS_MPU_REAL; 144 xs_cfg.memoryMode = XS_MPU_REAL;
145 break; 145 break;
146 } 146 }
147 147
148 148
149 /* Audio parameters sanity checking and setup */ 149 /* Audio parameters sanity checking and setup */
150 myEngine->currConfig.precision = myStatus->audioBitsPerSample; 150 myEngine->currConfig.precision = myStatus->audioBitsPerSample;
151 tmpFreq = myStatus->audioFrequency; 151 tmpFreq = myStatus->audioFrequency;
152 152
153 if (myStatus->oversampleEnable) 153 if (myStatus->oversampleEnable)
154 tmpFreq = (tmpFreq * myStatus->oversampleFactor); 154 tmpFreq = (tmpFreq * myStatus->oversampleFactor);
155 155
156 myEngine->currConfig.frequency = tmpFreq; 156 myEngine->currConfig.frequency = tmpFreq;
157 157
158 switch (myStatus->audioBitsPerSample) { 158 switch (myStatus->audioBitsPerSample) {
159 case XS_RES_8BIT: 159 case XS_RES_8BIT:
160 myStatus->audioFormat = FMT_U8; 160 myStatus->audioFormat = FMT_U8;
161 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; 161 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED;
162 break; 162 break;
163 163
164 case XS_RES_16BIT: 164 case XS_RES_16BIT:
165 default: 165 default:
166 switch (myStatus->audioFormat) { 166 switch (myStatus->audioFormat) {
167 case FMT_U16_LE: 167 case FMT_U16_LE:
168 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; 168 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED;
169 break; 169 break;
170 170
171 case FMT_U16_BE: 171 case FMT_U16_BE:
172 myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED; 172 myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED;
173 break; 173 break;
174 174
175 case FMT_U16_NE: 175 case FMT_U16_NE:
176 #if G_BYTE_ORDER == G_BIG_ENDIAN 176 #if G_BYTE_ORDER == G_BIG_ENDIAN
177 myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED; 177 myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED;
178 #else 178 #else
179 #if G_BYTE_ORDER == G_LITTLE_ENDIAN 179 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
180 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; 180 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED;
181 #else 181 #else
182 #error Unsupported endianess! 182 #error Unsupported endianess!
183 #endif 183 #endif
184 #endif 184 #endif
185 break; 185 break;
186 186
187 case FMT_S16_LE: 187 case FMT_S16_LE:
188 myEngine->currConfig.sampleFormat = SID2_LITTLE_SIGNED; 188 myEngine->currConfig.sampleFormat = SID2_LITTLE_SIGNED;
189 break; 189 break;
190 190
191 case FMT_S16_BE: 191 case FMT_S16_BE:
192 myEngine->currConfig.sampleFormat = SID2_BIG_SIGNED; 192 myEngine->currConfig.sampleFormat = SID2_BIG_SIGNED;
193 break; 193 break;
194 194
195 default: 195 default:
196 myStatus->audioFormat = FMT_S16_NE; 196 myStatus->audioFormat = FMT_S16_NE;
197 #if G_BYTE_ORDER == G_BIG_ENDIAN 197 #if G_BYTE_ORDER == G_BIG_ENDIAN
198 myEngine->currConfig.sampleFormat = SID2_BIG_SIGNED; 198 myEngine->currConfig.sampleFormat = SID2_BIG_SIGNED;
199 #else 199 #else
200 #if G_BYTE_ORDER == G_LITTLE_ENDIAN 200 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
201 myEngine->currConfig.sampleFormat = SID2_LITTLE_SIGNED; 201 myEngine->currConfig.sampleFormat = SID2_LITTLE_SIGNED;
202 #else 202 #else
203 #error Unsupported endianess! 203 #error Unsupported endianess!
204 #endif 204 #endif
205 #endif 205 #endif
206 break; 206 break;
207 207
208 } 208 }
209 break; 209 break;
210 } 210 }
211 211
212 /* Convert filter */ 212 /* Convert filter */
213 f = &(xs_cfg.sid2Filter); 213 f = &(xs_cfg.sid2Filter);
214 XSDEBUG("using filter '%s', %d points\n", f->name, f->npoints); 214 XSDEBUG("using filter '%s', %d points\n", f->name, f->npoints);
215 if (f->npoints > XS_SIDPLAY2_NFPOINTS) { 215 if (f->npoints > XS_SIDPLAY2_NFPOINTS) {
216 xs_error("[SIDPlay2] Invalid number of filter curve points (%d > %d)\n", 216 xs_error("[SIDPlay2] Invalid number of filter curve points (%d > %d)\n",
217 f->npoints, XS_SIDPLAY2_NFPOINTS); 217 f->npoints, XS_SIDPLAY2_NFPOINTS);
218 f->npoints = XS_SIDPLAY2_NFPOINTS; 218 f->npoints = XS_SIDPLAY2_NFPOINTS;
219 } 219 }
220 220
221 tmpFilter.points = f->npoints; 221 tmpFilter.points = f->npoints;
222 for (i = 0; i < f->npoints; i++) { 222 for (i = 0; i < f->npoints; i++) {
223 tmpFilter.cutoff[i][0] = f->points[i].x; 223 tmpFilter.cutoff[i][0] = f->points[i].x;
224 tmpFilter.cutoff[i][1] = f->points[i].y; 224 tmpFilter.cutoff[i][1] = f->points[i].y;
225 } 225 }
226 226
227 /* Initialize builder object */ 227 /* Initialize builder object */
228 XSDEBUG("init builder #%i, maxsids=%i\n", xs_cfg.sid2Builder, (myEngine->currEng->info()).maxsids); 228 XSDEBUG("init builder #%i, maxsids=%i\n", xs_cfg.sid2Builder, (myEngine->currEng->info()).maxsids);
229 #ifdef HAVE_RESID_BUILDER 229 #ifdef HAVE_RESID_BUILDER
230 if (xs_cfg.sid2Builder == XS_BLD_RESID) { 230 if (xs_cfg.sid2Builder == XS_BLD_RESID) {
231 ReSIDBuilder *rs = new ReSIDBuilder("ReSID builder"); 231 ReSIDBuilder *rs = new ReSIDBuilder("ReSID builder");
232 myEngine->currBuilder = (sidbuilder *) rs; 232 myEngine->currBuilder = (sidbuilder *) rs;
233 if (rs) { 233 if (rs) {
234 /* Builder object created, initialize it */ 234 /* Builder object created, initialize it */
235 rs->create((myEngine->currEng->info()).maxsids); 235 rs->create((myEngine->currEng->info()).maxsids);
236 if (!*rs) { 236 if (!*rs) {
237 xs_error("reSID->create() failed.\n"); 237 xs_error("reSID->create() failed.\n");
238 return FALSE; 238 return FALSE;
239 } 239 }
240 240
241 rs->filter(xs_cfg.emulateFilters); 241 rs->filter(xs_cfg.emulateFilters);
242 if (!*rs) { 242 if (!*rs) {
243 xs_error("reSID->filter(%d) failed.\n", xs_cfg.emulateFilters); 243 xs_error("reSID->filter(%d) failed.\n", xs_cfg.emulateFilters);
244 return FALSE; 244 return FALSE;
245 } 245 }
246 246
247 // FIXME FIX ME: support other configurable parameters ... 247 // FIXME FIX ME: support other configurable parameters ...
248 // ... WHEN/IF resid-builder+libsidplay2 gets fixed 248 // ... WHEN/IF resid-builder+libsidplay2 gets fixed
249 rs->sampling(tmpFreq); 249 rs->sampling(tmpFreq);
250 if (!*rs) { 250 if (!*rs) {
251 xs_error("reSID->sampling(%d) failed.\n", tmpFreq); 251 xs_error("reSID->sampling(%d) failed.\n", tmpFreq);
252 return FALSE; 252 return FALSE;
253 } 253 }
254 254
255 if (tmpFilter.points > 0) 255 if (tmpFilter.points > 0)
256 rs->filter((sid_filter_t *) &tmpFilter); 256 rs->filter((sid_filter_t *) &tmpFilter);
257 else 257 else
258 rs->filter((sid_filter_t *) NULL); 258 rs->filter((sid_filter_t *) NULL);
259 259
260 if (!*rs) { 260 if (!*rs) {
261 xs_error("reSID->filter(NULL) failed.\n"); 261 xs_error("reSID->filter(NULL) failed.\n");
262 return FALSE; 262 return FALSE;
263 } 263 }
264 } 264 }
265 } 265 }
266 #endif 266 #endif
267 #ifdef HAVE_HARDSID_BUILDER 267 #ifdef HAVE_HARDSID_BUILDER
268 if (xs_cfg.sid2Builder == XS_BLD_HARDSID) { 268 if (xs_cfg.sid2Builder == XS_BLD_HARDSID) {
269 HardSIDBuilder *hs = new HardSIDBuilder("HardSID builder"); 269 HardSIDBuilder *hs = new HardSIDBuilder("HardSID builder");
270 myEngine->currBuilder = (sidbuilder *) hs; 270 myEngine->currBuilder = (sidbuilder *) hs;
271 if (hs) { 271 if (hs) {
272 /* Builder object created, initialize it */ 272 /* Builder object created, initialize it */
273 hs->create((myEngine->currEng->info()).maxsids); 273 hs->create((myEngine->currEng->info()).maxsids);
274 if (!*hs) { 274 if (!*hs) {
275 xs_error("hardSID->create() failed.\n"); 275 xs_error("hardSID->create() failed.\n");
276 return FALSE; 276 return FALSE;
277 } 277 }
278 278
279 hs->filter(xs_cfg.emulateFilters); 279 hs->filter(xs_cfg.emulateFilters);
280 if (!*hs) { 280 if (!*hs) {
281 xs_error("hardSID->filter(%d) failed.\n", xs_cfg.emulateFilters); 281 xs_error("hardSID->filter(%d) failed.\n", xs_cfg.emulateFilters);
282 return FALSE; 282 return FALSE;
283 } 283 }
284 } 284 }
285 } 285 }
286 #endif 286 #endif
287 287
288 if (!myEngine->currBuilder) { 288 if (!myEngine->currBuilder) {
289 xs_error("[SIDPlay2] Could not initialize SIDBuilder object.\n"); 289 xs_error("[SIDPlay2] Could not initialize SIDBuilder object.\n");
290 return FALSE; 290 return FALSE;
291 } 291 }
292 292
293 XSDEBUG("%s\n", myEngine->currBuilder->credits()); 293 XSDEBUG("%s\n", myEngine->currBuilder->credits());
294 294
295 295
296 /* Clockspeed settings */ 296 /* Clockspeed settings */
297 switch (xs_cfg.clockSpeed) { 297 switch (xs_cfg.clockSpeed) {
298 case XS_CLOCK_NTSC: 298 case XS_CLOCK_NTSC:
299 myEngine->currConfig.clockDefault = SID2_CLOCK_NTSC; 299 myEngine->currConfig.clockDefault = SID2_CLOCK_NTSC;
300 break; 300 break;
301 301
302 default: 302 default:
303 xs_error("[SIDPlay2] Invalid clockSpeed=%d, falling back to PAL.\n", 303 xs_error("[SIDPlay2] Invalid clockSpeed=%d, falling back to PAL.\n",
304 xs_cfg.clockSpeed); 304 xs_cfg.clockSpeed);
305 305
306 case XS_CLOCK_PAL: 306 case XS_CLOCK_PAL:
307 myEngine->currConfig.clockDefault = SID2_CLOCK_PAL; 307 myEngine->currConfig.clockDefault = SID2_CLOCK_PAL;
308 xs_cfg.clockSpeed = XS_CLOCK_PAL; 308 xs_cfg.clockSpeed = XS_CLOCK_PAL;
309 break; 309 break;
310 } 310 }
311 311
312 312
313 /* Configure rest of the emulation */ 313 /* Configure rest of the emulation */
314 myEngine->currConfig.sidEmulation = myEngine->currBuilder; 314 myEngine->currConfig.sidEmulation = myEngine->currBuilder;
315 315
316 if (xs_cfg.forceSpeed) { 316 if (xs_cfg.forceSpeed) {
317 myEngine->currConfig.clockForced = true; 317 myEngine->currConfig.clockForced = true;
318 myEngine->currConfig.clockSpeed = myEngine->currConfig.clockDefault; 318 myEngine->currConfig.clockSpeed = myEngine->currConfig.clockDefault;
319 } else { 319 } else {
320 myEngine->currConfig.clockForced = false; 320 myEngine->currConfig.clockForced = false;
321 myEngine->currConfig.clockSpeed = SID2_CLOCK_CORRECT; 321 myEngine->currConfig.clockSpeed = SID2_CLOCK_CORRECT;
322 } 322 }
323 323
324 if ((xs_cfg.sid2OptLevel >= 0) && (xs_cfg.sid2OptLevel <= SID2_MAX_OPTIMISATION)) 324 if ((xs_cfg.sid2OptLevel >= 0) && (xs_cfg.sid2OptLevel <= SID2_MAX_OPTIMISATION))
325 myEngine->currConfig.optimisation = xs_cfg.sid2OptLevel; 325 myEngine->currConfig.optimisation = xs_cfg.sid2OptLevel;
326 else { 326 else {
327 xs_error("Invalid sid2OptLevel=%d, falling back to %d.\n", 327 xs_error("Invalid sid2OptLevel=%d, falling back to %d.\n",
328 xs_cfg.sid2OptLevel, SID2_DEFAULT_OPTIMISATION); 328 xs_cfg.sid2OptLevel, SID2_DEFAULT_OPTIMISATION);
329 329
330 xs_cfg.sid2OptLevel = 330 xs_cfg.sid2OptLevel =
331 myEngine->currConfig.optimisation = SID2_DEFAULT_OPTIMISATION; 331 myEngine->currConfig.optimisation = SID2_DEFAULT_OPTIMISATION;
332 } 332 }
333 333
334 if (xs_cfg.mos8580) 334 if (xs_cfg.mos8580)
335 myEngine->currConfig.sidDefault = SID2_MOS8580; 335 myEngine->currConfig.sidDefault = SID2_MOS8580;
336 else 336 else
337 myEngine->currConfig.sidDefault = SID2_MOS6581; 337 myEngine->currConfig.sidDefault = SID2_MOS6581;
338 338
339 if (xs_cfg.forceModel) 339 if (xs_cfg.forceModel)
340 myEngine->currConfig.sidModel = myEngine->currConfig.sidDefault; 340 myEngine->currConfig.sidModel = myEngine->currConfig.sidDefault;
341 else 341 else
342 myEngine->currConfig.sidModel = SID2_MODEL_CORRECT; 342 myEngine->currConfig.sidModel = SID2_MODEL_CORRECT;
343 343
344 344
345 /* XXX: Should this be configurable? libSIDPlay1 does not support it, though */ 345 /* XXX: Should this be configurable? libSIDPlay1 does not support it, though */
346 myEngine->currConfig.sidSamples = TRUE; 346 myEngine->currConfig.sidSamples = TRUE;
347 347
348 348
349 /* Now set the emulator configuration */ 349 /* Now set the emulator configuration */
350 if (myEngine->currEng->config(myEngine->currConfig) < 0) { 350 if (myEngine->currEng->config(myEngine->currConfig) < 0) {
351 xs_error("[SIDPlay2] Emulator engine configuration failed!\n"); 351 xs_error("[SIDPlay2] Emulator engine configuration failed!\n");
352 return FALSE; 352 return FALSE;
353 } 353 }
354 354
355 /* Create the sidtune */ 355 /* Create the sidtune */
356 myEngine->currTune = new SidTune(0); 356 myEngine->currTune = new SidTune(0);
357 if (!myEngine->currTune) { 357 if (!myEngine->currTune) {
358 xs_error("[SIDPlay2] Could not initialize SIDTune object.\n"); 358 xs_error("[SIDPlay2] Could not initialize SIDTune object.\n");
359 return FALSE; 359 return FALSE;
360 } 360 }
361 361
362 return TRUE; 362 return TRUE;
363 } 363 }
364 364
365 365
366 /* Close SIDPlay2 engine 366 /* Close SIDPlay2 engine
367 */ 367 */
368 void xs_sidplay2_close(xs_status_t * myStatus) 368 void xs_sidplay2_close(xs_status_t * myStatus)
369 { 369 {
370 xs_sidplay2_t *myEngine; 370 xs_sidplay2_t *myEngine;
371 assert(myStatus); 371 assert(myStatus);
372 372
373 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; 373 myEngine = (xs_sidplay2_t *) myStatus->sidEngine;
374 374
375 /* Free internals */ 375 /* Free internals */
376 if (myEngine->currBuilder) { 376 if (myEngine->currBuilder) {
377 delete myEngine->currBuilder; 377 delete myEngine->currBuilder;
378 myEngine->currBuilder = NULL; 378 myEngine->currBuilder = NULL;
379 } 379 }
380 380
381 if (myEngine->currEng) { 381 if (myEngine->currEng) {
382 delete myEngine->currEng; 382 delete myEngine->currEng;
383 myEngine->currEng = NULL; 383 myEngine->currEng = NULL;
384 } 384 }
385 385
386 if (myEngine->currTune) { 386 if (myEngine->currTune) {
387 delete myEngine->currTune; 387 delete myEngine->currTune;
388 myEngine->currTune = NULL; 388 myEngine->currTune = NULL;
389 } 389 }
390 390
391 xs_sidplay2_delete(myStatus); 391 xs_sidplay2_delete(myStatus);
392 392
393 g_free(myEngine); 393 g_free(myEngine);
394 myStatus->sidEngine = NULL; 394 myStatus->sidEngine = NULL;
395 } 395 }
396 396
397 397
398 /* Initialize current song and sub-tune 398 /* Initialize current song and sub-tune
399 */ 399 */
400 gboolean xs_sidplay2_initsong(xs_status_t * myStatus) 400 gboolean xs_sidplay2_initsong(xs_status_t * myStatus)
401 { 401 {
402 xs_sidplay2_t *myEngine; 402 xs_sidplay2_t *myEngine;
403 assert(myStatus); 403 assert(myStatus);
404 404
405 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; 405 myEngine = (xs_sidplay2_t *) myStatus->sidEngine;
406 if (!myEngine) return FALSE; 406 if (!myEngine) return FALSE;
407 407
408 if (!myEngine->currTune->selectSong(myStatus->currSong)) { 408 if (!myEngine->currTune->selectSong(myStatus->currSong)) {
409 xs_error("[SIDPlay2] currTune->selectSong() failed\n"); 409 xs_error("[SIDPlay2] currTune->selectSong() failed\n");
410 return FALSE; 410 return FALSE;
411 } 411 }
412 412
413 if (myEngine->currEng->load(myEngine->currTune) < 0) { 413 if (myEngine->currEng->load(myEngine->currTune) < 0) {
414 xs_error("[SIDPlay2] currEng->load() failed\n"); 414 xs_error("[SIDPlay2] currEng->load() failed\n");
415 return FALSE; 415 return FALSE;
416 } 416 }
417 417
418 myStatus->isInitialized = TRUE; 418 myStatus->isInitialized = TRUE;
419 419
420 return TRUE; 420 return TRUE;
421 } 421 }
422 422
423 423
424 /* Emulate and render audio data to given buffer 424 /* Emulate and render audio data to given buffer
425 */ 425 */
426 guint xs_sidplay2_fillbuffer(xs_status_t * myStatus, gchar * audioBuffer, guint audioBufSize) 426 guint xs_sidplay2_fillbuffer(xs_status_t * myStatus, gchar * audioBuffer, guint audioBufSize)
427 { 427 {
428 xs_sidplay2_t *myEngine; 428 xs_sidplay2_t *myEngine;
429 assert(myStatus); 429 assert(myStatus);
430 430
431 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; 431 myEngine = (xs_sidplay2_t *) myStatus->sidEngine;
432 if (!myEngine) return 0; 432 if (!myEngine) return 0;
433 433
434 return myEngine->currEng->play(audioBuffer, audioBufSize); 434 return myEngine->currEng->play(audioBuffer, audioBufSize);
435 } 435 }
436 436
437 437
438 /* Load a given SID-tune file 438 /* Load a given SID-tune file
439 */ 439 */
440 gboolean xs_sidplay2_load(xs_status_t * myStatus, gchar * pcFilename) 440 gboolean xs_sidplay2_load(xs_status_t * myStatus, gchar * pcFilename)
441 { 441 {
442 xs_sidplay2_t *myEngine; 442 xs_sidplay2_t *myEngine;
443 assert(myStatus); 443 assert(myStatus);
444 myStatus->isInitialized = FALSE; 444 myStatus->isInitialized = FALSE;
445 445
446 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; 446 myEngine = (xs_sidplay2_t *) myStatus->sidEngine;
447 if (!myEngine) return FALSE; 447 if (!myEngine) return FALSE;
448 448
449 /* Try to get the tune */ 449 /* Try to get the tune */
450 if (!pcFilename) return FALSE; 450 if (!pcFilename) return FALSE;
451 451
452 if (xs_fload_buffer(pcFilename, &(myEngine->buf), &(myEngine->bufSize)) != 0) 452 if (xs_fload_buffer(pcFilename, &(myEngine->buf), &(myEngine->bufSize)) != 0)
453 return FALSE; 453 return FALSE;
454 454
455 if (!myEngine->currTune->read(myEngine->buf, myEngine->bufSize)) 455 if (!myEngine->currTune->read(myEngine->buf, myEngine->bufSize))
456 return FALSE; 456 return FALSE;
457 457
458 return TRUE; 458 return TRUE;
459 } 459 }
460 460
461 461
462 /* Delete INTERNAL information 462 /* Delete INTERNAL information
463 */ 463 */
464 void xs_sidplay2_delete(xs_status_t * myStatus) 464 void xs_sidplay2_delete(xs_status_t * myStatus)
465 { 465 {
466 xs_sidplay2_t *myEngine; 466 xs_sidplay2_t *myEngine;
467 assert(myStatus); 467 assert(myStatus);
468 468
469 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; 469 myEngine = (xs_sidplay2_t *) myStatus->sidEngine;
470 if (!myEngine) return; 470 if (!myEngine) return;
471 471
472 g_free(myEngine->buf); 472 g_free(myEngine->buf);
473 myEngine->buf = NULL; 473 myEngine->buf = NULL;
474 myEngine->bufSize = 0; 474 myEngine->bufSize = 0;
475 } 475 }
476 476
477 477
478 /* Hardware backend flushing 478 /* Hardware backend flushing
479 */ 479 */
480 void xs_sidplay2_flush(xs_status_t * myStatus) 480 void xs_sidplay2_flush(xs_status_t * myStatus)
481 { 481 {
482 assert(myStatus); 482 assert(myStatus);
483 483
484 #ifdef HAVE_HARDSID_BUILDER 484 #ifdef HAVE_HARDSID_BUILDER
485 #ifdef HSID_SID2_COM 485 #ifdef HSID_SID2_COM
486 IfPtr<HardSIDBuilder> hs(myStatus->currBuilder); 486 IfPtr<HardSIDBuilder> hs(myStatus->currBuilder);
487 if (hs) 487 if (hs)
488 hs->flush(); 488 hs->flush();
489 #else 489 #else
490 if (xs_cfg.sid2Builder == XS_BLD_HARDSID) 490 if (xs_cfg.sid2Builder == XS_BLD_HARDSID)
491 ((HardSIDBuilder *) myStatus->currBuilder)->flush(); 491 ((HardSIDBuilder *) myStatus->currBuilder)->flush();
492 #endif 492 #endif
493 #endif 493 #endif
494 } 494 }
495 495
496 496
497 } /* extern "C" */ 497 } /* extern "C" */
498 #endif /* HAVE_SIDPLAY2 */ 498 #endif /* HAVE_SIDPLAY2 */