view src/xs_sidplay.h @ 744:c7fa50576c70

Initial implementation for supporting libSIDPlay2-FP (or libSIDPlay-FP, as they seem to call it.) Also removed support for the "old" libSIDPlay2 API, only supporting the "new" CVS trunk COMI API for the old libSIDPlay2. We'll see how that goes ..
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 05 Nov 2012 17:24:16 +0200
parents 9321ffa2ea7e
children 55eea3fa8868
line wrap: on
line source

/*
   XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)

   libSIDPlay skeleton functions used both by v1 and 2 of the backends

   Programmed and designed by Matti 'ccr' Hamalainen <ccr@tnsp.org>
   (C) Copyright 2005-2009 Tecnic Software productions (TNSP)

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/


/* This function gets most of the information, though we do miss some
 * (those variables that are only set by libSIDPlay when tune is initialized).
 * Rest of the information is acquired in TFUNCTION2()
 */
xs_tuneinfo_t *TFUNCTION(const gchar *sidFilename)
{
    xs_tuneinfo_t *pResult;
    TTUNEINFO myInfo;
    TTUNE *myTune;
    guint8 *buf = NULL;
    size_t bufSize = 0;

    /* Load file */
    if (!sidFilename) return NULL;

    if (xs_fload_buffer(sidFilename, &buf, &bufSize) != 0)
        return NULL;
    
    /* Check if the tune exists and is readable */
    if ((myTune = new TTUNE(buf, bufSize)) == NULL) {
        g_free(buf);
        return NULL;
    }
    g_free(buf);

    if (!myTune->getStatus()) {
        delete myTune;
        return NULL;
    }

    /* Get general tune information */
#ifdef XS_SIDPLAY1_H
    myTune->getInfo(myInfo);
#endif
#ifdef XS_SIDPLAY2_H
    myInfo = myTune->getInfo();
#endif

    /* Allocate tuneinfo structure and set information */
    pResult = xs_tuneinfo_new(sidFilename,
        myInfo.songs, myInfo.startSong,
        myInfo.infoString[0], myInfo.infoString[1], myInfo.infoString[2],
        myInfo.loadAddr, myInfo.initAddr, myInfo.playAddr,
        myInfo.dataFileLen, myInfo.formatString,
#if defined(XS_SIDPLAY2_H) && defined(HAVE_SIDPLAY2_FP)
        myInfo.sidModel1
#else
        myInfo.sidModel
#endif
        );
    
    /* NOTICE! libSIDPlay[12] headers specifically state that sidModel,
     * songSpeed and clockSpeed are "undefined" before song initialization,
     * but in practice sidModel is known after getInfo() invocation...
     * This of course does not take the sub-tune specific changes into account,
     * but at least we have a reasonable guesstimate.
     */

    delete myTune;

    return pResult;
}


/* Updates the information of currently playing tune
 */
gboolean TFUNCTION2(xs_status_t *myStatus)
{
    TTUNEINFO myInfo;
    TTUNE *myTune;
    TENGINE *myEngine;
    xs_tuneinfo_t *i;
    
    /* Check if we have required structures initialized */
    if (!myStatus || !myStatus->tuneInfo || !myStatus->sidEngine)
        return FALSE;

    myEngine = (TENGINE *) myStatus->sidEngine;
    myTune = myEngine->currTune;
    if (!myTune)
        return FALSE;

    /* Get currently playing tune information */
#ifdef XS_SIDPLAY1_H
    myTune->getInfo(myInfo);
#endif
#ifdef XS_SIDPLAY2_H
    myInfo = myTune->getInfo();
#endif

    /* NOTICE! Here we assume that libSIDPlay[12] headers define
     * SIDTUNE_SIDMODEL_* similarly to our enums in xs_config.h ...
     */
    i = myStatus->tuneInfo;
#if defined(XS_SIDPLAY2_H) && defined(HAVE_SIDPLAY2_FP)
    i->sidModel = myInfo.sidModel1;
#else
    i->sidModel = myInfo.sidModel;
#endif

    if ((myStatus->currSong > 0) && (myStatus->currSong <= i->nsubTunes)) {
        gint tmpSpeed = -1;
        
        switch (myInfo.clockSpeed) {
        case SIDTUNE_CLOCK_PAL:
            tmpSpeed = XS_CLOCK_PAL;
            break;
        case SIDTUNE_CLOCK_NTSC:
            tmpSpeed = XS_CLOCK_NTSC;
            break;
        case SIDTUNE_CLOCK_ANY:
            tmpSpeed = XS_CLOCK_ANY;
            break;
        case SIDTUNE_CLOCK_UNKNOWN:
            switch (myInfo.songSpeed) {
            case SIDTUNE_SPEED_VBI:
                tmpSpeed = XS_CLOCK_VBI;
                break;
            case SIDTUNE_SPEED_CIA_1A:
                tmpSpeed = XS_CLOCK_CIA;
                break;
            default:
                tmpSpeed = myInfo.songSpeed;
                break;
            }
        default:
            tmpSpeed = myInfo.clockSpeed;
            break;
        }
            
        i->subTunes[myStatus->currSong - 1].tuneSpeed = tmpSpeed;
    }

    return TRUE;
}

/* Undefine these */
#undef TFUNCTION
#undef TFUNCTION2
#undef TTUNEINFO
#undef TTUNE