ScummVM API documentation
c64.music.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef FREESCAPE_DARK_C64_MUSIC_H
23 #define FREESCAPE_DARK_C64_MUSIC_H
24 
25 #include "audio/sid.h"
26 #include "freescape/music.h"
27 
28 namespace Freescape {
29 
30 // 3-channel SID music player for Dark Side C64.
31 // Implements the Wally Beben byte-stream sequencer from darkside.prg ($0901).
33 public:
36 
37  void startMusic() override;
38  void stopMusic() override;
39  bool isPlaying() const override;
40 
41 private:
42  SID::SID *_sid;
43 
44  void sidWrite(int reg, uint8 data);
45  void onTimer();
46 
47  // Song setup
48  void setupSong();
49  void silenceAll();
50  void loadNextPattern(int ch);
51  void buildEffectArpeggio(int ch);
52  void loadCurrentFrequency(int ch);
53  void finalizeChannel(int ch);
54 
55  // Per-tick processing
56  void processChannel(int ch, bool newBeat);
57  void parseCommands(int ch);
58  void applyNote(int ch, uint8 note);
59  void applyFrameEffects(int ch);
60  bool applySpecialAttack(int ch);
61  bool applyEnvelopeSequence(int ch);
62  bool applyInstrumentVibrato(int ch);
63  void applyEffectArpeggio(int ch);
64  void applyTimedSlide(int ch);
65  void applyPWModulation(int ch);
66 
67  uint8 readPatByte(int ch);
68 
69  void initSID();
70  void destroySID();
71 
72  // Global state
73  bool _musicActive;
74  uint8 _speedDiv; // $15A1: speed divider
75  uint8 _speedCounter; // $15A2: frames until next beat
76 
77  // Per-channel state
78  struct ChannelState {
79  const uint8 *orderData;
80  uint8 orderPos; // $15A3
81 
82  const uint8 *patData;
83  int patOffset;
84 
85  uint8 instIdx; // $15F6: instrument# * 8
86  uint8 curNote; // $159C: note index (with transpose)
87  uint8 transpose; // $15C4
88 
89  uint8 freqLo; // $15A6
90  uint8 freqHi; // $15A9
91  uint8 pwLo; // $15AC
92  uint8 pwHi; // $15AF
93 
94  uint8 durReload; // $15B8
95  uint8 durCounter; // $15BB
96 
97  uint8 effectMode; // $15BE: mode 2 keeps effectParam alive across note loads
98  uint8 effectParam; // $15C1
99 
100  uint8 arpPattern; // $15C7
101  uint8 arpParam2; // $15CA
102  uint8 arpSeqPos; // $15D9
103  uint8 arpSeqData[20]; // $160C
104  uint8 arpSeqLen;
105 
106  uint8 noteStepCommand; // $15D0: self-modified INC/DEC opcode for beat step
107  uint8 stepDownCounter; // $15D3: short downward slide counter
108 
109  uint8 vibPhase; // $15DE
110  uint8 vibCounter; // $15E1
111 
112  uint8 pwDirection; // $15D6: 0=up, 1=down
113 
114  uint8 delayValue; // $15E4
115  uint8 delayCounter; // $15E7
116 
117  uint8 envCounter; // $15FC
118  bool gateOffDisabled; // $1606: set when SR release nibble is $F
119  bool gateModeControl; // $1600: flags bit 7
120  bool specialAttack; // flags bit 3
121  bool attackDone; // $1603
122  uint8 waveform; // current instrument ctrl byte
123  uint8 instFlags; // current instrument flags byte
124 
125  void reset();
126  };
127 
128  ChannelState _ch[3];
129 };
130 
131 } // namespace Freescape
132 
133 #endif // FREESCAPE_DARK_C64_MUSIC_H
Definition: area.h:36
Definition: sid.h:44
Definition: c64.music.h:32
Definition: music.h:29