diff --git a/sources/Application/Model/Phrase.cpp b/sources/Application/Model/Phrase.cpp index 0e7a5f8bd..70f90b4f9 100644 --- a/sources/Application/Model/Phrase.cpp +++ b/sources/Application/Model/Phrase.cpp @@ -4,9 +4,9 @@ #include Phrase::Phrase() { - for (int i = 0; i < PHRASE_COUNT * 16; i++) { - note_[i] = 0xFF; - instr_[i] = 0xFF; + for (int i = 0; i < PHRASE_COUNT * PHRASE_ROW_COUNT; i++) { + note_[i] = NO_NOTE_ASSIGNED; + instr_[i] = NO_INSTRUMENT_ASSIGNED; cmd1_[i] = FourCC::InstrumentCommandNone; param1_[i] = 0x00; cmd2_[i] = FourCC::InstrumentCommandNone; diff --git a/sources/Application/Model/Phrase.h b/sources/Application/Model/Phrase.h index 0fc5e3ddf..7a40f3d3f 100644 --- a/sources/Application/Model/Phrase.h +++ b/sources/Application/Model/Phrase.h @@ -4,6 +4,9 @@ #include "Foundation/Types/Types.h" #define PHRASE_COUNT 0x80 #define NO_MORE_PHRASE 0x81 +#define PHRASE_ROW_COUNT 16 +#define NO_NOTE_ASSIGNED 0xFF +#define NO_INSTRUMENT_ASSIGNED 0xFF class Phrase { public: @@ -14,12 +17,12 @@ class Phrase { void SetUsed(uchar c); void ClearAllocation(); - uchar note_[PHRASE_COUNT * 16]; - uchar instr_[PHRASE_COUNT * 16]; - FourCC cmd1_[PHRASE_COUNT * 16]; - ushort param1_[PHRASE_COUNT * 16]; - FourCC cmd2_[PHRASE_COUNT * 16]; - ushort param2_[PHRASE_COUNT * 16]; + uchar note_[PHRASE_COUNT * PHRASE_ROW_COUNT]; + uchar instr_[PHRASE_COUNT * PHRASE_ROW_COUNT]; + FourCC cmd1_[PHRASE_COUNT * PHRASE_ROW_COUNT]; + ushort param1_[PHRASE_COUNT * PHRASE_ROW_COUNT]; + FourCC cmd2_[PHRASE_COUNT * PHRASE_ROW_COUNT]; + ushort param2_[PHRASE_COUNT * PHRASE_ROW_COUNT]; private: bool isUsed_[PHRASE_COUNT]; diff --git a/sources/Application/Views/PhraseView.cpp b/sources/Application/Views/PhraseView.cpp index 6139ee27f..0b756c35f 100644 --- a/sources/Application/Views/PhraseView.cpp +++ b/sources/Application/Views/PhraseView.cpp @@ -13,6 +13,13 @@ #include #include +#define NOTE_COLUMN 0 +#define INSTR_COLUMN 1 +#define CMD1_COLUMN 2 +#define PARAM1_COLUMN 3 +#define CMD2_COLUMN 4 +#define PARAM2_COLUMN 5 + short PhraseView::offsets_[2][4] = {-1, 1, 12, -12, -1, 1, 16, -16}; PhraseView::PhraseView(GUIWindow &w, ViewData *viewData) @@ -328,6 +335,97 @@ void PhraseView::pasteLast() { } } +void PhraseView::jumpToNextSection(int direction) { + int phraseStart = viewData_->currentPhrase_ * PHRASE_ROW_COUNT; + int current = row_; + bool foundGap = false; + + switch (col_) { + case NOTE_COLUMN: { + for (int i = 0; i < PHRASE_ROW_COUNT; i++) { + uchar note = phrase_->note_[phraseStart + current]; + if (foundGap && note != NO_NOTE_ASSIGNED) { + break; + } else if (note == NO_NOTE_ASSIGNED) { + foundGap = true; + } + current += direction; + if (current < 0) + current += PHRASE_ROW_COUNT; + if (current >= PHRASE_ROW_COUNT) + current -= PHRASE_ROW_COUNT; + } + break; + } + + case INSTR_COLUMN: { + for (int i = 0; i < PHRASE_ROW_COUNT; i++) { + uchar instrument = phrase_->instr_[phraseStart + current]; + if (foundGap && instrument != NO_INSTRUMENT_ASSIGNED) { + break; + } else if (instrument == NO_INSTRUMENT_ASSIGNED) { + foundGap = true; + } + current += direction; + if (current < 0) + current += PHRASE_ROW_COUNT; + if (current >= PHRASE_ROW_COUNT) + current -= PHRASE_ROW_COUNT; + } + break; + } + + // find gap based on cmd1 for both columns + case CMD1_COLUMN: + case PARAM1_COLUMN: { + for (int i = 0; i < PHRASE_ROW_COUNT; i++) { + FourCC command = phrase_->cmd1_[phraseStart + current]; + if (foundGap && command != FourCC::InstrumentCommandNone) { + break; + } else if (command == FourCC::InstrumentCommandNone) { + foundGap = true; + } + current += direction; + if (current < 0) + current += PHRASE_ROW_COUNT; + if (current >= PHRASE_ROW_COUNT) + current -= PHRASE_ROW_COUNT; + } + break; + } + + // find gap based on cmd2 for both columns + case CMD2_COLUMN: + case PARAM2_COLUMN: { + for (int i = 0; i < PHRASE_ROW_COUNT; i++) { + FourCC command = phrase_->cmd2_[phraseStart + current]; + if (foundGap && command != FourCC::InstrumentCommandNone) { + break; + } else if (command == FourCC::InstrumentCommandNone) { + foundGap = true; + } + current += direction; + if (current < 0) + current += PHRASE_ROW_COUNT; + if (current >= PHRASE_ROW_COUNT) + current -= PHRASE_ROW_COUNT; + } + break; + } + + default: { + Trace::Error("PHRASEVIEW: jumpToNextSection received unexpected value for " + "col %d not implemented", + col_); + return; + } + } + + // update view + row_ = current; + isDirty_ = true; +} + void PhraseView::cutPosition() { clipboard_.active_ = true; @@ -964,7 +1062,12 @@ void PhraseView::processNormalButtonMask(unsigned short mask) { } else { // L Modifier if (mask & EPBM_ALT) { - + if (mask & EPBM_DOWN) { + jumpToNextSection(1); + } + if (mask & EPBM_UP) { + jumpToNextSection(-1); + } } else { // No modifier @@ -1278,7 +1381,22 @@ void PhraseView::DrawView() { OnPlayerUpdate(PET_UPDATE); }; + // if in one of the param columns, update cmdEdit(Field) as well if ((viewMode_ != VM_SELECTION) && ((col_ == 3) || (col_ == 5))) { + // get current (new) cursor position + GUIPoint p; + p._y = row_ + anchor._y; + p._x = anchor._x + ((col_ == 3) ? 12 : 21); + + // update cmdEditField with current position + cmdEditField_->SetPosition(p); + + // Update the command edit field's value with the current parameter + ushort *paramPtr = + (col_ == 3) ? &phrase_->param1_[16 * viewData_->currentPhrase_ + row_] + : &phrase_->param2_[16 * viewData_->currentPhrase_ + row_]; + cmdEdit_.SetInt(*paramPtr); + cmdEditField_->SetFocus(); cmdEditField_->Draw(w_); }; diff --git a/sources/Application/Views/PhraseView.h b/sources/Application/Views/PhraseView.h index 4acc06424..939e3f5d1 100644 --- a/sources/Application/Views/PhraseView.h +++ b/sources/Application/Views/PhraseView.h @@ -27,6 +27,8 @@ class PhraseView : public ScreenView { void cutPosition(); void pasteLast(); + void jumpToNextSection(int dir); + void extendSelection(); GUIRect getSelectionRect(); diff --git a/sources/Application/Views/SongView.cpp b/sources/Application/Views/SongView.cpp index f0004d6ba..4a587a47e 100644 --- a/sources/Application/Views/SongView.cpp +++ b/sources/Application/Views/SongView.cpp @@ -447,9 +447,10 @@ void SongView::jumpToNextSection(int direction) { current -= SONG_ROW_COUNT; } } - // If we go backwards, we stil have to go to the beginning of the block - if (direction < 0) { + // In live mode, when we go backwards, we still have to go to the beginning of + // the block + if (Player::GetInstance()->GetSequencerMode() == SM_LIVE && direction < 0) { while (current > 0) { unsigned char *start = viewData_->song_->data_ + viewData_->songX_ + SONG_CHANNEL_COUNT * current;