diff 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
line wrap: on
line diff
--- a/src/xs_sidplay1.cc	Fri Sep 12 03:26:04 2003 +0000
+++ b/src/xs_sidplay1.cc	Sun Sep 14 03:14:01 2003 +0000
@@ -19,11 +19,17 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
+#include "xmms-sid.h"
+
 #ifdef HAVE_SIDPLAY1
-#include "xs_sidplay1.h"
 
 extern "C" {
-#include <xmms/title.h>
+#include "xs_sidplay1.h"
+#include <stdio.h>
+#include <xmms/titlestring.h>
+#include "xs_config.h"
+#include "xs_support.h"
+#include "xs_length.h"
 }
 
 #include <sidplay/player.h>
@@ -31,96 +37,156 @@
 #include <sidplay/fformat.h>
 
 
+typedef struct {
+	emuEngine	*currEng;
+	emuConfig	currConfig;
+	sidTune		*currTune;
+} t_xs_sidplay1;
+
+
+/*
+ * We need to 'export' all this pseudo-C++ crap
+ */
+extern "C" {
+
+gboolean xs_sidplay1_isourfile(gchar *pcFileName)
+{
+ /* Try to detect via libSIDPlay's detection routine, if required */
+ sidTune *testTune = new sidTune(pcFileName);
+
+ if (!testTune) return FALSE;
+ if (!testTune->getStatus())
+	{
+	delete testTune;
+	return FALSE;
+	}
+
+ delete testTune;
+ return TRUE;
+}
+
+
 void xs_sidplay1_close(t_xs_status *myStatus)
 {
+ t_xs_sidplay1 *myPlayer;
+
+ /* Check pointer */
  if (!myStatus) return;
 
- if (!myStatus->currEng)
-	delete (emuEngine *) myStatus->currEng;
+ /* Free internals */
+ xs_sidplay1_deletesid(myStatus);
+
+ myPlayer = (t_xs_sidplay1 *) myStatus->player;
+
+ if (myPlayer->currEng) delete myPlayer->currEng;
 
- if (!myStatus->currConf)
-	free(myStatus->currConf);
+ free(myPlayer);
+ myStatus->player = NULL;
 
- free(myStatus);
+ /* Miscellaneous */
+ free(myStatus->currFileName);
+ myStatus->currFileName = NULL;
 }
 
 
 gboolean xs_sidplay1_init(t_xs_status *myStatus)
 {
+ t_xs_sidplay1 *myPlayer;
+
+ /* Check pointer */
  if (!myStatus) return FALSE;
 
- myStatus->currEng = (void *) new emuEngine;
- if (!myStatus->currEng)
+ /* Allocate internal structures */
+ myPlayer = (t_xs_sidplay1 *) g_malloc0(sizeof(t_xs_sidplay1));
+ if (!myPlayer) return FALSE;
+
+ /* Initialize engine */
+ myPlayer->currEng = new emuEngine();
+ if (!myPlayer->currEng)
 	{
-	xs_sidplay1_close(myStatus);
+	XSERR("Could not initialize libSIDPlay1 emulation engine\n");
+	free(myPlayer);
 	return FALSE;
 	}
 
- myStatus->currConf = calloc(1, sizeof(struct emuConfig));
- if (!myStatus->currConf)
+ /* Verify endianess */
+ if (!myPlayer->currEng->verifyEndianess())
 	{
-	xs_sidplay1_close(myStatus);
+	XSERR("Endianess verification failed\n");
+	free(myPlayer);
 	return FALSE;
 	}
 
+ myStatus->player = myPlayer;
  return TRUE;
 }
 
 
 gboolean xs_sidplay1_initsong(t_xs_status *myStatus)
 {
- if ((!myStatus->currTune) || (!((sidTune *)myStatus->currTune)->getStatus())) return FALSE;
+ t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player;
+
+ if (!myPlayer) return FALSE;
+
+ if ((!myPlayer->currTune) || (!myPlayer->currTune->getStatus())) return FALSE;
 
  return sidEmuInitializeSong(
-	(emuEngine *) myStatus->currEngine,
-	(sidTune *) myStatus->currTune,
+	*myPlayer->currEng,
+	*myPlayer->currTune,
 	myStatus->currSong);
 }
 
 
-void xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, gint audioBufSize)
+gboolean xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, gint audioBufSize)
 {
+ t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player;
+
+ if (!myPlayer) return FALSE;
+
  sidEmuFillBuffer(
-	(emuEngine *) myStatus->currEngine,
-	(sidTune *) myStatus->currTune,
+	*myPlayer->currEng,
+	*myPlayer->currTune,
 	audioBuffer,
 	audioBufSize);
+
+ return TRUE;
 }
 
 
 gboolean xs_sidplay1_loadsid(t_xs_status *myStatus, gchar *pcFileName)
 {
+ t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player;
  sidTune *newTune;
  sidTuneInfo tuneInfo;
 
  /* Try to get the tune */
  if (!pcFileName) return FALSE;
  newTune = new sidTune(pcFileName);
- if (newTune == NULL) return FALSE;
+ if (!newTune) return FALSE;
 
  /* Get current configuration */
- myStatus->currEngine.getConfig(myStatus->currConf);
+ myPlayer->currEng->getConfig(myPlayer->currConfig);
 
  /* Configure channels and stuff */
  switch (xs_cfg.fmtChannels) {
 
 	case XS_CHN_AUTOPAN:
-		myStatus->currConf.channels = SIDEMU_STEREO;
-		myStatus->currConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING;
-		myStatus->currConf.volumeControl = SIDEMU_FULLPANNING;
+		myPlayer->currConfig.channels = SIDEMU_STEREO;
+		myPlayer->currConfig.autoPanning = SIDEMU_CENTEREDAUTOPANNING;
+		myPlayer->currConfig.volumeControl = SIDEMU_FULLPANNING;
 		break;
 
 	case XS_CHN_STEREO:
-		myStatus->currConf.channels = SIDEMU_STEREO;
-		myStatus->currConf.autoPanning = SIDEMU_NONE;
-		myStatus->currConf.volumeControl = SIDEMU_NONE;
+		myPlayer->currConfig.channels = SIDEMU_STEREO;
+		myPlayer->currConfig.autoPanning = SIDEMU_NONE;
+		myPlayer->currConfig.volumeControl = SIDEMU_NONE;
 		break;
 
 	case XS_CHN_MONO:
 	default:
-		myStatus->currConf.channels = SIDEMU_MONO;
-		myStatus->currConf.autoPanning = SIDEMU_NONE;
-		myStatus->currConf.volumeControl = SIDEMU_NONE;
+		myPlayer->currConfig.channels = SIDEMU_MONO;
+		myPlayer->currConfig.autoPanning = SIDEMU_NONE;
+		myPlayer->currConfig.volumeControl = SIDEMU_NONE;
 		break;
  }
 
@@ -128,19 +194,19 @@
  /* Memory mode settings */
  switch (xs_cfg.memoryMode) {
 	case XS_MPU_BANK_SWITCHING:
-		myStatus->currConf.memoryMode = MPU_BANK_SWITCHING;
+		myPlayer->currConfig.memoryMode = MPU_BANK_SWITCHING;
 		break;
 
 	case XS_MPU_TRANSPARENT_ROM:
-		myStatus->currConf.memoryMode = MPU_TRANSPARENT_ROM;
+		myPlayer->currConfig.memoryMode = MPU_TRANSPARENT_ROM;
 		break;
 
 	case XS_MPU_PLAYSID_ENVIRONMENT:
-		myStatus->currConf.memoryMode = MPU_PLAYSID_ENVIRONMENT;
+		myPlayer->currConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT;
 		break;
 
 	default:
-		myStatus->currConf.memoryMode = MPU_BANK_SWITCHING;
+		myPlayer->currConfig.memoryMode = MPU_BANK_SWITCHING;
 		break;
  }
 
@@ -148,46 +214,104 @@
  /* Clockspeed settings */
  switch (xs_cfg.clockSpeed) {
 	case XS_CLOCK_NTSC:
-		myStatus->currConf.clockSpeed = SIDTUNE_CLOCK_NTSC;
+		myPlayer->currConfig.clockSpeed = SIDTUNE_CLOCK_NTSC;
 		break;
 
 	case XS_CLOCK_PAL:
 	default:
-		myStatus->currConf.clockSpeed = SIDTUNE_CLOCK_PAL;
+		myPlayer->currConfig.clockSpeed = SIDTUNE_CLOCK_PAL;
 		break;
  }
 
 
  /* Configure rest of the emulation */
- myStatus->currConf.bitsPerSample	= xs_cfg.fmtBitsPerSample;
- myStatus->currConf.frequency		= xs_cfg.fmtFrequency;
+ myPlayer->currConfig.bitsPerSample	= xs_cfg.fmtBitsPerSample;
+ myPlayer->currConfig.frequency		= xs_cfg.fmtFrequency;
 #ifdef HAVE_UNSIGNEDPCM
- myStatus->currConf.sampleFormat	= SIDEMU_UNSIGNED_PCM;
+ myPlayer->currConfig.sampleFormat	= SIDEMU_UNSIGNED_PCM;
 #else
- myStatus->currConf.sampleFormat	= SIDEMU_SIGNED_PCM;
+ myPlayer->currConfig.sampleFormat	= SIDEMU_SIGNED_PCM;
 #endif
- myStatus->currConf.mos8580		= xs_cfg.mos8580;
- myStatus->currConf.emulateFilter	= xs_cfg.emulateFilters;
- myStatus->currConf.filterFs		= xs_cfg.filterFs;
- myStatus->currConf.filterFm		= xs_cfg.filterFm;
- myStatus->currConf.filterFt		= xs_cfg.filterFt;
+ myPlayer->currConfig.mos8580		= xs_cfg.mos8580;
+ myPlayer->currConfig.emulateFilter	= xs_cfg.emulateFilters;
+ myPlayer->currConfig.filterFs		= xs_cfg.filterFs;
+ myPlayer->currConfig.filterFm		= xs_cfg.filterFm;
+ myPlayer->currConfig.filterFt		= xs_cfg.filterFt;
 
  /* Now set the emulator configuration */
- myStatus->currEngine.setConfig(myStatus->currConf);
+ myPlayer->currEng->setConfig(myPlayer->currConfig);
 
  /* Initialize status information */
  newTune->getInfo(tuneInfo);
- if (!newTune) return FALSE;
 
  myStatus->isPlaying	= TRUE;
  myStatus->isError	= FALSE;
  myStatus->currSong	= tuneInfo.startSong;
  myStatus->nSongs	= tuneInfo.songs;
- myStatus->currTune	= newTune;
+ myPlayer->currTune	= newTune;
  myStatus->currFileName = g_strdup(pcFileName);
 
  return TRUE;
 }
 
 
