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 #ifndef MINDLINK_HXX 19 #define MINDLINK_HXX 20 21 #include "bspf.hxx" 22 #include "Control.hxx" 23 24 /** 25 The Atari Mindlink was an unreleased video game controller intended for 26 release in 1984. The Mindlink was unique in that one had to move the 27 muscles in one's head to control the game. These movements would be read by 28 infrared sensors and transferred as movement in the game. For more 29 information, see the following link: 30 31 http://www.atarimuseum.com/videogames/consoles/2600/mindlink.html 32 33 This code was heavily borrowed from z26, and uses conventions defined 34 there. Specifically, IOPortA is treated as a complete uInt8, whereas 35 the Stella core actually stores this information in boolean arrays 36 addressable by DigitalPin number. 37 38 @author Stephen Anthony, Thomas Jentzsch & z26 team 39 */ 40 class MindLink : public Controller 41 { 42 public: 43 /** 44 Create a new MindLink controller plugged into the specified jack 45 46 @param jack The jack the controller is plugged into 47 @param event The event object to use for events 48 @param system The system using this controller 49 */ 50 MindLink(Jack jack, const Event& event, const System& system); 51 ~MindLink() override = default; 52 53 public: 54 /** 55 Write the given value to the specified digital pin for this 56 controller. Writing is only allowed to the pins associated 57 with the PIA. Therefore you cannot write to pin six. 58 59 @param pin The pin of the controller jack to write to 60 @param value The value to write to the pin 61 */ write(DigitalPin pin,bool value)62 void write(DigitalPin pin, bool value) override { setPin(pin, value); } 63 64 /** 65 Called after *all* digital pins have been written on Port A. 66 */ controlWrite(uInt8)67 void controlWrite(uInt8) override { nextMindlinkBit(); } 68 69 /** 70 Update the entire digital and analog pin state according to the 71 events currently set. 72 */ 73 void update() override; 74 75 /** 76 Returns the name of this controller. 77 */ name() const78 string name() const override { return "MindLink"; } 79 80 /** 81 Answers whether the controller is intrinsically an analog controller. 82 */ isAnalog() const83 bool isAnalog() const override { return true; } 84 85 /** 86 Determines how this controller will treat values received from the 87 X/Y axis and left/right buttons of the mouse. Since not all controllers 88 use the mouse the same way (or at all), it's up to the specific class to 89 decide how to use this data. 90 91 In the current implementation, the left button is tied to the X axis, 92 and the right one tied to the Y axis. 93 94 @param xtype The controller to use for x-axis data 95 @param xid The controller ID to use for x-axis data (-1 for no id) 96 @param ytype The controller to use for y-axis data 97 @param yid The controller ID to use for y-axis data (-1 for no id) 98 99 @return Whether the controller supports using the mouse 100 */ 101 bool setMouseControl( 102 Controller::Type xtype, int xid, Controller::Type ytype, int yid) override; 103 104 private: 105 void nextMindlinkBit(); 106 107 // Range of valid values 108 static constexpr int MIN_POS = 0x2700; 109 static constexpr int MAX_POS = 0x3e00; 110 static constexpr int CALIBRATE_FLAG = 0x8000; // this causes a left side calibration 111 112 private: 113 // Position value in Mindlink controller 114 // Gets transferred bitwise (16 bits) 115 int myMindlinkPos{MIN_POS}; 116 117 // Which bit to transfer next 118 int myMindlinkShift{1}; 119 120 // Whether to use the mouse to emulate this controller 121 int myMouseEnabled{false}; 122 123 private: 124 // Following constructors and assignment operators not supported 125 MindLink() = delete; 126 MindLink(const MindLink&) = delete; 127 MindLink(MindLink&&) = delete; 128 MindLink& operator=(const MindLink&) = delete; 129 MindLink& operator=(MindLink&&) = delete; 130 }; 131 132 #endif 133