1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2021 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 
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;
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 
67     /// Mixer
68     Mixer m_mixer;
69 
70     /// Emulator info
71     SidTune *m_tune;
72 
73     /// User Configuration Settings
74     SidInfoImpl m_info;
75 
76     /// User Configuration Settings
77     SidConfig m_cfg;
78 
79     /// Error message
80     const char *m_errorString;
81 
82     volatile state_t m_isPlaying;
83 
84     sidrandom m_rand;
85 
86     /// PAL/NTSC switch value
87     uint8_t videoSwitch;
88 
89 private:
90     /**
91      * Get the C64 model for the current loaded tune.
92      *
93      * @param defaultModel the default model
94      * @param forced true if the default model shold be forced in spite of tune model
95      */
96     c64::model_t c64model(SidConfig::c64_model_t defaultModel, bool forced);
97 
98     /**
99      * Initialize the emulation.
100      *
101      * @throw configError
102      */
103     void initialise();
104 
105     /**
106      * Release the SID builders.
107      */
108     void sidRelease();
109 
110     /**
111      * Create the SID emulation(s).
112      *
113      * @throw configError
114      */
115     void sidCreate(sidbuilder *builder, SidConfig::sid_model_t defaultModel, bool digiboost,
116                     bool forced, const std::vector<unsigned int> &extraSidAddresses);
117 
118     /**
119      * Set the SID emulation parameters.
120      *
121      * @param cpuFreq the CPU clock frequency
122      * @param frequency the output sampling frequency
123      * @param sampling the sampling method to use
124      * @param fastSampling true to enable fast low quality resampling (only for reSID)
125      */
126     void sidParams(double cpuFreq, int frequency,
127                     SidConfig::sampling_method_t sampling, bool fastSampling);
128 
129     inline void run(unsigned int events);
130 
131 public:
132     Player();
~Player()133     ~Player() {}
134 
config()135     const SidConfig &config() const { return m_cfg; }
136 
info()137     const SidInfo &info() const { return m_info; }
138 
139     bool config(const SidConfig &cfg, bool force=false);
140 
141     bool fastForward(unsigned int percent);
142 
143     bool load(SidTune *tune);
144 
145     uint_least32_t play(short *buffer, uint_least32_t samples);
146 
isPlaying()147     bool isPlaying() const { return m_isPlaying != STOPPED; }
148 
149     void stop();
150 
time()151     uint_least32_t time() const { return m_c64.getTime(); }
152 
timeMs()153     uint_least32_t timeMs() const { return m_c64.getTimeMs(); }
154 
debug(const bool enable,FILE * out)155     void debug(const bool enable, FILE *out) { m_c64.debug(enable, out); }
156 
157     void mute(unsigned int sidNum, unsigned int voice, bool enable);
158 
error()159     const char *error() const { return m_errorString; }
160 
161     void setKernal(const uint8_t* rom);
162     void setBasic(const uint8_t* rom);
163     void setChargen(const uint8_t* rom);
164 
getCia1TimerA()165     uint_least16_t getCia1TimerA() const { return m_c64.getCia1TimerA(); }
166 
167     bool getSidStatus(unsigned int sidNum, uint8_t regs[32]);
168 };
169 
170 }
171 
172 #endif // PLAYER_H
173