diff --git a/common/source/main.cpp b/common/source/main.cpp index 30de7bd..5a865ed 100644 --- a/common/source/main.cpp +++ b/common/source/main.cpp @@ -260,7 +260,7 @@ bool multisamp_from_mapsamp = false; bool mod_loading = false; // TODO: Make own class for tracker control and remove forward declarations -void handleButtons(u16 buttons, u16 buttonsheld); +void handleButtons(u16 buttons, u16 buttonsheld, u16 buttonsup); void HandleTick(void); void handlePotPosChangeFromSong(u16 newpotpos); void handleSampleChange(u16 sample); @@ -2151,7 +2151,7 @@ void setEffectParam(u16 eff_par, bool new_e_cmd, bool force_clear=false, bool ov } } -void handleTranspose(s32 transpose_amount) +void handleSelTranspose(s32 transpose_amount) { const s32 min_note = 0; // c-0 const s32 max_note = 95; // h-7 @@ -2178,6 +2178,53 @@ void handleTranspose(s32 transpose_amount) } } +void handleInPlaceTranspose(s32 direction, bool wide) +{ + const s32 min_note = 0; // c-0 + const s32 max_note = 95; // h-7 + bool changed = false; + s32 transpose_amount = direction; + if(wide) + transpose_amount *= (pv->getComponentNavOffset() == PV_COMPONENT_NOTE ? 12 : (pv->getComponentNavOffset() == PV_COMPONENT_EFFECT ? 1 : 16)); + Cell cell = song->getPattern(song->getPotEntry(state->potpos))[state->channel][state->getCursorRow()]; + switch(pv->getComponentNavOffset()) + { + case PV_COMPONENT_NOTE: + if(cell.note != EMPTY_NOTE && cell.note != STOP_NOTE) + { + s32 new_note = (s32)cell.note + transpose_amount; + if (new_note >= min_note && new_note <= max_note) + { + cell.note = (u8)new_note; + changed = true; + } + } + break; + case PV_COMPONENT_INSTRUMENT: + // TODO + changed = true; + break; + case PV_COMPONENT_VOLUME: + cell.volume = (cell.volume + transpose_amount) & 0x7F; + changed = true; + break; + case PV_COMPONENT_EFFECT: + cell.effect = (cell.effect + transpose_amount) & 0xF; + changed = true; + break; + case PV_COMPONENT_EFFECT_PARAM: + cell.effect_param = (cell.effect_param + transpose_amount); + changed = true; + break; + } + if(changed) + { + action_buffer->add(song, new SingleCellSetAction(state, state->channel, state->getCursorRow(), cell)); + redraw_main_requested = true; + updateSampleOffsetGuide(); + } +} + void destroyThemeDialog(void) { gui->unregisterOverlayWidget(); @@ -2261,14 +2308,14 @@ void handleThemeButton(void) fbtheme->reveal(); } -void handleTransposeUp(void) +void handleSelTransposeUp(void) { - handleTranspose((PlatformKeysHeld & PlatformKey_R) ? 12 : 1); + handleSelTranspose((PlatformKeysHeld & PlatformKey_R) ? 12 : 1); } -void handleTransposeDown(void) +void handleSelTransposeDown(void) { - handleTranspose((PlatformKeysHeld & PlatformKey_R) ? -12 : -1); + handleSelTranspose((PlatformKeysHeld & PlatformKey_R) ? -12 : -1); } // number slider @@ -4179,10 +4226,10 @@ void setupGUI(bool dldi_enabled) labeltranspose->setCaption("trps"); */ buttontransposedown = new Button(RIGHT_SIDE_BUTTON_X(main_screen), 74, 14, 12, main_screen); buttontransposedown->setCaption("-"); - buttontransposedown->registerPushCallback(handleTransposeDown); + buttontransposedown->registerPushCallback(handleSelTransposeDown); buttontransposeup = new Button(RIGHT_SIDE_BUTTON_X(main_screen) + RIGHT_SIDE_BUTTON_WIDTH - 14, 74, 14, 12, main_screen); buttontransposeup->setCaption("+"); - buttontransposeup->registerPushCallback(handleTransposeUp); + buttontransposeup->registerPushCallback(handleSelTransposeUp); tbeffects = new ToggleButton(tabbox_endx + 18, add_oct_number_y + 1, 16, 16, sub_screen); tbeffects->setBitmap(icon_fx_raw, 12, 12); @@ -4334,11 +4381,40 @@ void updateSampleOffsetGuide(void) // Update the state for certain keypresses -void handleButtons(u16 buttons, u16 buttonsheld) +void handleButtons(u16 buttons, u16 buttonsheld, u16 buttonsup) { u16 ptnlen = song->getPatternLength(song->getPotEntry(state->potpos)); + bool pv_changed = false; + + static bool a_no_dpad_pressed; + + if(buttons & PlatformKey_A) + { + a_no_dpad_pressed = true; + } + else if(buttonsup & PlatformKey_A) + { + if(a_no_dpad_pressed) + { + pv->setPerComponentNav(!pv->isPerComponentNav()); + pv_changed = true; + a_no_dpad_pressed = false; + } + } + else if(buttonsheld & PlatformKey_A) + { + a_no_dpad_pressed &= (buttonsheld & (PlatformKey_UP | PlatformKey_DOWN | PlatformKey_LEFT | PlatformKey_RIGHT)) == 0; + if(buttons & PlatformKey_UP) + handleInPlaceTranspose(1, true); + if(buttons & PlatformKey_DOWN) + handleInPlaceTranspose(-1, true); + if(buttons & PlatformKey_LEFT) + handleInPlaceTranspose(-1, false); + if(buttons & PlatformKey_RIGHT) + handleInPlaceTranspose(1, false); + } - if(!(buttonsheld & PlatformKey_R)) + if(!(buttonsheld & (PlatformKey_R | PlatformKey_A))) { if(buttons & PlatformKey_UP) { @@ -4355,10 +4431,7 @@ void handleButtons(u16 buttons, u16 buttonsheld) state->setCursorRow(newrow); - pv->updateSelection(); - updateSampleOffsetGuide(); - redraw_main_requested = true; - + pv_changed = true; } else if(buttons & PlatformKey_DOWN) { @@ -4374,30 +4447,48 @@ void handleButtons(u16 buttons, u16 buttonsheld) state->setCursorRow(newrow); - pv->updateSelection(); - updateSampleOffsetGuide(); - redraw_main_requested = true; + pv_changed = true; } } - if((buttons & PlatformKey_LEFT)&&(!typewriter_active)) + if(!(buttonsheld & PlatformKey_A) && !typewriter_active) { - if(state->channel>0) { - state->channel--; - pv->updateSelection(); - updateSampleOffsetGuide(); - redraw_main_requested = true; - } - } - else if((buttons & PlatformKey_RIGHT)&&(!typewriter_active)) - { - if(state->channel < song->getChannels()-1) - { - state->channel++; - pv->updateSelection(); - updateSampleOffsetGuide(); - redraw_main_requested = true; - } + int offset = 0; + int chnOffset = 0; + if(buttons & PlatformKey_LEFT) + { + offset = -1; + } + else if(buttons & PlatformKey_RIGHT) + { + offset = 1; + } + + if(pv->isPerComponentNav()) + { + int newComponentOffset = pv->getComponentNavOffset() + offset; + if(newComponentOffset >= 0 && newComponentOffset <= pv->getMaxComponentNavOffset()) + { + pv->setComponentNavOffset(newComponentOffset); + pv_changed = true; + } + else + { + chnOffset = offset; + } + } + else + { + chnOffset = offset; + } + + if(chnOffset && (state->channel + chnOffset) >= 0 && (state->channel + chnOffset) < song->getChannels()) + { + state->channel += chnOffset; + if(pv->isPerComponentNav()) + pv->setComponentNavOffset((chnOffset >= 0) ? 0 : pv->getMaxComponentNavOffset()); + pv_changed = true; + } } else if(buttons & PlatformKey_START) { @@ -4427,6 +4518,13 @@ void handleButtons(u16 buttons, u16 buttonsheld) } */ #endif + + if(pv_changed) + { + pv->updateSelection(); + updateSampleOffsetGuide(); + redraw_main_requested = true; + } } void VblankHandler(void) @@ -4450,7 +4548,7 @@ void VblankHandler(void) lasty = -255; } - if( (PlatformKeysHeld & PlatformKey_TOUCH) && ( (abs(PlatformTouchX - lastx)>0) || (abs(PlatformTouchY - lasty)>0) ) ) // PenMove + if( (PlatformKeysHeld & PlatformKey_TOUCH) && ((PlatformTouchX != lastx) || (PlatformTouchY != lasty)) ) { gui->penMove(PlatformTouchX, PlatformTouchY, touchScreen); lastx = PlatformTouchX; @@ -4467,7 +4565,7 @@ void VblankHandler(void) move_to_top(); } - if(PlatformKeysDown & ~PlatformKey_TOUCH) + if((PlatformKeysDown | PlatformKeysUp) & ~PlatformKey_TOUCH) { if((PlatformKeysDown & PlatformKey_X)||(PlatformKeysDown & PlatformKey_L)) { switchScreens(); @@ -4477,9 +4575,9 @@ void VblankHandler(void) fastscroll = true; } - gui->buttonPress(PlatformKeysDown); - handleButtons(PlatformKeysDown, PlatformKeysHeld); - pv->pleaseDraw(); + if(PlatformKeysDown & ~PlatformKey_TOUCH) + gui->buttonPress(PlatformKeysDown); + handleButtons(PlatformKeysDown, PlatformKeysHeld, PlatformKeysUp); } if(PlatformKeysUp) diff --git a/common/source/tobkit/patternview.cpp b/common/source/tobkit/patternview.cpp index 1548c7f..40408f4 100644 --- a/common/source/tobkit/patternview.cpp +++ b/common/source/tobkit/patternview.cpp @@ -40,9 +40,10 @@ PatternView::PatternView(u16 _x, u16 _y, u16 _width, u16 _height, Screen *_scree :Widget(_x, _y, _width, _height, _screen), onMute(0), pattern(0), song(0), state(_state), hscrollpos(0), lines_per_beat(8), selection_exists(false), pen_down(false), - effects_visible(true), cell_width(50) + effects_visible(true), + componentpos(0), componentnav(false) { - for(int i=0;i<32;++i) + for(int i=0;ichannel-hscrollpos)*getCellWidth(), PV_CURSORBAR_Y, getCellWidth()+1, PV_CELL_HEIGHT+1, theme->col_pv_pb_cell); - drawGradient(theme->col_pv_cb_col1_highlight, theme->col_pv_cb_col2_highlight, PV_BORDER_WIDTH+(state->channel-hscrollpos)*getCellWidth(), - PV_CURSORBAR_Y+1, getCellWidth()-1, PV_CELL_HEIGHT-1); + int cursorX = 0; + int cursorWidth = getCellWidth(); + if(componentnav) { + // Per-component navigation + if(componentpos >= PV_COMPONENT_EFFECT && !effects_visible) componentpos = PV_COMPONENT_VOLUME; + switch(componentpos) { + case PV_COMPONENT_NOTE: cursorX = PV_CELL_NOTE_X; cursorWidth = PV_CELL_NOTE_WIDTH; break; + case PV_COMPONENT_INSTRUMENT: cursorX = PV_CELL_INST_X; cursorWidth = PV_CELL_INST_WIDTH; break; + case PV_COMPONENT_VOLUME: cursorX = PV_CELL_VOL_X; cursorWidth = PV_CELL_VOL_WIDTH; break; + case PV_COMPONENT_EFFECT: cursorX = PV_CELL_FX_X; cursorWidth = PV_CHAR_WIDTH; break; + case PV_COMPONENT_EFFECT_PARAM: cursorX = PV_CELL_FX_X+PV_CHAR_WIDTH; cursorWidth = 2*PV_CHAR_WIDTH; break; + } + cursorX -= 1; cursorWidth += 2; + } + drawBox(PV_BORDER_WIDTH-1+(state->channel-hscrollpos)*getCellWidth()+cursorX, PV_CURSORBAR_Y, cursorWidth+1, PV_CELL_HEIGHT+1, theme->col_pv_pb_cell); + drawGradient(theme->col_pv_cb_col1_highlight, theme->col_pv_cb_col2_highlight, PV_BORDER_WIDTH+(state->channel-hscrollpos)*getCellWidth()+cursorX, + PV_CURSORBAR_Y+1, cursorWidth-1, PV_CELL_HEIGHT-1); // Numbers on the left s16 ip; @@ -354,11 +369,7 @@ void PatternView::draw(void) { if((firstrow+j>=0)&&(firstrow+jnote == STOP_NOTE) { - drawSmallChar(DOT, realx , realy, notecol); - drawSmallChar(MINUS, realx+1*PV_CHAR_WIDTH, realy, notecol); - drawSmallChar(DOT, realx+2*PV_CHAR_WIDTH, realy, notecol); + drawSmallChar(DOT, realx+PV_CELL_NOTE_X, realy, notecol); + drawSmallChar(MINUS, realx+PV_CELL_NOTE_X+PV_CHAR_WIDTH, realy, notecol); + drawSmallChar(DOT, realx+PV_CELL_NOTE_X+2*PV_CHAR_WIDTH, realy, notecol); } else if(cell->note != EMPTY_NOTE) { // Note - drawSmallChar(notes_chars[cell->note%12], realx, realy, notecol); + drawSmallChar(notes_chars[cell->note%12], realx+PV_CELL_NOTE_X, realy, notecol); if(notes_signs[cell->note%12]) { - drawSmallChar(SHARP, realx+1*PV_CHAR_WIDTH, realy, notecol); + drawSmallChar(SHARP, realx+PV_CELL_NOTE_X+PV_CHAR_WIDTH, realy, notecol); } else { - drawSmallChar(MINUS, realx+1*PV_CHAR_WIDTH, realy, notecol); + drawSmallChar(MINUS, realx+PV_CELL_NOTE_X+PV_CHAR_WIDTH, realy, notecol); } - drawSmallChar(cell->note/12, realx+2*PV_CHAR_WIDTH, realy, notecol); + drawSmallChar(cell->note/12, realx+PV_CELL_NOTE_X+2*PV_CHAR_WIDTH, realy, notecol); } // Instrument if(cell->instrument != NO_INSTRUMENT) - drawHexByte(cell->instrument+1, realx+3*PV_CHAR_WIDTH+1, realy, instrcol); // Adding one because FT2 indices start with 1 + drawHexByte(cell->instrument+1, realx+PV_CELL_INST_X, realy, instrcol); // Adding one because FT2 indices start with 1 if (cell->volume != NO_VOLUME) { - drawHexByte(cell->volume, realx + 5 * PV_CHAR_WIDTH + 2, realy, volumecol); + drawHexByte(cell->volume, realx+PV_CELL_VOL_X, realy, volumecol); } // volume effect column slightly buggy and needs @@ -260,10 +286,10 @@ class PatternView: public Widget { if(effects_visible) { // Effect and effect parameter if (cell->effect != 0xff) - drawSmallChar(cell->effect, realx+7*PV_CHAR_WIDTH+3, realy, effectcol); + drawSmallChar(cell->effect, realx+PV_CELL_FX_X, realy, effectcol); if (cell->effect_param != 0x00 || cell->effect != 0xff) - drawHexByte(cell->effect_param, realx+8*PV_CHAR_WIDTH+3, realy, effectparamcol); + drawHexByte(cell->effect_param, realx+PV_CELL_FX_X+PV_CHAR_WIDTH, realy, effectparamcol); } } @@ -271,12 +297,10 @@ class PatternView: public Widget { inline u16 getCellWidth(void) { - if (effects_visible) { - cell_width = 45; - } else { - cell_width = 32; - } - return cell_width; + if (effects_visible) + return PV_CELL_WIDTH_FX; + else + return PV_CELL_WIDTH; } inline u16 getEffectiveWidth(void) @@ -304,7 +328,6 @@ class PatternView: public Widget { return getNumVisibleRows()/2-1; } - void callMuteCallback(void); void (*onMute)(bool *channels_muted); @@ -318,7 +341,8 @@ class PatternView: public Widget { u16 col_notes, col_instr, col_volume, col_effect, col_effect_param, col_notes_dark, col_instr_dark, col_volume_dark, col_effect_dark, col_effect_param_dark; - u16 hscrollpos, lines_per_beat; + u8 hscrollpos; + u16 lines_per_beat; bool selection_exists, pen_down; bool effects_visible; @@ -328,8 +352,11 @@ class PatternView: public Widget { u16 sel_start_x, sel_end_x, sel_start_y, sel_end_y; u16 sel_x, sel_y, sel_w, sel_h; - bool solo_channels[32]; - bool mute_channels[32]; + bool solo_channels[MAX_CHANNELS]; + bool mute_channels[MAX_CHANNELS]; + + u8 componentpos; + bool componentnav; }; };