Path: blob/master/libgambatte/src/sound/envelope_unit.cpp
2 views
/***************************************************************************1* Copyright (C) 2007 by Sindre Aamås *2* [email protected] *3* *4* This program is free software; you can redistribute it and/or modify *5* it under the terms of the GNU General Public License version 2 as *6* published by the Free Software Foundation. *7* *8* This program is distributed in the hope that it will be useful, *9* but WITHOUT ANY WARRANTY; without even the implied warranty of *10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *11* GNU General Public License version 2 for more details. *12* *13* You should have received a copy of the GNU General Public License *14* version 2 along with this program; if not, write to the *15* Free Software Foundation, Inc., *16* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *17***************************************************************************/18#include "envelope_unit.h"19#include <algorithm>2021namespace gambatte {2223EnvelopeUnit::VolOnOffEvent EnvelopeUnit::nullEvent;2425void EnvelopeUnit::event() {26const unsigned long period = nr2 & 7;2728if (period) {29unsigned newVol = volume;3031if (nr2 & 8)32++newVol;33else34--newVol;3536if (newVol < 0x10U) {37volume = newVol;3839if (volume < 2)40volOnOffEvent(counter);4142counter += period << 15;43} else44counter = COUNTER_DISABLED;45} else46counter += 8ul << 15;47}4849bool EnvelopeUnit::nr2Change(const unsigned newNr2) {50if (!(nr2 & 7) && counter != COUNTER_DISABLED)51++volume;52else if (!(nr2 & 8))53volume += 2;5455if ((nr2 ^ newNr2) & 8)56volume = 0x10 - volume;5758volume &= 0xF;5960nr2 = newNr2;6162return !(newNr2 & 0xF8);63}6465bool EnvelopeUnit::nr4Init(const unsigned long cc) {66{67unsigned long period = nr2 & 7;6869if (!period)70period = 8;7172if (!(cc & 0x7000))73++period;7475counter = cc - ((cc - 0x1000) & 0x7FFF) + period * 0x8000;76}7778volume = nr2 >> 4;7980return !(nr2 & 0xF8);81}8283EnvelopeUnit::EnvelopeUnit(VolOnOffEvent &volOnOffEvent)84: volOnOffEvent(volOnOffEvent),85nr2(0),86volume(0)87{88}8990void EnvelopeUnit::reset() {91counter = COUNTER_DISABLED;92}9394void EnvelopeUnit::loadState(const SaveState::SPU::Env &estate, const unsigned nr2, const unsigned long cc) {95counter = std::max(estate.counter, cc);96volume = estate.volume;97this->nr2 = nr2;98}99100SYNCFUNC(EnvelopeUnit)101{102NSS(counter);103NSS(nr2);104NSS(volume);105}106107}108109110