diff --git a/src/drivers/win/help/fceux.chm b/src/drivers/win/help/fceux.chm index 4444252c..aa5f7855 100644 Binary files a/src/drivers/win/help/fceux.chm and b/src/drivers/win/help/fceux.chm differ diff --git a/src/drivers/win/taseditor/bookmarks.cpp b/src/drivers/win/taseditor/bookmarks.cpp index 9f47d59c..4904f23b 100644 --- a/src/drivers/win/taseditor/bookmarks.cpp +++ b/src/drivers/win/taseditor/bookmarks.cpp @@ -766,7 +766,7 @@ LRESULT APIENTRY BookmarksListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM return 0; } case WM_MOUSEWHEEL: - bookmarks.bookmark_rightclicked = -1; + bookmarks.bookmark_rightclicked = -1; // ensure that accidental rightclick on BookmarksList won't set Bookmarks when user does rightbutton + wheel return SendMessage(piano_roll.hwndList, msg, wParam, lParam); } diff --git a/src/drivers/win/taseditor/piano_roll.cpp b/src/drivers/win/taseditor/piano_roll.cpp index 5571c7a2..ae8d55ca 100644 --- a/src/drivers/win/taseditor/piano_roll.cpp +++ b/src/drivers/win/taseditor/piano_roll.cpp @@ -11,12 +11,13 @@ Piano Roll - Piano Roll interface [Singleton] * implements the working of Piano Roll List: creating, redrawing, scrolling, mouseover, clicks, drag +* regularly updates the size of the List according to current movie input * on demand: scrolls visible area of the List to any given item: to Playback Cursor, to Selection Cursor, to "undo pointer", to a Marker * saves and loads current position of vertical scrolling from a project file. On error: scrolls the List to the beginning * implements the working of Piano Roll List Header: creating, redrawing, animating, mouseover, clicks -* on demand: launches flashes in the List Header -* regularly updates the size of the List according to current movie input, also updates lights in the List Header according to button presses data from Recorder and Alt key state -* implements the working of mouse wheel: List scrolling, Playback cursor movement, Selection cursor movement +* regularly updates lights in the Header according to button presses data from Recorder and Alt key state +* on demand: launches flashes in the Header +* implements the working of mouse wheel: List scrolling, Playback cursor movement, Selection cursor movement, scrolling across gaps in Input/markers * implements context menu on Right-click * updates mouse cursor icon depending on item under cursor * stores resources: save id, ids of columns, widths of columns, tables of colors, gradient of Hot Changes, gradient of Header flashings, timings of flashes, all fonts used in TAS Editor, images @@ -856,6 +857,10 @@ void PIANO_ROLL::FollowMarker(int marker_id) ListView_EnsureVisible(hwndList, 0, false); } } +void PIANO_ROLL::EnsureVisible(int row_index) +{ + ListView_EnsureVisible(hwndList, row_index, false); +} void PIANO_ROLL::ColumnSet(int column, bool alt_pressed) { @@ -1331,6 +1336,113 @@ void PIANO_ROLL::RightClick(LVHITTESTINFO& info) TrackPopupMenu(sub, 0, pt.x, pt.y, 0, taseditor_window.hwndTasEditor, 0); } } + +void PIANO_ROLL::CrossGaps(int zDelta) +{ + POINT p; + if (GetCursorPos(&p)) + { + ScreenToClient(hwndList, &p); + RECT wrect; + GetClientRect(hwndList, &wrect); + if (p.x >= 0 && p.x < wrect.right - wrect.left && p.y >= list_row_top && p.y < wrect.bottom - wrect.top) + { + // perform hit test + LVHITTESTINFO info; + info.pt.x = p.x; + info.pt.y = p.y; + ListView_SubItemHitTest(hwndList, &info); + int row_index = info.iItem; + int column_index = info.iSubItem; + if (row_index >= 0 && column_index >= COLUMN_FRAMENUM && column_index <= COLUMN_FRAMENUM2) + { + if (column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2) + { + // cross gaps in Markers + if (zDelta < 0) + { + // search down + int last_frame = currMovieData.getNumRecords() - 1; + if (row_index < last_frame) + { + int frame = row_index + 1; + bool result_of_closest_frame = (markers_manager.GetMarker(frame) != 0); + while ((++frame) <= last_frame) + { + if ((markers_manager.GetMarker(frame) != 0) != result_of_closest_frame) + { + // found different result, so we crossed the gap + ListView_Scroll(hwndList, 0, list_row_height * (frame - row_index)); + break; + } + } + } + } else + { + // search up + int first_frame = 0; + if (row_index > first_frame) + { + int frame = row_index - 1; + bool result_of_closest_frame = (markers_manager.GetMarker(frame) != 0); + while ((--frame) >= first_frame) + { + if ((markers_manager.GetMarker(frame) != 0) != result_of_closest_frame) + { + // found different result, so we crossed the gap + ListView_Scroll(hwndList, 0, list_row_height * (frame - row_index)); + break; + } + } + } + } + } else + { + // cross gaps in Input + int joy = (column_index - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS; + int button = (column_index - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS; + if (zDelta < 0) + { + // search down + int last_frame = currMovieData.getNumRecords() - 1; + if (row_index < last_frame) + { + int frame = row_index + 1; + bool result_of_closest_frame = currMovieData.records[frame].checkBit(joy, button); + while ((++frame) <= last_frame) + { + if (currMovieData.records[frame].checkBit(joy, button) != result_of_closest_frame) + { + // found different result, so we crossed the gap + ListView_Scroll(hwndList, 0, list_row_height * (frame - row_index)); + break; + } + } + } + } else + { + // search up + int first_frame = 0; + if (row_index > first_frame) + { + int frame = row_index - 1; + bool result_of_closest_frame = currMovieData.records[frame].checkBit(joy, button); + while ((--frame) >= first_frame) + { + if (currMovieData.records[frame].checkBit(joy, button) != result_of_closest_frame) + { + // found different result, so we crossed the gap + ListView_Scroll(hwndList, 0, list_row_height * (frame - row_index)); + break; + } + } + } + } + } + } + } + } +} // ------------------------------------------------------------------------- LRESULT APIENTRY HeaderWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { @@ -1566,12 +1678,9 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) selection.JumpNextMarker(-zDelta / WHEEL_DELTA); else if (zDelta > 0) selection.JumpPrevMarker(zDelta / WHEEL_DELTA); - } else if (alt_pressed || fwKeys & MK_RBUTTON) + } else if (fwKeys & MK_RBUTTON) { - // Right button + wheel = Alt + wheel = rewind/forward - // if both Right button and Alt are pressed, move 4x faster - if (alt_pressed && fwKeys & MK_RBUTTON) - zDelta *= BOOST_WHEN_BOTH_RIGHTBUTTON_AND_ALT_PRESSED; + // Right button + wheel = rewind/forward int destination_frame = currFrameCounter - (zDelta / WHEEL_DELTA); if (destination_frame < 0) destination_frame = 0; int lastCursor = currFrameCounter; @@ -1585,6 +1694,10 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) } else if (history.CursorOverHistoryList()) { return SendMessage(history.hwndHistoryList, WM_MOUSEWHEEL_RESENT, wParam, lParam); + } else if (alt_pressed) + { + // cross gaps in input/Markers + piano_roll.CrossGaps(zDelta); } else { // normal scrolling - make it 2x faster than usual diff --git a/src/drivers/win/taseditor/piano_roll.h b/src/drivers/win/taseditor/piano_roll.h index 01ab5f65..76b622c6 100644 --- a/src/drivers/win/taseditor/piano_roll.h +++ b/src/drivers/win/taseditor/piano_roll.h @@ -18,7 +18,6 @@ #define HEADER_DX_FIX 4 #define PIANO_ROLL_SCROLLING_BOOST 2 -#define BOOST_WHEN_BOTH_RIGHTBUTTON_AND_ALT_PRESSED 4 #define MARKER_DRAG_BOX_ALPHA 175 #define MARKER_DRAG_COUNTDOWN_MAX 14 @@ -160,6 +159,7 @@ public: void FollowSelection(); void FollowPauseframe(); void FollowMarker(int marker_id); + void EnsureVisible(int row_index); void ColumnSet(int column, bool alt_pressed); @@ -175,6 +175,8 @@ public: void RightClick(LVHITTESTINFO& info); + void CrossGaps(int zDelta); + int header_item_under_mouse; HWND hwndList, hwndHeader; TRACKMOUSEEVENT tme; diff --git a/src/drivers/win/taseditor/taseditor_window.cpp b/src/drivers/win/taseditor/taseditor_window.cpp index 2755aed6..f451b76c 100644 --- a/src/drivers/win/taseditor/taseditor_window.cpp +++ b/src/drivers/win/taseditor/taseditor_window.cpp @@ -84,15 +84,15 @@ Window_items_struct window_items[TASEDITOR_WINDOW_TOTAL_ITEMS] = { IDC_BOOKMARKS_BOX, -1, 0, 0, 0, "", "", false, 0, 0, IDC_HISTORY_BOX, -1, 0, 0, -1, "", "", false, 0, 0, TASEDITOR_REWIND_FULL, -1, 0, 0, 0, "Send Playback to previous Marker (mouse: Shift+Wheel up) (hotkey: Shift+PageUp)", "", false, 0, 0, - TASEDITOR_REWIND, -1, 0, 0, 0, "Rewind 1 frame (mouse: Right button+Wheel up) (Alt+Wheel up) (hotkey: Shift+Up)", "", false, 0, 0, // EMUCMD_TASEDITOR_REWIND + TASEDITOR_REWIND, -1, 0, 0, 0, "Rewind 1 frame (mouse: Right button+Wheel up) (hotkey: Shift+Up)", "", false, 0, 0, // EMUCMD_TASEDITOR_REWIND TASEDITOR_PLAYSTOP, -1, 0, 0, 0, "Pause/Unpause Emulation (mouse: Middle button)", "", false, EMUCMD_PAUSE, 0, - TASEDITOR_FORWARD, -1, 0, 0, 0, "Advance (mouse: Right button+Wheel down) (Alt+Wheel down) (hotkey: Shift+Down)", "", false, 0, 0, + TASEDITOR_FORWARD, -1, 0, 0, 0, "Advance 1 frame (mouse: Right button+Wheel down) (hotkey: Shift+Down)", "", false, 0, 0, TASEDITOR_FORWARD_FULL, -1, 0, 0, 0, "Send Playback to next Marker (mouse: Shift+Wheel down) (hotkey: Shift+PageDown)", "", false, 0, 0, IDC_PROGRESS1, -1, 0, 0, 0, "", "", false, 0, 0, CHECK_FOLLOW_CURSOR, -1, 0, 0, 0, "The Piano Roll will follow Playback cursor movements", "", false, 0, 0, CHECK_AUTORESTORE_PLAYBACK, -1, 0, 0, 0, "If you change input above Playback, cursor will run where it was before change", "", false, 0, 0, IDC_BOOKMARKSLIST, -1, 0, 0, 0, "Right click = set Bookmark, Left click = jump to Bookmark or load Branch", "", false, 0, 0, - IDC_HISTORYLIST, -1, 0, 0, -1, "Click to revert movie back to that time", "", false, 0, 0, + IDC_HISTORYLIST, -1, 0, 0, -1, "Click to revert the movie back to that time", "", false, 0, 0, IDC_RADIO_ALL, -1, 0, 0, 0, "", "", false, 0, 0, IDC_RADIO_1P, -1, 0, 0, 0, "", "", false, 0, 0, IDC_RADIO_2P, -1, 0, 0, 0, "", "", false, 0, 0, @@ -1246,7 +1246,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara if (selection_beginning >= 0) { selection.Transpose(-selection_beginning); - piano_roll.FollowSelection(); + piano_roll.EnsureVisible(0); } } break; @@ -1260,7 +1260,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara if (selection_end >= 0) { selection.Transpose(currMovieData.getNumRecords() - 1 - selection_end); - piano_roll.FollowSelection(); + piano_roll.EnsureVisible(currMovieData.getNumRecords() - 1); } } break; @@ -1278,7 +1278,9 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara if (piano_roll.drag_mode != DRAG_MODE_SELECTION) { selection.Transpose(-1); - piano_roll.FollowSelection(); + int selection_beginning = selection.GetCurrentSelectionBeginning(); + if (selection_beginning >= 0) + piano_roll.EnsureVisible(selection_beginning); } break; case ACCEL_CTRL_DOWN: @@ -1286,7 +1288,9 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara if (piano_roll.drag_mode != DRAG_MODE_SELECTION) { selection.Transpose(1); - piano_roll.FollowSelection(); + int selection_end = selection.GetCurrentSelectionEnd(); + if (selection_end >= 0) + piano_roll.EnsureVisible(selection_end); } break; case ACCEL_CTRL_LEFT: diff --git a/vc/Help/fceux.hnd b/vc/Help/fceux.hnd index d882a2d4..492cdba7 100644 Binary files a/vc/Help/fceux.hnd and b/vc/Help/fceux.hnd differ