+/*
+ * Delete tune
+ */
+void xs_sidplay1_deletesid(t_xs_status *myStatus)
+{
+ t_xs_sidplay1 *myPlayer;
+
+ if (!myStatus) return;
+
+ myPlayer = (t_xs_sidplay1 *) myStatus->player;
+ if (!myPlayer) return;
+
+ if (myPlayer->currTune)
+	delete myPlayer->currTune;
+}
+
+
+gint xs_sidplay1_gettunespeed(t_xs_status *myStatus)
+{
+ return 0;
+}
+
+/*
+ * Return song information
+ */
+#include "xs_sidplay_info.h"
+
+void xs_sidplay1_getsidinfo(gchar *songFileName, gchar **songTitle, gint *songLength)
+{
+ sidTuneInfo tuneInfo;
+ sidTune *testTune;
+ gint tmpInt;
+
+ /* Check if the tune exists and is readable */
+ testTune = new sidTune(songFileName);
+ if (!testTune) return;
+ if (!testTune->getStatus())
+	{
+	delete testTune;
+	return;
+	}
+
+ /* Get general tune information */
+ testTune->getInfo(tuneInfo);
+ delete testTune;
+
+ /* Get titlestring */
+ *songTitle = xs_make_filetitle(songFileName, &tuneInfo, tuneInfo.startSong);
+
+ /* Get song length (in milliseconds), negative if no known length */
+ tmpInt = xs_songlen_get(songFileName, tuneInfo.startSong);
+ if (tmpInt >= 0)
+	*songLength = (tmpInt * 1000);
+	else
+	*songLength = -1;
+}
+
+
+}	/* extern "C" */
 #endif	/* HAVE_SIDPLAY1 */