1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2019 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2007-2010 Antti Lankila
6  * Copyright 2000-2001 Simon White
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22 
23 
24 #ifndef PLAYER_H
25 #define PLAYER_H
26 
next_char(FILE * infile)27 #include <stdint.h>
28 #include <cstdio>
29 
30 #include "sidplayfp/siddefs.h"
31 #include "sidplayfp/SidConfig.h"
32 #include "sidplayfp/SidTuneInfo.h"
33 
34 #include "SidInfoImpl.h"
35 #include "sidrandom.h"
36 #include "mixer.h"
37 #include "c64/c64.h"
38 
39 #ifdef HAVE_CONFIG_H
40 #  include "config.h"
41 #endif
42 
43 #include <vector>
44 
45 class SidTune;
46 class SidInfo;
47 class sidbuilder;
grecs_path_parser(const char * name,int traceflags)48 
49 
50 namespace libsidplayfp
51 {
52 
53 class Player
54 {
55 private:
56     typedef enum
57     {
58         STOPPED,
59         PLAYING,
60         STOPPING
61     } state_t;
62 
63 private:
64     /// Commodore 64 emulator
65     c64 m_c64;
66     c64::model_t m_model;
67 
68     std::vector<SidConfig::sid_model_t> m_sidModels;
69     std::vector<unsigned int> m_sidAddresses;
70 
71     /// Mixer
72     Mixer m_mixer;
73 
74     /// Emulator info
75     SidTune *m_tune;
76 
77     /// User Configuration Settings
78     SidInfoImpl m_info;
79 
80     /// User Configuration Settings
81     SidConfig m_cfg;
82 
83     /// Error message
84     const char *m_errorString;
85 
86     volatile state_t m_isPlaying;
87 
88     sidrandom m_rand;
89 
90     /// PAL/NTSC switch value
91     uint8_t videoSwitch;
92 
93 private:
94     /**
95      * Get the C64 model for the current loaded tune.
96      *
97      * @param defaultModel the default model
98      * @param forced true if the default model shold be forced in spite of tune model
99      */
100     c64::model_t c64model(SidConfig::c64_model_t defaultModel, bool forced);
101 
102     /**
103      * Initialize the emulation.
104      *
105      * @throw configError
106      */
107     void initialise();
108 
109     /**
110      * Release the SID builders.
111      */
112     void sidRelease();
113 
114     /**
115      * Create the SID emulation(s).
116      *
117      * @throw configError
118      */
119     void sidCreate(sidbuilder *builder, SidConfig::sid_model_t defaultModel, bool digiboost,
120                     bool forced, const std::vector<unsigned int> &extraSidAddresses);
121 
122     /**
123      * Set the SID emulation parameters.
124      *
125      * @param cpuFreq the CPU clock frequency
126      * @param frequency the output sampling frequency
127      * @param sampling the sampling method to use
128      * @param fastSampling true to enable fast low quality resampling (only for reSID)
129      */
130     void sidParams(double cpuFreq, int frequency,
131                     SidConfig::sampling_method_t sampling, bool fastSampling);
132 
133     inline void run(unsigned int events);
134 
135 public:
136     Player();
137     ~Player() {}
138 
139     const SidConfig &config() const { return m_cfg; }
140 
141     const SidInfo &info() const { return m_info; }
142 
143     c64::model_t getModel () const { return m_model; }
144 
145     unsigned int getSidCount () const { return m_sidModels.size(); }
146     SidConfig::sid_model_t getSidModel (unsigned int i) const { return m_sidModels[i]; }
147     unsigned int getSidAddress (unsigned int i) const { return m_sidAddresses[i]; }
148 
149     double getMainCpuSpeed () const { return m_c64.getMainCpuSpeed(); }
150 
151     bool config(const SidConfig &cfg, bool force=false);
152 
153     bool fastForward(unsigned int percent);
154 
155     bool load(SidTune *tune);
156 
157     uint_least32_t play(int16_t *buffer, uint_least32_t samples, std::vector<int16_t*> *rawBuffers = nullptr);
158 
159     bool isPlaying() const { return m_isPlaying != STOPPED; }
160 
161     void stop();
162 
163     uint_least32_t time() const { return m_c64.getTime(); }
164 
165     uint_least32_t timeMs() const { return m_c64.getTimeMs(); }
166 
167     void debug(const bool enable, FILE *out) { m_c64.debug(enable, out); }
168 
169     void mute(unsigned int sidNum, unsigned int voice, bool enable);
170 
171     bool getSidStatus(unsigned int sidNum, uint8_t& gatestoggle, uint8_t& syncstoggle, uint8_t& teststoggle, uint8_t **registers, uint8_t &volume_a, uint8_t &volume_b, uint8_t &volume_c);
172 
173     const char *error() const { return m_errorString; }
174 
175     void setRoms(const uint8_t* kernal, const uint8_t* basic, const uint8_t* character);
176 
177     uint_least16_t getCia1TimerA() const { return m_c64.getCia1TimerA(); }
178 };
179 
180 }
181 
182 #endif // PLAYER_H
183