1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#include "DataGridWidget.hxx"
19#include "GuiObject.hxx"
20#include "Font.hxx"
21#include "OSystem.hxx"
22#include "Debugger.hxx"
23#include "TIADebug.hxx"
24#include "Widget.hxx"
25#include "Base.hxx"
26using Common::Base;
27
28#include "AudioWidget.hxx"
29
30// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
31AudioWidget::AudioWidget(GuiObject* boss, const GUI::Font& lfont,
32 const GUI::Font& nfont,
33 int x, int y, int w, int h)
34 : Widget(boss, lfont, x, y, w, h),
35 CommandSender(boss)
36{
37 const int fontWidth = lfont.getMaxCharWidth(),
38 fontHeight = lfont.getFontHeight(),
39 lineHeight = lfont.getLineHeight();
40 int xpos = 10, ypos = 25, lwidth = lfont.getStringWidth("AUDW ");
41
42 // AudF registers
43 new StaticTextWidget(boss, lfont, xpos, ypos+2,
44 lwidth, fontHeight,
45 "AUDF", TextAlign::Left);
46 xpos += lwidth;
47 myAudF = new DataGridWidget(boss, nfont, xpos, ypos,
48 2, 1, 2, 5, Common::Base::F_16);
49 myAudF->setTarget(this);
50 myAudF->setID(kAUDFID);
51 addFocusWidget(myAudF);
52
53 for(int col = 0; col < 2; ++col)
54 {
55 new StaticTextWidget(boss, lfont, xpos + col * myAudF->colWidth() + int(myAudF->colWidth() / 2.75),
56 ypos - lineHeight, fontWidth, fontHeight,
57 Common::Base::toString(col, Common::Base::F_16_1),
58 TextAlign::Left);
59 }
60
61 // AudC registers
62 xpos = 10; ypos += lineHeight + 5;
63 new StaticTextWidget(boss, lfont, xpos, ypos+2, lwidth, fontHeight,
64 "AUDC", TextAlign::Left);
65 xpos += lwidth;
66 myAudC = new DataGridWidget(boss, nfont, xpos + int(myAudF->colWidth() / 2.75), ypos,
67 2, 1, 1, 4, Common::Base::F_16_1);
68 myAudC->setTarget(this);
69 myAudC->setID(kAUDCID);
70 addFocusWidget(myAudC);
71
72 // AudV registers
73 xpos = 10; ypos += lineHeight + 5;
74 new StaticTextWidget(boss, lfont, xpos, ypos+2, lwidth, fontHeight,
75 "AUDV", TextAlign::Left);
76 xpos += lwidth;
77 myAudV = new DataGridWidget(boss, nfont, xpos + int(myAudF->colWidth() / 2.75), ypos,
78 2, 1, 1, 4, Common::Base::F_16_1);
79 myAudV->setTarget(this);
80 myAudV->setID(kAUDVID);
81 addFocusWidget(myAudV);
82
83 myAudEffV = new StaticTextWidget(boss, lfont, myAudV->getRight() + fontWidth, myAudV->getTop() + 2,
84 "100% (eff. volume)");
85}
86
87// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
88void AudioWidget::loadConfig()
89{
90 IntArray alist;
91 IntArray vlist;
92 BoolArray blist, changed, grNew, grOld;
93
94 Debugger& dbg = instance().debugger();
95 TIADebug& tia = dbg.tiaDebug();
96 const TiaState& state = static_cast<const TiaState&>(tia.getState());
97 const TiaState& oldstate = static_cast<const TiaState&>(tia.getOldState());
98
99 // AUDF0/1
100 alist.clear(); vlist.clear(); changed.clear();
101 for(uInt32 i = 0; i < 2; ++i)
102 {
103 alist.push_back(i);
104 vlist.push_back(state.aud[i]);
105 changed.push_back(state.aud[i] != oldstate.aud[i]);
106 }
107 myAudF->setList(alist, vlist, changed);
108
109 // AUDC0/1
110 alist.clear(); vlist.clear(); changed.clear();
111 for(uInt32 i = 2; i < 4; ++i)
112 {
113 alist.push_back(i-2);
114 vlist.push_back(state.aud[i]);
115 changed.push_back(state.aud[i] != oldstate.aud[i]);
116 }
117 myAudC->setList(alist, vlist, changed);
118
119 // AUDV0/1
120 alist.clear(); vlist.clear(); changed.clear();
121 for(uInt32 i = 4; i < 6; ++i)
122 {
123 alist.push_back(i-4);
124 vlist.push_back(state.aud[i]);
125 changed.push_back(state.aud[i] != oldstate.aud[i]);
126 }
127 myAudV->setList(alist, vlist, changed);
128
129 handleVolume();
130}
131
132// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
133void AudioWidget::handleVolume()
134{
135 stringstream s;
136
137 s << getEffectiveVolume() << "% (eff. volume)";
138 myAudEffV->setLabel(s.str());
139}
140
141// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
142void AudioWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
143{
144 switch(cmd)
145 {
146 case DataGridWidget::kItemDataChangedCmd:
147 switch(id)
148 {
149 case kAUDFID:
150 changeFrequencyRegs();
151 break;
152
153 case kAUDCID:
154 changeControlRegs();
155 break;
156
157 case kAUDVID:
158 changeVolumeRegs();
159 break;
160
161 default:
162 cerr << "AudioWidget DG changed\n";
163 break;
164 }
165 break;
166 }
167}
168
169// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
170void AudioWidget::changeFrequencyRegs()
171{
172 int addr = myAudF->getSelectedAddr();
173 int value = myAudF->getSelectedValue();
174
175 switch(addr)
176 {
177 case kAud0Addr:
178 instance().debugger().tiaDebug().audF0(value);
179 break;
180
181 case kAud1Addr:
182 instance().debugger().tiaDebug().audF1(value);
183 break;
184 }
185}
186
187// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
188void AudioWidget::changeControlRegs()
189{
190 int addr = myAudC->getSelectedAddr();
191 int value = myAudC->getSelectedValue();
192
193 switch(addr)
194 {
195 case kAud0Addr:
196 instance().debugger().tiaDebug().audC0(value);
197 break;
198
199 case kAud1Addr:
200 instance().debugger().tiaDebug().audC1(value);
201 break;
202 }
203 handleVolume();
204}
205
206// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
207void AudioWidget::changeVolumeRegs()
208{
209 int addr = myAudV->getSelectedAddr();
210 int value = myAudV->getSelectedValue();
211
212 switch(addr)
213 {
214 case kAud0Addr:
215 instance().debugger().tiaDebug().audV0(value);
216 break;
217
218 case kAud1Addr:
219 instance().debugger().tiaDebug().audV1(value);
220 break;
221 }
222 handleVolume();
223}
224
225// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
226uInt32 AudioWidget::getEffectiveVolume()
227{
228 const int EFF_VOL[] = {
229 0, 6, 13, 18, 24, 29, 33, 38,
230 42, 46, 50, 54, 57, 60, 64, 67,
231 70, 72, 75, 78, 80, 82, 85, 87,
232 89, 91, 93, 95, 97, 98,100};
233
234 return EFF_VOL[(instance().debugger().tiaDebug().audC0() ? instance().debugger().tiaDebug().audV0() : 0) +
235 (instance().debugger().tiaDebug().audC1() ? instance().debugger().tiaDebug().audV1() : 0)];
236}
237