/* * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "EmuWrapper.h" #include "SidTuneMod.h" #include "emucfg.h" QString EmuWrapper::versionString; int EmuWrapper::engines = 0; QMutex EmuWrapper::emuMutex; #ifdef SID_WITH_SIDPLAY2 sidplay2* EmuWrapper::pEmuEngine = 0; ReSIDBuilder* EmuWrapper::pEmuSid = 0; sid2_config_t EmuWrapper::sid2_cfg; #else emuEngine* EmuWrapper::pEmuEngine = 0; #endif emuConfig EmuWrapper::myEmuConfig; emuConfig EmuWrapper::myEmuConfigDefault; EmuWrapper::EmuWrapper() { if ( engines==0 && pEmuEngine==0 ) { #ifdef SID_WITH_SIDPLAY2 pEmuEngine = new sidplay2; pEmuSid = new ReSIDBuilder("XSIDPLAY reSID"); sid2_cfg = pEmuEngine->config(); sid2_cfg.sidSamples = false; myEmuConfig.emulateFilter = true; if (*pEmuSid) // TODO: nothrow above { // Builder initialisation ok. pEmuSid->create( (pEmuEngine->info()).maxsids ); sid2_cfg.sidEmulation = pEmuSid; pEmuEngine->config(sid2_cfg); } myEmuConfigDefault = getConfig (); #else pEmuEngine = new emuEngine; pEmuEngine->getConfig(myEmuConfigDefault); myEmuConfig = myEmuConfigDefault; #endif ++engines; } } EmuWrapper::~EmuWrapper() { if ( --engines==0 ) { #ifdef SID_WITH_SIDPLAY2 delete pEmuSid; #endif delete pEmuEngine; } } void EmuWrapper::initSong(SidTuneMod* pSidTune, int song) { emuMutex.lock(); #ifdef SID_WITH_SIDPLAY2 pSidTune->selectSong(song); pEmuEngine->load(pSidTune); #else sidEmuInitializeSong(*pEmuEngine,*pSidTune,song); #endif emuMutex.unlock(); } void EmuWrapper::setConfig(const emuConfig& inConfig) { emuMutex.lock(); #ifdef SID_WITH_SIDPLAY2 // Convert config for sidplay2. sid2_cfg.frequency = (uint_least32_t) inConfig.frequency; sid2_cfg.precision = inConfig.bitsPerSample; sid2_cfg.playback = sid2_mono; if (inConfig.channels == SIDEMU_STEREO) sid2_cfg.playback = sid2_stereo; sid2_cfg.sidModel = SID2_MODEL_CORRECT; if ( inConfig.mos8580 ) sid2_cfg.sidDefault = SID2_MOS8580; else sid2_cfg.sidDefault = SID2_MOS6581; if ( inConfig.forceSidModel ) sid2_cfg.sidModel = sid2_cfg.sidDefault; sid2_cfg.sidSamples = true; sid2_cfg.clockSpeed = SID2_CLOCK_CORRECT; if (inConfig.clockSpeed == SIDTUNE_CLOCK_NTSC) sid2_cfg.clockDefault = SID2_CLOCK_NTSC; else sid2_cfg.clockDefault = SID2_CLOCK_PAL; if ( sid2_cfg.clockForced = inConfig.forceSongSpeed ) sid2_cfg.clockSpeed = sid2_cfg.clockDefault; switch (inConfig.memoryMode) { case MPU_PLAYSID_ENVIRONMENT: sid2_cfg.environment = sid2_envPS; break; case MPU_TRANSPARENT_ROM: sid2_cfg.environment = sid2_envTP; break; case MPU_BANK_SWITCHING: default: sid2_cfg.environment = sid2_envBS; break; } pEmuSid->sampling (sid2_cfg.frequency); pEmuSid->filter (inConfig.emulateFilter); pEmuEngine->config(sid2_cfg); sid2_cfg = pEmuEngine->config(); #else myEmuConfig = inConfig; pEmuEngine->setConfig(myEmuConfig); pEmuEngine->getConfig(myEmuConfig); #endif emuMutex.unlock(); } const emuConfig& EmuWrapper::getConfig() { emuMutex.lock(); #ifdef SID_WITH_SIDPLAY2 // Convert config to sidplay1. sid2_cfg = pEmuEngine->config(); myEmuConfig.frequency = (int) sid2_cfg.frequency; myEmuConfig.bitsPerSample = sid2_cfg.precision; myEmuConfig.sampleFormat = SIDEMU_SIGNED_PCM; if (sid2_cfg.precision == 8) myEmuConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; myEmuConfig.channels = SIDEMU_MONO; if (sid2_cfg.playback == sid2_stereo) myEmuConfig.channels = SIDEMU_STEREO; myEmuConfig.mos8580 = ( sid2_cfg.sidDefault == SID2_MOS8580 ); myEmuConfig.forceSidModel = ( sid2_cfg.sidModel != SID2_MODEL_CORRECT ); myEmuConfig.clockSpeed = SIDTUNE_CLOCK_PAL; if (sid2_cfg.clockDefault == SID2_CLOCK_NTSC) myEmuConfig.clockSpeed = SIDTUNE_CLOCK_NTSC; myEmuConfig.forceSongSpeed = sid2_cfg.clockForced; switch (sid2_cfg.environment) { case sid2_envPS: myEmuConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT; break; case sid2_envTP: myEmuConfig.memoryMode = MPU_TRANSPARENT_ROM; break; case sid2_envBS: case sid2_envR: default: myEmuConfig.memoryMode = MPU_BANK_SWITCHING; break; } #else pEmuEngine->getConfig(myEmuConfig); #endif emuMutex.unlock(); return myEmuConfig; } const emuConfig& EmuWrapper::getConfigDefault() { return myEmuConfigDefault; } void EmuWrapper::resetSecondsThisSong() { #ifndef SID_WITH_SIDPLAY2 emuMutex.lock(); pEmuEngine->resetSecondsThisSong(); emuMutex.unlock(); #endif } int EmuWrapper::getSecondsThisSong() { emuMutex.lock(); #ifdef SID_WITH_SIDPLAY2 int secs = pEmuEngine->time() / 10; #else int secs = pEmuEngine->getSecondsThisSong(); #endif emuMutex.unlock(); return secs; } int EmuWrapper::getSecondsTotal() { emuMutex.lock(); #ifdef SID_WITH_SIDPLAY2 int secs = pEmuEngine->mileage(); #else int secs = pEmuEngine->getSecondsTotal(); #endif emuMutex.unlock(); return secs; } const char* EmuWrapper::getVersionString() { #ifdef SID_WITH_SIDPLAY2 emuMutex.lock(); sid2_info_t info; info = pEmuEngine->info(); emuMutex.unlock(); versionString = "SID player library Version "; versionString += info.version; versionString += "\nby Simon White \n"; versionString += "http://sidplay2.sourceforge.net\n\n"; versionString += "reSID engine by Dag Lem "; #else versionString = "SID player library Version "; versionString += pEmuEngine->getVersionString(); versionString += "\nhttp://www.geocities.com/SiliconValley/Lakes/5147/sidplay/"; #endif return versionString; } #ifdef SID_WITH_SIDPLAY2 const char* EmuWrapper::getSpeedString() { emuMutex.lock(); sid2_info_t info = pEmuEngine->info(); emuMutex.unlock(); return info.tuneInfo->speedString; } const char* EmuWrapper::getSidModelString() { emuMutex.lock(); sid2_info_t info = pEmuEngine->info(); emuMutex.unlock(); if ( info.tuneInfo->sidModel == SID2_MOS8580 ) return "MOS 8580"; else return "MOS 6581"; } #endif void EmuWrapper::stop() { #ifdef SID_WITH_SIDPLAY2 emuMutex.lock(); pEmuEngine->stop(); emuMutex.unlock(); #endif } void EmuWrapper::fillBuffer(SidTuneMod* pSidTune, ubyte_emuwt* pBuffer, udword_emuwt bufferSize) { emuMutex.lock(); #ifdef SID_WITH_SIDPLAY2 pEmuEngine->play(pBuffer,bufferSize); #else sidEmuFillBuffer(*pEmuEngine,*pSidTune,pBuffer,bufferSize); #endif emuMutex.unlock(); } void EmuWrapper::setVoiceVolume(int voice, ubyte_emuwt left, ubyte_emuwt right, uword_emuwt total) { #ifndef SID_WITH_SIDPLAY2 emuMutex.lock(); pEmuEngine->setVoiceVolume(voice,left,right,total); emuMutex.unlock(); #endif }