From 9332de7a8b93eac36c4ea7ab5c5712099275eb00 Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 1 Sep 2022 12:48:10 +0200 Subject: [PATCH] added ASCIISTEP16 compatibility (stepsequencer mode) --- src/tracker/PatternEditor.cpp | 28 +++++++ src/tracker/PatternEditor.h | 6 ++ .../PatternEditorControlEventListener.cpp | 2 +- src/tracker/PatternEditorControlKeyboard.cpp | 9 +- src/tracker/Tracker.h | 1 + src/tracker/TrackerShortCuts.cpp | 84 +++++++++++++++++++ 6 files changed, 123 insertions(+), 7 deletions(-) diff --git a/src/tracker/PatternEditor.cpp b/src/tracker/PatternEditor.cpp index ac8a544e..9ceb1b01 100644 --- a/src/tracker/PatternEditor.cpp +++ b/src/tracker/PatternEditor.cpp @@ -1170,6 +1170,34 @@ pp_int32 PatternEditor::relocateCommandsSelection(const PatternEditorTools::Relo return resCnt; } +bool PatternEditor::writeStep(pp_uint32 channel, + pp_uint32 step, + pp_uint32 note, + pp_uint32 barRow, + bool withUndo/* = false*/) +{ + if (withUndo) + prepareUndo(); + + // ASCIISTEP16 standard (https://gist.github.com/coderofsalvation/8d760b191f4bb5465c8772d5618e5c4b) + // determines final cursor position based on pckeyboard stepvalue + cursor.row = step; + cursor.channel = channel; + PatternTools patternTools; + patternTools.setPosition(pattern, cursor.channel, cursor.row); + + pp_int32 instr = getCurrentActiveInstrument(); + bool enable = (patternTools.getNote() == 0 || instr != patternTools.getInstrument() ); + patternTools.setNote( enable ? note : 0 ); + patternTools.setInstrument( enable ? instr : 0 ); + cursor.row = barRow; // stick cursor to beginning of bar so page-up/down navigates thru bars + setCursor(cursor); + + if (withUndo) + finishUndo(LastChangeSlotChange); + return true; +} + bool PatternEditor::writeNote(pp_int32 note, bool withUndo/* = false*/, PatternAdvanceInterface* advanceImpl/* = NULL*/) diff --git a/src/tracker/PatternEditor.h b/src/tracker/PatternEditor.h index 222ee1f2..c771b657 100644 --- a/src/tracker/PatternEditor.h +++ b/src/tracker/PatternEditor.h @@ -370,6 +370,12 @@ class PatternEditor : public EditorBase bool writeNote(pp_int32 note, bool withUndo = false, PatternAdvanceInterface* advanceImpl = NULL); + + bool writeStep(pp_uint32 channel, + pp_uint32 stup, + pp_uint32 note, + pp_uint32 barRow, + bool withUndo/* = false*/); // --- write through, without undo etc. ---------------------------------- void writeDirectNote(pp_int32 note, diff --git a/src/tracker/PatternEditorControlEventListener.cpp b/src/tracker/PatternEditorControlEventListener.cpp index bfedace4..7e578a1c 100644 --- a/src/tracker/PatternEditorControlEventListener.cpp +++ b/src/tracker/PatternEditorControlEventListener.cpp @@ -1135,4 +1135,4 @@ bool PatternEditorControl::isSoloChannel(pp_int32 c) return true; return false; -} +} \ No newline at end of file diff --git a/src/tracker/PatternEditorControlKeyboard.cpp b/src/tracker/PatternEditorControlKeyboard.cpp index 3e8d60fe..cd560fec 100644 --- a/src/tracker/PatternEditorControlKeyboard.cpp +++ b/src/tracker/PatternEditorControlKeyboard.cpp @@ -663,7 +663,6 @@ void PatternEditorControl::handleKeyDown(pp_uint16 keyCode, pp_uint16 scanCode, if (cursor.inner == 0) { handleDeleteKey(keyCode, number); - if (number == -1 && ::getKeyModifier() == 0) number = ScanCodeToNote(scanCode); @@ -677,17 +676,15 @@ void PatternEditorControl::handleKeyDown(pp_uint16 keyCode, pp_uint16 scanCode, void PatternEditorControl::handleKeyChar(pp_uint8 character) { - PatternEditorTools::Position& cursor = patternEditor->getCursor(); - pp_int32 number = -1; - // prevent unnecessary screen refreshing through listener callback // remember to reset this when leaving this function patternEditor->setLazyUpdateNotifications(true); + PatternEditorTools::Position& cursor = patternEditor->getCursor(); + pp_int32 number = -1; if ((cursor.inner == 1 || cursor.inner == 2)) { number = asciiToHex(character); - if (number == 0xFF) patternEditor->writeInstrument(PatternEditor::NibbleTypeBoth, 0, true, this); else if (number >= 0 && number <= 0xF) @@ -795,7 +792,7 @@ void PatternEditorControl::handleKeyChar(pp_uint8 character) patternEditor->writeEffectOperand(PatternEditor::NibbleTypeBoth, number, true, this); else patternEditor->writeEffectOperand(cursor.inner == 6 ? PatternEditor::NibbleTypeHigh : PatternEditor::NibbleTypeLow, - number, true, this); + number, true, this); } } diff --git a/src/tracker/Tracker.h b/src/tracker/Tracker.h index 841d58b6..960213f7 100644 --- a/src/tracker/Tracker.h +++ b/src/tracker/Tracker.h @@ -338,6 +338,7 @@ class Tracker : public EventListenerInterface void fillInstrumentListBox(PPListBox* listBox, ModuleEditor* moduleEditor = NULL); void fillSampleListBox(PPListBox* listBox, pp_int32 insIndex, ModuleEditor* moduleEditor = NULL); void fillModuleListBox(PPListBox* listBox); + void doASCIISTEP16( pp_uint8 character, bool chselect ); void setChanged(); diff --git a/src/tracker/TrackerShortCuts.cpp b/src/tracker/TrackerShortCuts.cpp index 4600683b..59a76632 100644 --- a/src/tracker/TrackerShortCuts.cpp +++ b/src/tracker/TrackerShortCuts.cpp @@ -47,6 +47,8 @@ #include "SectionInstruments.h" #include "SectionTranspose.h" #include "SectionDiskMenu.h" +#include "ScopesControl.h" +#include "TrackerSettingsDatabase.h" void Tracker::sendNoteDown(mp_sint32 note, pp_int32 volume/* = -1*/) { @@ -144,6 +146,8 @@ void Tracker::processShortcutsMilkyTracker(PPEvent* event) } } + if (::getKeyModifier() == (KeyModifierSHIFT) ) + doASCIISTEP16(keyCode, ::getKeyModifier() == (KeyModifierCTRL) ); } else if (event->getID() == eKeyUp) { @@ -678,3 +682,83 @@ bool Tracker::processMessageBoxShortcuts(PPEvent* event) return false; } + +static pp_int32 ASCIISTEP16(pp_uint8 ascii,pp_uint16 bar) +{ + pp_int32 number = -1; + switch (ascii) + { + // ASCIISTEP16 standard (https://gist.github.com/coderofsalvation/8d760b191f4bb5465c8772d5618e5c4b) + case 'Q': number = 0; break; + case 'W': number = 1; break; + case 'E': number = 2; break; + case 'R': number = 3; break; + case 'T': number = 4; break; + case 'Y': number = 5; break; + case 'U': number = 6; break; + case 'I': number = 7; break; + case 'A': number = 8; break; + case 'S': number = 9; break; + case 'D': number = 10; break; + case 'F': number = 11; break; + case 'G': number = 12; break; + case 'H': number = 13; break; + case 'J': number = 14; break; + case 'K': number = 15; break; + } + return number == -1 ? -1 : number + (bar*16); +} + +static pp_int32 ASCIISTEP16_channel(pp_uint8 ascii) +{ + pp_int32 number = -1; + switch (ascii) + { + // ASCIISTEP16 standard (https://gist.github.com/coderofsalvation/8d760b191f4bb5465c8772d5618e5c4b) + case '1': number = 0; break; + case '2': number = 1; break; + case '3': number = 2; break; + case '4': number = 3; break; + case '5': number = 4; break; + case '6': number = 5; break; + case '7': number = 6; break; + case '8': number = 7; break; + case '9': number = 8; break; + case '0': number = 9; break; + case '-': number = 10; break; + case '=': number = 11; break; + } + return number; +} + +void Tracker::doASCIISTEP16( pp_uint8 character, bool chselect ){ + // check for ASCIISTEP16 events + PatternEditorTools::Position& cursor = getPatternEditor()->getCursor(); + pp_int32 stepsize = getPatternEditorControl()->getRowInsertAdd() + 1; + pp_int32 bar = cursor.row / (16*stepsize); + pp_int32 step = ASCIISTEP16(character,bar) * stepsize; + pp_int32 ch = ASCIISTEP16_channel(character); + if ( ch > -1 ){ + if( chselect ){ + PatternEditor *p = getPatternEditor(); + PatternEditorTools::Position& cursor = p->getCursor(); + cursor.channel = ch < p->getNumChannels() ? ch : cursor.channel; + getPatternEditorControl()->setChannel( cursor.channel, 0 ); + }else{ + muteChannels[ch] = !muteChannels[ch]; + bool mute = muteChannels[ch]; + playerController->muteChannel(ch,mute); + scopesControl->muteChannel(ch,mute); + getPatternEditorControl()->muteChannel(ch,mute); + patternEditorControl->muteChannel( ch, mute ); // ASCIISTEP16 mute toggle + } + updatePatternEditorControl(true); + } + if ( step > -1 ){ + PatternEditorTools::Position cursor; + // write ASCIISTEP16 step + pp_uint32 note = TONOTE(getPatternEditor()->getCurrentOctave(),0); + getPatternEditor()->writeStep( patternEditorControl->getCurrentChannel(), step, note, bar * (16*stepsize),true); + updatePatternEditorControl(true); + } +}