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-2021 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 "BoosterWidget.hxx"
19 
20 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BoosterWidget(GuiObject * boss,const GUI::Font & font,int x,int y,Controller & controller)21 BoosterWidget::BoosterWidget(GuiObject* boss, const GUI::Font& font,
22                              int x, int y, Controller& controller)
23   : ControllerWidget(boss, font, x, y, controller)
24 {
25   const string& label = isLeftPort() ? "Left (Booster)" : "Right (Booster)";
26 
27   const int fontHeight = font.getFontHeight();
28   int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Booster)");
29   StaticTextWidget* t;
30 
31   t = new StaticTextWidget(boss, font, xpos, ypos+2, lwidth,
32                            fontHeight, label, TextAlign::Left);
33   xpos += t->getWidth()/2 - 5;  ypos += t->getHeight() + 10;
34   myPins[kJUp] = new CheckboxWidget(boss, font, xpos, ypos, "",
35                                     CheckboxWidget::kCheckActionCmd);
36   myPins[kJUp]->setID(kJUp);
37   myPins[kJUp]->setTarget(this);
38 
39   ypos += myPins[kJUp]->getHeight() * 2 + 10;
40   myPins[kJDown] = new CheckboxWidget(boss, font, xpos, ypos, "",
41                                       CheckboxWidget::kCheckActionCmd);
42   myPins[kJDown]->setID(kJDown);
43   myPins[kJDown]->setTarget(this);
44 
45   xpos -= myPins[kJUp]->getWidth() + 5;
46   ypos -= myPins[kJUp]->getHeight() + 5;
47   myPins[kJLeft] = new CheckboxWidget(boss, font, xpos, ypos, "",
48                                       CheckboxWidget::kCheckActionCmd);
49   myPins[kJLeft]->setID(kJLeft);
50   myPins[kJLeft]->setTarget(this);
51 
52   xpos += (myPins[kJUp]->getWidth() + 5) * 2;
53   myPins[kJRight] = new CheckboxWidget(boss, font, xpos, ypos, "",
54                                        CheckboxWidget::kCheckActionCmd);
55   myPins[kJRight]->setID(kJRight);
56   myPins[kJRight]->setTarget(this);
57 
58   xpos -= (myPins[kJUp]->getWidth() + 5) * 2;
59   ypos = 20 + (myPins[kJUp]->getHeight() + 10) * 3;
60   myPins[kJFire] = new CheckboxWidget(boss, font, xpos, ypos, "Fire",
61                                       CheckboxWidget::kCheckActionCmd);
62   myPins[kJFire]->setID(kJFire);
63   myPins[kJFire]->setTarget(this);
64 
65   ypos += myPins[kJFire]->getHeight() + 5;
66   myPins[kJBooster] = new CheckboxWidget(boss, font, xpos, ypos, "Booster",
67                                          CheckboxWidget::kCheckActionCmd);
68   myPins[kJBooster]->setID(kJBooster);
69   myPins[kJBooster]->setTarget(this);
70 
71   ypos += myPins[kJBooster]->getHeight() + 5;
72   myPins[kJTrigger] = new CheckboxWidget(boss, font, xpos, ypos, "Trigger",
73                                          CheckboxWidget::kCheckActionCmd);
74   myPins[kJTrigger]->setID(kJTrigger);
75   myPins[kJTrigger]->setTarget(this);
76 
77   addFocusWidget(myPins[kJUp]);
78   addFocusWidget(myPins[kJLeft]);
79   addFocusWidget(myPins[kJRight]);
80   addFocusWidget(myPins[kJDown]);
81   addFocusWidget(myPins[kJFire]);
82   addFocusWidget(myPins[kJBooster]);
83   addFocusWidget(myPins[kJTrigger]);
84 }
85 
86 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
loadConfig()87 void BoosterWidget::loadConfig()
88 {
89   myPins[kJUp]->setState(!getPin(ourPinNo[kJUp]));
90   myPins[kJDown]->setState(!getPin(ourPinNo[kJDown]));
91   myPins[kJLeft]->setState(!getPin(ourPinNo[kJLeft]));
92   myPins[kJRight]->setState(!getPin(ourPinNo[kJRight]));
93   myPins[kJFire]->setState(!getPin(ourPinNo[kJFire]));
94 
95   myPins[kJBooster]->setState(
96     getPin(Controller::AnalogPin::Five) == AnalogReadout::connectToVcc());
97   myPins[kJTrigger]->setState(
98     getPin(Controller::AnalogPin::Nine) == AnalogReadout::connectToVcc());
99 }
100 
101 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
handleCommand(CommandSender * sender,int cmd,int data,int id)102 void BoosterWidget::handleCommand(
103     CommandSender* sender, int cmd, int data, int id)
104 {
105   if(cmd == CheckboxWidget::kCheckActionCmd)
106   {
107     switch(id)
108     {
109       case kJUp:
110       case kJDown:
111       case kJLeft:
112       case kJRight:
113       case kJFire:
114         setPin(ourPinNo[id], !myPins[id]->getState());
115         break;
116       case kJBooster:
117         setPin(Controller::AnalogPin::Five,
118           myPins[id]->getState() ? AnalogReadout::connectToVcc() :
119                                    AnalogReadout::disconnect());
120         break;
121       case kJTrigger:
122         setPin(Controller::AnalogPin::Nine,
123           myPins[id]->getState() ? AnalogReadout::connectToVcc() :
124                                    AnalogReadout::disconnect());
125         break;
126       default:
127         break;
128     }
129   }
130 }
131 
132 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
133 constexpr std::array<Controller::DigitalPin, 5> BoosterWidget::ourPinNo;
134