1  /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2012-2021 Leandro Nini <drfiemost@users.sourceforge.net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 
21 #include "SidTune.h"
22 
23 #include "sidtune/SidTuneBase.h"
24 
25 #include "sidcxx11.h"
26 
27 using namespace libsidplayfp;
28 
29 const char MSG_NO_ERRORS[] = "No errors";
30 
31 // Default sidtune file name extensions. This selection can be overriden
32 // by specifying a custom list in the constructor.
33 const char* defaultFileNameExt[] =
34 {
35     // Preferred default file extension for single-file sidtunes
36     // or sidtune description files in SIDPLAY INFOFILE format.
37     ".sid", ".SID",
38     // File extensions used (and created) by various C64 emulators and
39     // related utilities. These extensions are recommended to be used as
40     // a replacement for ".dat" in conjunction with two-file sidtunes.
41     ".c64", ".prg", ".p00", ".C64", ".PRG", ".P00",
42     // Stereo Sidplayer (.mus/.MUS ought not be included because
43     // these must be loaded first; it sometimes contains the first
44     // credit lines of a MUS/STR pair).
45     ".str", ".STR", ".mus", ".MUS",
46     // End.
47     0
48 };
49 
50 const char** SidTune::fileNameExtensions = defaultFileNameExt;
51 
SidTune(const char * fileName,const char ** fileNameExt,bool separatorIsSlash)52 SidTune::SidTune(const char* fileName, const char **fileNameExt, bool separatorIsSlash) :
53     SidTune(nullptr, fileName, fileNameExt, separatorIsSlash)
54 {
55 }
56 
SidTune(LoaderFunc loader,const char * fileName,const char ** fileNameExt,bool separatorIsSlash)57 SidTune::SidTune(LoaderFunc loader, const char* fileName, const char **fileNameExt, bool separatorIsSlash) :
58     tune(nullptr)
59 {
60     setFileNameExtensions(fileNameExt);
61     load(loader, fileName, separatorIsSlash);
62 }
63 
SidTune(const uint_least8_t * oneFileFormatSidtune,uint_least32_t sidtuneLength)64 SidTune::SidTune(const uint_least8_t* oneFileFormatSidtune, uint_least32_t sidtuneLength) :
65     tune(nullptr)
66 {
67     read(oneFileFormatSidtune, sidtuneLength);
68 }
69 
~SidTune()70 SidTune::~SidTune()
71 {
72     delete tune;
73 }
74 
setFileNameExtensions(const char ** fileNameExt)75 void SidTune::setFileNameExtensions(const char **fileNameExt)
76 {
77     fileNameExtensions = ((fileNameExt != nullptr) ? fileNameExt : defaultFileNameExt);
78 }
79 
load(const char * fileName,bool separatorIsSlash)80 void SidTune::load(const char* fileName, bool separatorIsSlash)
81 {
82     load(nullptr, fileName, separatorIsSlash);
83 }
84 
load(LoaderFunc loader,const char * fileName,bool separatorIsSlash)85 void SidTune::load(LoaderFunc loader, const char* fileName, bool separatorIsSlash)
86 {
87     try
88     {
89         delete tune;
90         tune = SidTuneBase::load(loader, fileName, fileNameExtensions, separatorIsSlash);
91         m_status = true;
92         m_statusString = MSG_NO_ERRORS;
93     }
94     catch (loadError const &e)
95     {
96         tune =  nullptr;
97         m_status = false;
98         m_statusString = e.message();
99     }
100 }
101 
read(const uint_least8_t * sourceBuffer,uint_least32_t bufferLen)102 void SidTune::read(const uint_least8_t* sourceBuffer, uint_least32_t bufferLen)
103 {
104     try
105     {
106         delete tune;
107         tune = SidTuneBase::read(sourceBuffer, bufferLen);
108         m_status = true;
109         m_statusString = MSG_NO_ERRORS;
110     }
111     catch (loadError const &e)
112     {
113         tune =  nullptr;
114         m_status = false;
115         m_statusString = e.message();
116     }
117 }
118 
selectSong(unsigned int songNum)119 unsigned int SidTune::selectSong(unsigned int songNum)
120 {
121     return tune != nullptr ? tune->selectSong(songNum) : 0;
122 }
123 
getInfo() const124 const SidTuneInfo* SidTune::getInfo() const
125 {
126     return tune != nullptr ? tune->getInfo() : nullptr;
127 }
128 
getInfo(unsigned int songNum)129 const SidTuneInfo* SidTune::getInfo(unsigned int songNum)
130 {
131     return tune != nullptr ? tune->getInfo(songNum) : nullptr;
132 }
133 
getStatus() const134 bool SidTune::getStatus() const { return m_status; }
135 
statusString() const136 const char* SidTune::statusString() const { return m_statusString; }
137 
placeSidTuneInC64mem(sidmemory & mem)138 bool SidTune::placeSidTuneInC64mem(sidmemory& mem)
139 {
140     if (tune == nullptr)
141         return false;
142 
143     tune->placeSidTuneInC64mem(mem);
144     return true;
145 }
146 
createMD5(char * md5)147 const char* SidTune::createMD5(char *md5)
148 {
149     return tune != nullptr ? tune->createMD5(md5) : nullptr;
150 }
151 
createMD5New(char * md5)152 const char* SidTune::createMD5New(char *md5)
153 {
154     return tune != nullptr ? tune->createMD5New(md5) : nullptr;
155 }
156 
c64Data() const157 const uint_least8_t* SidTune::c64Data() const
158 {
159     return tune != nullptr ? tune->c64Data() : nullptr;
160 }
161