void CInstrumentEditDlg::SwitchOffNote(bool ForceHalt)
{
	stChanNote NoteData { };		// // //

	CFamiTrackerView *pView = CFamiTrackerView::GetView();
	CMainFrame *pFrameWnd = static_cast<CMainFrame*>(GetParent());

	int Channel = pView->GetSelectedChannel();

	NoteData.Note			= (pView->DoRelease() && !ForceHalt) ? RELEASE : HALT;
	NoteData.Instrument		= pFrameWnd->GetSelectedInstrument();

	theApp.GetSoundGenerator()->QueueNote(Channel, NoteData, NOTE_PRIO_2);

	m_iLastKey = -1;
}
void CInstrumentEditDlg::SwitchOnNote(int x, int y)
{
	CFamiTrackerView *pView = CFamiTrackerView::GetView();
	CFamiTrackerDoc *pDoc = static_cast<CFamiTrackerDoc*>(static_cast<CFrameWnd*>(GetParent())->GetActiveDocument());
	CMainFrame *pFrameWnd = static_cast<CMainFrame*>(GetParent());
	int Channel = pView->GetSelectedChannel();		// // //
	int Chip = pDoc->GetExpansionChip();

	stChanNote NoteData { };

	// // // Send to respective channels whenever cursor is outside instrument chip
	if (m_iSelectedInstType == INST_2A03) {
		if (m_pPanels[0]->IsWindowVisible() && Channel > CHANID_NOISE)
			pView->SelectChannel(pDoc->GetChannelIndex(CHANID_SQUARE1));
		if (m_pPanels[1]->IsWindowVisible())
			pView->SelectChannel(pDoc->GetChannelIndex(CHANID_DPCM));
	}
	else {
		chan_id_t First = CHANNELS;
		switch (m_iSelectedInstType) {
		case INST_VRC6: First = CHANID_VRC6_PULSE1; break;
		case INST_N163: First = CHANID_N163_CH1; break;
		case INST_FDS:  First = CHANID_FDS; break;
		case INST_VRC7: First = CHANID_VRC7_CH1; break;
		case INST_S5B:  First = CHANID_S5B_CH1; break;
		}
		int Index = pDoc->GetChannelIndex(First);
		if (Index != -1 && pDoc->GetChipType(Index) != pDoc->GetChipType(Channel))
			pView->SelectChannel(Index);
	}
	Channel = pView->GetSelectedChannel();		// // //

	if (m_KeyboardRect.PtInRect({x, y})) {
		int KeyPos = (x - m_KeyboardRect.left) % 70;		// // //
		int Octave = (x - m_KeyboardRect.left) / 70;
		int Note;

		if (y > m_KeyboardRect.top + 38) {
			// Only white keys
			     if (KeyPos >= 60) Note = NOTE_B;
			else if (KeyPos >= 50) Note = NOTE_A;
			else if (KeyPos >= 40) Note = NOTE_G;
			else if (KeyPos >= 30) Note = NOTE_F;
			else if (KeyPos >= 20) Note = NOTE_E;
			else if (KeyPos >= 10) Note = NOTE_D;
			else if (KeyPos >=  0) Note = NOTE_C;
		}
		else {
			// Black and white keys
			     if (KeyPos >= 62) Note = NOTE_B;
			else if (KeyPos >= 56) Note = NOTE_As;
			else if (KeyPos >= 53) Note = NOTE_A;
			else if (KeyPos >= 46) Note = NOTE_Gs;
			else if (KeyPos >= 43) Note = NOTE_G;
			else if (KeyPos >= 37) Note = NOTE_Fs;
			else if (KeyPos >= 30) Note = NOTE_F;
			else if (KeyPos >= 23) Note = NOTE_E;
			else if (KeyPos >= 16) Note = NOTE_Ds;
			else if (KeyPos >= 13) Note = NOTE_D;
			else if (KeyPos >=  7) Note = NOTE_Cs;
			else if (KeyPos >=  0) Note = NOTE_C;
		}

		int NewNote = MIDI_NOTE(Octave, Note);		// // //
		if (NewNote != m_iLastKey) {
			NoteData.Note			= Note;
			NoteData.Octave			= Octave;
			NoteData.Vol			= MAX_VOLUME - 1;
			NoteData.Instrument		= pFrameWnd->GetSelectedInstrument();
			memset(NoteData.EffNumber, 0, 4);
			memset(NoteData.EffParam, 0, 4);

			theApp.GetSoundGenerator()->QueueNote(Channel, NoteData, NOTE_PRIO_2);
			theApp.GetSoundGenerator()->ForceReloadInstrument(Channel);		// // //
			m_iLastKey = NewNote;
		}
	}
	else {
		NoteData.Note			= pView->DoRelease() ? RELEASE : HALT;//HALT;
		NoteData.Vol			= MAX_VOLUME;
		NoteData.Instrument		= pFrameWnd->GetSelectedInstrument();;
		memset(NoteData.EffNumber, 0, 4);
		memset(NoteData.EffParam, 0, 4);

		theApp.GetSoundGenerator()->QueueNote(Channel, NoteData, NOTE_PRIO_2);

		m_iLastKey = -1;
	}
}
示例#3
0
bool CFrameAction::SaveState(CMainFrame *pMainFrm)
{
	// Perform action

	CFrameEditor *pFrameEditor = pMainFrm->GetFrameEditor();
	CFamiTrackerView *pView = (CFamiTrackerView*)pMainFrm->GetActiveView();
	CFamiTrackerDoc *pDocument = pView->GetDocument();

	m_iUndoFramePos = pView->GetSelectedFrame();
	m_iUndoChannelPos = pView->GetSelectedChannel();

	switch (m_iAction) {
		case ACT_ADD:
			if (!pDocument->InsertFrame(m_iUndoFramePos + 1))
				return false;
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_REMOVE:
			SaveFrame(pDocument);
			if (!pDocument->RemoveFrame(m_iUndoFramePos))
				return false;
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_DUPLICATE:
			if (!pDocument->DuplicateFrame(m_iUndoFramePos))
				return false;
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_DUPLICATE_PATTERNS:
			if (!pDocument->DuplicatePatterns(m_iUndoFramePos + 1))
				return false;
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_CHANGE_COUNT:
			m_iUndoFrameCount = pDocument->GetFrameCount();
			pDocument->SetFrameCount(m_iNewFrameCount);
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_SET_PATTERN:
			m_iOldPattern = pDocument->GetPatternAtFrame(m_iUndoFramePos, m_iUndoChannelPos);
			pDocument->SetPatternAtFrame(m_iUndoFramePos, m_iUndoChannelPos, m_iNewPattern);
			pDocument->UpdateAllViews(NULL, CHANGED_PATTERN);
			break;
		case ACT_SET_PATTERN_ALL:
			{
				int Channels = pDocument->GetAvailableChannels();
				for (int i = 0; i < Channels; ++i) {
					m_iPatterns[i] = pDocument->GetPatternAtFrame(m_iUndoFramePos, i);
					pDocument->SetPatternAtFrame(m_iUndoFramePos, i, m_iNewPattern);
				}
				pDocument->UpdateAllViews(NULL, CHANGED_PATTERN);
			}
			break;
		case ACT_CHANGE_PATTERN:
			{
				m_iOldPattern = pDocument->GetPatternAtFrame(m_iUndoFramePos, m_iUndoChannelPos);
				int NewPattern = m_iOldPattern + m_iPatternDelta;
				if (NewPattern < 0)
					NewPattern = 0;
				if (NewPattern >= MAX_FRAMES)
					NewPattern = MAX_FRAMES - 1;
				if (NewPattern == m_iOldPattern)
					return false;
				pDocument->SetPatternAtFrame(m_iUndoFramePos, m_iUndoChannelPos, NewPattern);
				pDocument->UpdateAllViews(NULL, CHANGED_PATTERN);
			}
			break;
		case ACT_CHANGE_PATTERN_ALL:
			{
				int Channels = pDocument->GetAvailableChannels();
				for (int i = 0; i < Channels; ++i) {
					m_iPatterns[i] = pDocument->GetPatternAtFrame(m_iUndoFramePos, i);
					if (m_iPatterns[i] + m_iPatternDelta < 0 || m_iPatterns[i] + m_iPatternDelta >= MAX_FRAMES)
						return false;
				}
				for (int i = 0; i < Channels; ++i)
					pDocument->SetPatternAtFrame(m_iUndoFramePos, i, m_iPatterns[i] + m_iPatternDelta);
				pDocument->UpdateAllViews(NULL, CHANGED_PATTERN);
			}
			break;
		case ACT_MOVE_DOWN:
			if (!pDocument->MoveFrameDown(m_iUndoFramePos))
				return false;
			pView->SelectFrame(m_iUndoFramePos + 1);
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_MOVE_UP:
			if (!pDocument->MoveFrameUp(m_iUndoFramePos))
				return false;
			pView->SelectFrame(m_iUndoFramePos - 1);
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_PASTE:
			SaveFrame(pDocument);
			{
				int Channels = pDocument->GetAvailableChannels();
				for (int i = 0; i < Channels; ++i)
					pDocument->SetPatternAtFrame(m_iUndoFramePos, i, m_iPasteData[i]);
			}
			pDocument->UpdateAllViews(NULL, CHANGED_PATTERN);
			break;
	}

	return true;
}
void CInstrumentEditDlg::SwitchOnNote(int x, int y)
{
    CFamiTrackerView *pView = CFamiTrackerView::GetView();
    CMainFrame *pFrameWnd = static_cast<CMainFrame*>(GetParent());

    stChanNote NoteData;

    // TODO: remove hardcoded numbers

    // Send to DPCM channel if DPCM view is activated
    if (m_iSelectedInstType == INST_2A03 && m_pPanels[1]->IsWindowVisible())
        pView->SelectChannel(4);

    // Select FDS channel
    if (m_iSelectedInstType == INST_FDS)
        pView->SelectChannel(5);

    int Channel = pView->GetSelectedChannel();

    if (y > KEYBOARD_TOP && y < (KEYBOARD_TOP + 58) && x > KEYBOARD_LEFT && x < (KEYBOARD_LEFT + 560)) {

        int Octave = (x - KEYBOARD_LEFT) / 70;
        int Note;

        if (y > KEYBOARD_TOP + 38) {

            // Only white keys
            int KeyPos = (x - KEYBOARD_LEFT) % 70;

            if (KeyPos >= 0 && KeyPos < 10)				// C
                Note = 0;
            else if (KeyPos >= 10 && KeyPos < 20)		// D
                Note = 2;
            else if (KeyPos >= 20 && KeyPos < 30)		// E
                Note = 4;
            else if (KeyPos >= 30 && KeyPos < 40)		// F
                Note = 5;
            else if (KeyPos >= 40 && KeyPos < 50)		// G
                Note = 7;
            else if (KeyPos >= 50 && KeyPos < 60)		// A
                Note = 9;
            else if (KeyPos >= 60 && KeyPos < 70)		// B
                Note = 11;
        }
        else {
            // Black and white keys
            int KeyPos = (x - KEYBOARD_LEFT) % 70;

            if (KeyPos >= 0 && KeyPos < 7)			// C
                Note = 0;
            else if (KeyPos >= 7 && KeyPos < 13) 	// C#
                Note = 1;
            else if (KeyPos >= 13 && KeyPos < 16) 	// D
                Note = 2;
            else if (KeyPos >= 16 && KeyPos < 23) 	// D#
                Note = 3;
            else if (KeyPos >= 23 && KeyPos < 30) 	// E
                Note = 4;
            else if (KeyPos >= 30 && KeyPos < 37) 	// F
                Note = 5;
            else if (KeyPos >= 37 && KeyPos < 43) 	// F#
                Note = 6;
            else if (KeyPos >= 43 && KeyPos < 46) 	// G
                Note = 7;
            else if (KeyPos >= 46 && KeyPos < 53) 	// G#
                Note = 8;
            else if (KeyPos >= 53 && KeyPos < 56) 	// A
                Note = 9;
            else if (KeyPos >= 56 && KeyPos < 62) 	// A#
                Note = 10;
            else if (KeyPos >= 62 && KeyPos < 70) 	// B
                Note = 11;
        }

        if (Note + (Octave * 12) != m_iLastKey) {
            NoteData.Note			= Note + 1;
            NoteData.Octave			= Octave;
            NoteData.Vol			= 0x0F;
            NoteData.Instrument		= pFrameWnd->GetSelectedInstrument();
            memset(NoteData.EffNumber, 0, 4);
            memset(NoteData.EffParam, 0, 4);

            theApp.GetSoundGenerator()->QueueNote(Channel, NoteData, NOTE_PRIO_2);
        }

        m_iLastKey = Note + (Octave * 12);
    }
    else {
        NoteData.Note			= pView->DoRelease() ? RELEASE : HALT;//HALT;
        NoteData.Octave			= 0;
        NoteData.Vol			= 0x10;
        NoteData.Instrument		= pFrameWnd->GetSelectedInstrument();;
        memset(NoteData.EffNumber, 0, 4);
        memset(NoteData.EffParam, 0, 4);

        theApp.GetSoundGenerator()->QueueNote(Channel, NoteData, NOTE_PRIO_2);

        m_iLastKey = -1;
    }
}
示例#5
0
void CFrameAction::Undo(CMainFrame *pMainFrm)
{
	// Undo action

	CFrameEditor *pFrameEditor = pMainFrm->GetFrameEditor();
	CFamiTrackerView *pView = (CFamiTrackerView*)pMainFrm->GetActiveView();
	CFamiTrackerDoc *pDocument = pView->GetDocument();

	m_iRedoFramePos = pView->GetSelectedFrame();
	m_iRedoChannelPos = pView->GetSelectedChannel();

	pView->SelectFrame(m_iUndoFramePos);
	pView->SelectChannel(m_iUndoChannelPos);

	switch (m_iAction) {
		case ACT_ADD:
			pDocument->RemoveFrame(m_iUndoFramePos + 1);
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_REMOVE:
			pDocument->InsertFrame(m_iUndoFramePos);
			RestoreFrame(pDocument);
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_DUPLICATE:
			pDocument->RemoveFrame(m_iUndoFramePos);
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_DUPLICATE_PATTERNS:
			for (unsigned int i = 0; i < pDocument->GetAvailableChannels(); ++i) {
				pDocument->ClearPattern(m_iUndoFramePos + 1, i);
			}
			pDocument->RemoveFrame(m_iUndoFramePos + 1);
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_CHANGE_COUNT:
			pDocument->SetFrameCount(m_iUndoFrameCount);
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_SET_PATTERN:
			pDocument->SetPatternAtFrame(m_iUndoFramePos, m_iUndoChannelPos, m_iOldPattern);
			pDocument->UpdateAllViews(NULL, CHANGED_PATTERN);
			pMainFrm->UpdateControls();
			break;
		case ACT_SET_PATTERN_ALL:
			for (unsigned int i = 0; i < pDocument->GetAvailableChannels(); ++i) {
				pDocument->SetPatternAtFrame(m_iUndoFramePos, i, m_iPatterns[i]);
			}
			pDocument->UpdateAllViews(NULL, CHANGED_PATTERN);
			break;
		case ACT_CHANGE_PATTERN:
			pDocument->SetPatternAtFrame(m_iUndoFramePos, m_iUndoChannelPos, m_iOldPattern);
			pDocument->UpdateAllViews(NULL, CHANGED_PATTERN);
			break;
		case ACT_CHANGE_PATTERN_ALL:
			for (unsigned int i = 0; i < pDocument->GetAvailableChannels(); ++i) {
				pDocument->SetPatternAtFrame(m_iUndoFramePos, i, m_iPatterns[i]);
			}
			pDocument->UpdateAllViews(NULL, CHANGED_PATTERN);
			break;
		case ACT_MOVE_DOWN:
			pDocument->MoveFrameUp(m_iUndoFramePos + 1);
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_MOVE_UP:
			pDocument->MoveFrameDown(m_iUndoFramePos - 1);
			pDocument->UpdateAllViews(NULL, CHANGED_FRAMES);
			break;
		case ACT_PASTE:
			RestoreFrame(pDocument);
			pDocument->UpdateAllViews(NULL, CHANGED_PATTERN);
			break;
	}

	pView->SelectFrame(m_iUndoFramePos);
	pView->SelectChannel(m_iUndoChannelPos);
}