gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

buttons.cpp (2624B)


      1 #include "buttons.h"
      2 
      3 #include "mqtypes.h"
      4 
      5 #include "mc68k/port.h"
      6 
      7 namespace mqLib
      8 {
      9 	Buttons::Buttons()
     10 	{
     11 		m_buttonStates.fill(0);
     12 	}
     13 
     14 	bool Buttons::processButtons(mc68k::Port& _gp, mc68k::Port& _e)
     15 	{
     16 		if(_gp.getDirection() == 0xff)
     17 			return false;
     18 
     19 		const auto w = _e.getWriteCounter();
     20 
     21 		const bool cycleEncoders = w != m_writeCounter;
     22 		m_writeCounter = w;
     23 
     24 		if (getButtonState(ButtonType::Power) && !_e.bittest(BtPower))
     25 		{
     26 			_e.setBitRX(BtPower);
     27 		}
     28 		else if (!getButtonState(ButtonType::Power) && _e.bittest(BtPower))
     29 		{
     30 			_e.clearBitRX(BtPower);
     31 		}
     32 		
     33 		if(!_e.bittest(Buttons0CS))
     34 		{
     35 			uint8_t res = 0;
     36 			for(size_t i=0; i<8; ++i)
     37 				res |= m_buttonStates[i] << i;
     38 			_gp.writeRX(res);
     39 			return true;
     40 		}
     41 
     42 		if(!_e.bittest(Buttons1CS))
     43 		{
     44 			uint8_t res = 0;
     45 			for(size_t i=0; i<8; ++i)
     46 				res |= m_buttonStates[i+8] << i;
     47 			_gp.writeRX(res);
     48 			return true;
     49 		}
     50 				
     51 		if(!_e.bittest(Encoders0CS))
     52 		{
     53 			uint8_t res = 0;
     54 
     55 			for(size_t i=0; i<4; ++i)
     56 			{
     57 				res |= processStepEncoder(static_cast<Encoders>(i), cycleEncoders) << (i<<1);
     58 			}
     59 			_gp.writeRX(res);
     60 			return true;
     61 		}
     62 
     63 		if(!_e.bittest(Encoders1CS))
     64 		{
     65 			uint8_t res = 0;
     66 
     67 			for(size_t i=4; i<static_cast<uint32_t>(Encoders::Master); ++i)
     68 			{
     69 				res |= processStepEncoder(static_cast<Encoders>(i), cycleEncoders) << ((i-4)<<1);
     70 			}
     71 
     72 			res |= processStepEncoder(Encoders::Master, cycleEncoders) << ((static_cast<uint32_t>(Encoders::Master)-4)<<1);
     73 
     74 			_gp.writeRX(res);
     75 			return true;
     76 		}
     77 
     78 		return false;
     79 	}
     80 
     81 	void Buttons::setButton(ButtonType _type, bool _pressed)
     82 	{
     83 		m_buttonStates[static_cast<uint32_t>(_type)] = _pressed;
     84 	}
     85 
     86 	void Buttons::toggleButton(ButtonType _type)
     87 	{
     88 		m_buttonStates[static_cast<uint32_t>(_type)] ^= 1;
     89 	}
     90 
     91 	void Buttons::rotate(Encoders _encoder, const int _amount)
     92 	{
     93 		auto& current = m_remainingRotations[static_cast<uint32_t>(_encoder)];
     94 
     95 		// The master encoder is a step encoder where 4 steps (one full cycle) is 1 tick
     96 		// The other encoders do not have any snapping, there are no ticks and there is some acceleration going on in the uc so use the smallest value that does something useful
     97 		current += _amount;// * (_encoder == Encoders::Master ? 4 : 3);
     98 	}
     99 
    100 	uint8_t Buttons::processStepEncoder(Encoders _encoder, bool cycleEncoders)
    101 	{
    102 		const auto i = static_cast<uint32_t>(_encoder);
    103 
    104 		auto& v = m_encoderValues[i];
    105 
    106 		constexpr uint8_t pattern[] = {0b00, 0b10, 0b11, 0b01};
    107 
    108 		if(!cycleEncoders)
    109 			return pattern[v&3];
    110 
    111 		auto& c = m_remainingRotations[i];
    112 
    113 		if(c > 0)
    114 		{
    115 			--v;
    116 			--c;
    117 		}
    118 		else if(c < 0)
    119 		{
    120 			++v;
    121 			++c;
    122 		}
    123 		return pattern[v&3];
    124 	}
    125 }