diff --git a/src/drivers/win/log.cpp b/src/drivers/win/log.cpp index 9451078e..5a1f0d82 100644 --- a/src/drivers/win/log.cpp +++ b/src/drivers/win/log.cpp @@ -66,7 +66,7 @@ void RedoText(void) } SetDlgItemText(logwin, LBL_LOG_TEXT, textbuf); - SendDlgItemMessage(logwin, LBL_LOG_TEXT, EM_LINESCROLL, 0, 200); + SendDlgItemMessage(logwin, LBL_LOG_TEXT, EM_LINESCROLL, 0, MAXIMUM_NUMBER_OF_LOGS); } /** diff --git a/src/drivers/win/log.h b/src/drivers/win/log.h index d0b7a361..80d0bca2 100644 --- a/src/drivers/win/log.h +++ b/src/drivers/win/log.h @@ -1,4 +1,4 @@ -#define MAXIMUM_NUMBER_OF_LOGS 256 +#define MAXIMUM_NUMBER_OF_LOGS 1024 #define DONT_ADD_NEWLINE 0 #define DO_ADD_NEWLINE 1 diff --git a/src/drivers/win/main.cpp b/src/drivers/win/main.cpp index 2b06750a..cc9ca568 100644 --- a/src/drivers/win/main.cpp +++ b/src/drivers/win/main.cpp @@ -60,7 +60,6 @@ #include "tracer.h" #include "cdlogger.h" #include "throttle.h" -#include "tasedit.h" #include "replay.h" #include "palette.h" //For the SetPalette function #include "main.h" @@ -857,6 +856,7 @@ void _updateWindow() //UpdateLogWindow(); //adelikat: Moved to FCEUI_Emulate UpdateMemWatch(); NTViewDoBlit(0); + extern void UpdateTasEdit(); UpdateTasEdit(); } diff --git a/src/drivers/win/tasedit.cpp b/src/drivers/win/tasedit.cpp index 14873f4b..be66956d 100644 --- a/src/drivers/win/tasedit.cpp +++ b/src/drivers/win/tasedit.cpp @@ -1,14 +1,13 @@ -#include +#include // #include #include #include "taseditlib/taseditproj.h" -#include "fceu.h" -#include "debugger.h" +#include "fceu.h" // #include "replay.h" #include "utils/xstring.h" #include "Win32InputBox.h" -#include "window.h" +#include "window.h" // #include "keyboard.h" #include "joystick.h" #include "help.h" @@ -21,14 +20,12 @@ int old_multitrack_recording_joypad, multitrack_recording_joypad; bool old_movie_readonly; bool TASEdit_focus = false; bool Tasedit_rewind_now = false; -int listItems; // number of items per list page // saved FCEU config int saved_eoptions; int saved_EnableAutosave; extern int EnableAutosave; -extern HWND hwndScrBmp; extern EMOVIEMODE movieMode; // maybe we need normal setter for movieMode, to encapsulate it // vars saved in cfg file @@ -59,22 +56,11 @@ char windowCaptions[6][30] = { "TAS Editor", "TAS Editor (Recording 2P)", "TAS Editor (Recording 3P)", "TAS Editor (Recording 4P)"}; -COLORREF hot_changes_colors[16] = { 0x0, 0x661212, 0x842B4E, 0x652C73, 0x48247D, 0x383596, 0x2947AE, 0x1E53C1, 0x135DD2, 0x116EDA, 0x107EE3, 0x0F8EEB, 0x209FF4, 0x3DB1FD, 0x51C2FF, 0x4DCDFF }; HWND hwndTasEdit = 0; HMENU hmenu, hrmenu; -HWND hwndList, hwndHeader; -WNDPROC hwndList_oldWndProc, hwndHeader_oldWndproc; -HWND hwndHistoryList; -WNDPROC hwndHistoryList_oldWndProc; -HWND hwndBookmarksList, hwndBookmarks; -WNDPROC hwndBookmarksList_oldWndProc; HWND hwndProgressbar, hwndRewind, hwndForward, hwndRewindFull, hwndForwardFull; HWND hwndRB_RecOff, hwndRB_RecAll, hwndRB_Rec1P, hwndRB_Rec2P, hwndRB_Rec3P, hwndRB_Rec4P; -HWND hwndBranchesBitmap; -WNDPROC hwndBranchesBitmap_oldWndProc; - -HFONT hMainListFont, hMainListSelectFont; // all Taseditor functional modules TASEDIT_PROJECT project; @@ -83,202 +69,15 @@ PLAYBACK playback; GREENZONE greenzone; MARKERS markers; BOOKMARKS bookmarks; +TASEDIT_LIST tasedit_list; TASEDIT_SELECTION selection; -void GetDispInfo(NMLVDISPINFO* nmlvDispInfo) -{ - LVITEM& item = nmlvDispInfo->item; - if(item.mask & LVIF_TEXT) - { - switch(item.iSubItem) - { - case COLUMN_ICONS: - { - if(item.iImage == I_IMAGECALLBACK) - { - item.iImage = bookmarks.FindBookmarkAtFrame(item.iItem); - if (item.iImage < 0) - { - if (item.iItem == currFrameCounter) - item.iImage = ARROW_IMAGE_ID; - } - } - break; - } - case COLUMN_FRAMENUM: - case COLUMN_FRAMENUM2: - { - U32ToDecStr(item.pszText, item.iItem, DIGITS_IN_FRAMENUM); - break; - } - case COLUMN_JOYPAD1_A: case COLUMN_JOYPAD1_B: case COLUMN_JOYPAD1_S: case COLUMN_JOYPAD1_T: - case COLUMN_JOYPAD1_U: case COLUMN_JOYPAD1_D: case COLUMN_JOYPAD1_L: case COLUMN_JOYPAD1_R: - case COLUMN_JOYPAD2_A: case COLUMN_JOYPAD2_B: case COLUMN_JOYPAD2_S: case COLUMN_JOYPAD2_T: - case COLUMN_JOYPAD2_U: case COLUMN_JOYPAD2_D: case COLUMN_JOYPAD2_L: case COLUMN_JOYPAD2_R: - case COLUMN_JOYPAD3_A: case COLUMN_JOYPAD3_B: case COLUMN_JOYPAD3_S: case COLUMN_JOYPAD3_T: - case COLUMN_JOYPAD3_U: case COLUMN_JOYPAD3_D: case COLUMN_JOYPAD3_L: case COLUMN_JOYPAD3_R: - case COLUMN_JOYPAD4_A: case COLUMN_JOYPAD4_B: case COLUMN_JOYPAD4_S: case COLUMN_JOYPAD4_T: - case COLUMN_JOYPAD4_U: case COLUMN_JOYPAD4_D: case COLUMN_JOYPAD4_L: case COLUMN_JOYPAD4_R: - { - int joy = (item.iSubItem - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS; - int bit = (item.iSubItem - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS; - uint8 data = currMovieData.records[item.iItem].joysticks[joy]; - if(data & (1<nmcd.dwDrawStage) - { - case CDDS_PREPAINT: - return CDRF_NOTIFYITEMDRAW; - case CDDS_ITEMPREPAINT: - return CDRF_NOTIFYSUBITEMDRAW; - case CDDS_SUBITEMPREPAINT: - cell_x = msg->iSubItem; - cell_y = msg->nmcd.dwItemSpec; - - - - if(cell_x > COLUMN_ICONS) - { - SelectObject(msg->nmcd.hdc, hMainListFont); - // text color - if(TASEdit_enable_hot_changes && cell_x >= COLUMN_JOYPAD1_A && cell_x <= COLUMN_JOYPAD4_R) - { - msg->clrText = hot_changes_colors[history.GetCurrentSnapshot().GetHotChangeInfo(cell_y, cell_x - COLUMN_JOYPAD1_A)]; - } else msg->clrText = NORMAL_TEXT_COLOR; - // bg color - if(cell_x == COLUMN_FRAMENUM || cell_x == COLUMN_FRAMENUM2) - { - // frame number - if (cell_y == history.GetUndoHint()) - { - // undo hint here - if(TASEdit_show_markers && (int)markers.markers_array.size() > cell_y && (markers.markers_array[cell_y] & MARKER_FLAG_BIT)) - msg->clrTextBk = MARKED_UNDOHINT_FRAMENUM_COLOR; - else - msg->clrTextBk = UNDOHINT_FRAMENUM_COLOR; - } else if (cell_y == currFrameCounter || cell_y == playback.GetPauseFrame()) - { - // current frame - if(TASEdit_show_markers && (int)markers.markers_array.size() > cell_y && (markers.markers_array[cell_y] & MARKER_FLAG_BIT)) - // this frame is also marked - msg->clrTextBk = CUR_MARKED_FRAMENUM_COLOR; - else - msg->clrTextBk = CUR_FRAMENUM_COLOR; - } else if(TASEdit_show_markers && (int)markers.markers_array.size() > cell_y && (markers.markers_array[cell_y] & MARKER_FLAG_BIT)) - { - // marked frame - msg->clrTextBk = MARKED_FRAMENUM_COLOR; - } else if(cell_y < greenzone.greenZoneCount) - { - if (!greenzone.savestates[cell_y].empty()) - { - if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) - msg->clrTextBk = LAG_FRAMENUM_COLOR; - else - msg->clrTextBk = GREENZONE_FRAMENUM_COLOR; - } else if ((!greenzone.savestates[cell_y & EVERY16TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0xF) + 1 && !greenzone.savestates[(cell_y | 0xF) + 1].empty()) - || (!greenzone.savestates[cell_y & EVERY8TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x7) + 1 && !greenzone.savestates[(cell_y | 0x7) + 1].empty()) - || (!greenzone.savestates[cell_y & EVERY4TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x3) + 1 && !greenzone.savestates[(cell_y | 0x3) + 1].empty()) - || (!greenzone.savestates[cell_y & EVERY2ND].empty() && !greenzone.savestates[(cell_y | 0x1) + 1].empty())) - { - if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) - msg->clrTextBk = PALE_LAG_FRAMENUM_COLOR; - else - msg->clrTextBk = PALE_GREENZONE_FRAMENUM_COLOR; - } else msg->clrTextBk = NORMAL_FRAMENUM_COLOR; - } else msg->clrTextBk = NORMAL_FRAMENUM_COLOR; - } else if((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 0 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 2) - { - // pad 1 or 3 - if (cell_y == history.GetUndoHint()) - { - // undo hint here - msg->clrTextBk = UNDOHINT_INPUT_COLOR1; - } else if (cell_y == currFrameCounter || cell_y == playback.GetPauseFrame()) - { - // current frame - msg->clrTextBk = CUR_INPUT_COLOR1; - } else if(cell_y < greenzone.greenZoneCount) - { - if (!greenzone.savestates[cell_y].empty()) - { - if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) - msg->clrTextBk = LAG_INPUT_COLOR1; - else - msg->clrTextBk = GREENZONE_INPUT_COLOR1; - } else if ((!greenzone.savestates[cell_y & EVERY16TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0xF) + 1 && !greenzone.savestates[(cell_y | 0xF) + 1].empty()) - || (!greenzone.savestates[cell_y & EVERY8TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x7) + 1 && !greenzone.savestates[(cell_y | 0x7) + 1].empty()) - || (!greenzone.savestates[cell_y & EVERY4TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x3) + 1 && !greenzone.savestates[(cell_y | 0x3) + 1].empty()) - || (!greenzone.savestates[cell_y & EVERY2ND].empty() && !greenzone.savestates[(cell_y | 0x1) + 1].empty())) - { - if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) - msg->clrTextBk = PALE_LAG_INPUT_COLOR1; - else - msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR1; - } else msg->clrTextBk = NORMAL_INPUT_COLOR1; - } else msg->clrTextBk = NORMAL_INPUT_COLOR1; - } else if((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 1 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 3) - { - // pad 2 or 4 - if (cell_y == history.GetUndoHint()) - { - // undo hint here - msg->clrTextBk = UNDOHINT_INPUT_COLOR2; - } else if (cell_y == currFrameCounter || cell_y == playback.GetPauseFrame()) - { - // current frame - msg->clrTextBk = CUR_INPUT_COLOR2; - } else if(cell_y < greenzone.greenZoneCount) - { - if (!greenzone.savestates[cell_y].empty()) - { - if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) - msg->clrTextBk = LAG_INPUT_COLOR2; - else - msg->clrTextBk = GREENZONE_INPUT_COLOR2; - } else if ((!greenzone.savestates[cell_y & EVERY16TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0xF) + 1 && !greenzone.savestates[(cell_y | 0xF) + 1].empty()) - || (!greenzone.savestates[cell_y & EVERY8TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x7) + 1 && !greenzone.savestates[(cell_y | 0x7) + 1].empty()) - || (!greenzone.savestates[cell_y & EVERY4TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x3) + 1 && !greenzone.savestates[(cell_y | 0x3) + 1].empty()) - || (!greenzone.savestates[cell_y & EVERY2ND].empty() && !greenzone.savestates[(cell_y | 0x1) + 1].empty())) - { - if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) - msg->clrTextBk = PALE_LAG_INPUT_COLOR2; - else - msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR2; - } else msg->clrTextBk = NORMAL_INPUT_COLOR2; - } else msg->clrTextBk = NORMAL_INPUT_COLOR2; - } - } - default: - return CDRF_DODEFAULT; - } -} - -// called from the rest of the emulator when things happen and the tasedit should change to reflect it +// enterframe function void UpdateTasEdit() { if(!hwndTasEdit) return; - UpdateList(); + tasedit_list.update(); markers.update(); greenzone.update(); playback.update(); @@ -286,7 +85,6 @@ void UpdateTasEdit() selection.update(); history.update(); project.update(); - selection.update(); // update window caption if (old_movie_readonly != movie_readonly || old_multitrack_recording_joypad != multitrack_recording_joypad) @@ -305,15 +103,6 @@ void UpdateTasEdit() } -void UpdateList() -{ - //update the number of items in the list - int currLVItemCount = ListView_GetItemCount(hwndList); - int movie_size = currMovieData.getNumRecords(); - if(currLVItemCount != movie_size) - ListView_SetItemCountEx(hwndList,movie_size,LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL); -} - void RedrawWindowCaption() { char windowCaption[300]; // 260 + 30 + 1 + ... @@ -337,22 +126,14 @@ void RedrawTasedit() { InvalidateRect(hwndTasEdit, 0, FALSE); } -void RedrawList() -{ - InvalidateRect(hwndList, 0, FALSE); -} void RedrawListAndBookmarks() { - InvalidateRect(hwndList, 0, FALSE); + tasedit_list.RedrawList(); bookmarks.RedrawBookmarksList(); } -void RedrawRow(int index) -{ - ListView_RedrawItems(hwndList, index, index); -} void RedrawRowAndBookmark(int index) { - ListView_RedrawItems(hwndList, index, index); + tasedit_list.RedrawRow(index); bookmarks.RedrawChangedBookmarks(index); } @@ -365,15 +146,15 @@ void ShowMenu(ECONTEXTMENU which, POINT& pt) void StrayClickMenu(LPNMITEMACTIVATE info) { POINT pt = info->ptAction; - ClientToScreen(hwndList,&pt); - ShowMenu(CONTEXTMENU_STRAY,pt); + ClientToScreen(tasedit_list.hwndList, &pt); + ShowMenu(CONTEXTMENU_STRAY, pt); } void RightClickMenu(LPNMITEMACTIVATE info) { POINT pt = info->ptAction; - ClientToScreen(hwndList,&pt); - ShowMenu(CONTEXTMENU_SELECTED,pt); + ClientToScreen(tasedit_list.hwndList, &pt); + ShowMenu(CONTEXTMENU_SELECTED, pt); } void RightClick(LPNMITEMACTIVATE info) @@ -403,12 +184,14 @@ void ToggleJoypadBit(int column_index, int row_index, UINT KeyFlags) int bit = (column_index - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS; if (KeyFlags & (LVKF_SHIFT|LVKF_CONTROL)) { - //update multiple rows - for(SelectionFrames::iterator it(selection.CurrentSelection().begin()); it != selection.CurrentSelection().end(); it++) + //update multiple rows + SelectionFrames* current_selection = selection.MakeStrobe(); + SelectionFrames::iterator current_selection_end(current_selection->end()); + for(SelectionFrames::iterator it(current_selection->begin()); it != current_selection_end; it++) { currMovieData.records[*it].toggleBit(joy,bit); } - greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_CHANGE, *selection.CurrentSelection().begin(), *selection.CurrentSelection().rbegin())); + greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_CHANGE, *current_selection->begin(), *current_selection->rbegin())); } else { //update one row @@ -444,9 +227,8 @@ void SingleClick(LPNMITEMACTIVATE info) else history.RegisterChanges(MODTYPE_MARKER_UNSET, row_index); project.SetProjectChanged(); - // deselect this row, so that new marker will be seen immediately - ListView_SetItemState(hwndList, row_index, 0, LVIS_SELECTED); - ListView_SetItemState(hwndList, -1, LVIS_FOCUSED, LVIS_FOCUSED); + // clear selection, so that new marker will be seen immediately + selection.ClearSelection(); // also no need to redraw row } } @@ -475,19 +257,20 @@ void DoubleClick(LPNMITEMACTIVATE info) void CloneFrames() { - int frames = selection.CurrentSelection().size(); + SelectionFrames* current_selection = selection.MakeStrobe(); + int frames = current_selection->size(); if (!frames) return; currMovieData.records.reserve(currMovieData.getNumRecords() + frames); - //insert frames before each selection, but consecutive selection lines are accounted as single region frames = 1; SelectionFrames::reverse_iterator next_it; - for(SelectionFrames::reverse_iterator it(selection.CurrentSelection().rbegin()); it != selection.CurrentSelection().rend(); it++) + SelectionFrames::reverse_iterator current_selection_rend = current_selection->rend(); + for(SelectionFrames::reverse_iterator it(current_selection->rbegin()); it != current_selection_rend; it++) { next_it = it; next_it++; - if (next_it == selection.CurrentSelection().rend() || (int)*next_it < ((int)*it - 1)) + if (next_it == current_selection_rend || (int)*next_it < ((int)*it - 1)) { // end of current region currMovieData.cloneRegion(*it, frames); @@ -496,13 +279,14 @@ void CloneFrames() frames = 1; } else frames++; } - UpdateList(); - greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_CLONE, *selection.CurrentSelection().begin())); + //tasedit_list.update(); + greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_CLONE, *current_selection->begin())); } void InsertFrames() { - int frames = selection.CurrentSelection().size(); + SelectionFrames* current_selection = selection.MakeStrobe(); + int frames = current_selection->size(); if (!frames) return; //to keep this from being even slower than it would otherwise be, go ahead and reserve records @@ -511,11 +295,12 @@ void InsertFrames() //insert frames before each selection, but consecutive selection lines are accounted as single region frames = 1; SelectionFrames::reverse_iterator next_it; - for(SelectionFrames::reverse_iterator it(selection.CurrentSelection().rbegin()); it != selection.CurrentSelection().rend(); it++) + SelectionFrames::reverse_iterator current_selection_rend = current_selection->rend(); + for(SelectionFrames::reverse_iterator it(current_selection->rbegin()); it != current_selection_rend; it++) { next_it = it; next_it++; - if (next_it == selection.CurrentSelection().rend() || (int)*next_it < ((int)*it - 1)) + if (next_it == current_selection_rend || (int)*next_it < ((int)*it - 1)) { // end of current region currMovieData.insertEmpty(*it,frames); @@ -524,22 +309,23 @@ void InsertFrames() frames = 1; } else frames++; } - UpdateList(); - greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_INSERT, *selection.CurrentSelection().begin())); + //tasedit_list.update(); + greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_INSERT, *current_selection->begin())); } void InsertNumFrames() { - int frames = selection.CurrentSelection().size(); + SelectionFrames* current_selection = selection.MakeStrobe(); + int frames = current_selection->size(); if(CWin32InputBox::GetInteger("Insert number of Frames", "How many frames?", frames, hwndTasEdit) == IDOK) { if (frames > 0) { int index; - if (selection.CurrentSelection().size()) + if (current_selection->size()) { // insert at selection - index = *selection.CurrentSelection().begin(); + index = *current_selection->begin(); selection.ClearSelection(); } else { @@ -549,8 +335,8 @@ void InsertNumFrames() currMovieData.insertEmpty(index, frames); if (TASEdit_bind_markers) markers.insertEmpty(index, frames); - UpdateList(); // select inserted rows + tasedit_list.update(); selection.SetRegionSelection(index, index + frames - 1); greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_INSERT, index)); } @@ -559,11 +345,14 @@ void InsertNumFrames() void DeleteFrames() { - if (selection.CurrentSelection().size() == 0) return; - int start_index = *selection.CurrentSelection().begin(); - int end_index = *selection.CurrentSelection().rbegin(); + SelectionFrames* current_selection = selection.MakeStrobe(); + if (current_selection->size() == 0) return; + + int start_index = *current_selection->begin(); + int end_index = *current_selection->rbegin(); + SelectionFrames::reverse_iterator current_selection_rend = current_selection->rend(); //delete frames on each selection, going backwards - for(SelectionFrames::reverse_iterator it(selection.CurrentSelection().rbegin()); it != selection.CurrentSelection().rend(); it++) + for(SelectionFrames::reverse_iterator it(current_selection->rbegin()); it != current_selection_rend; it++) { currMovieData.records.erase(currMovieData.records.begin() + *it); if (TASEdit_bind_markers) @@ -573,7 +362,7 @@ void DeleteFrames() if (!currMovieData.getNumRecords()) playback.StartFromZero(); // reduce list - UpdateList(); + tasedit_list.update(); int result = history.RegisterChanges(MODTYPE_DELETE, start_index); if (result >= 0) @@ -582,37 +371,42 @@ void DeleteFrames() } else if (greenzone.greenZoneCount >= currMovieData.getNumRecords()) { greenzone.InvalidateAndCheck(currMovieData.getNumRecords()-1); - } else RedrawList(); + } else tasedit_list.RedrawList(); } -void ClearFrames(bool cut) +void ClearFrames(SelectionFrames* current_selection) { - if (selection.CurrentSelection().size() == 0) return; - //clear input on each selection - for(SelectionFrames::iterator it(selection.CurrentSelection().begin()); it != selection.CurrentSelection().end(); it++) + bool cut = true; + if (!current_selection) + { + cut = false; + current_selection = selection.MakeStrobe(); + if (current_selection->size() == 0) return; + } + + //clear input on each selected frame + SelectionFrames::iterator current_selection_end(current_selection->end()); + for(SelectionFrames::iterator it(current_selection->begin()); it != current_selection_end; it++) { currMovieData.records[*it].clear(); } if (cut) - greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_CUT, *selection.CurrentSelection().begin(), *selection.CurrentSelection().rbegin())); + greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_CUT, *current_selection->begin(), *current_selection->rbegin())); else - greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_CLEAR, *selection.CurrentSelection().begin(), *selection.CurrentSelection().rbegin())); + greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_CLEAR, *current_selection->begin(), *current_selection->rbegin())); } void Truncate() { - int frame = currFrameCounter; - if (selection.CurrentSelection().size()) - { - frame = *selection.CurrentSelection().begin(); - selection.ClearSelection(); - } + int frame = selection.GetCurrentSelectionBeginning(); + if (frame < 0) frame = currFrameCounter; + if (currMovieData.getNumRecords() > frame+1) { currMovieData.truncateAt(frame+1); if (TASEdit_bind_markers) markers.truncateAt(frame+1); - UpdateList(); + tasedit_list.update(); int result = history.RegisterChanges(MODTYPE_TRUNCATE, frame+1); if (result >= 0) { @@ -620,19 +414,24 @@ void Truncate() } else if (greenzone.greenZoneCount >= currMovieData.getNumRecords()) { greenzone.InvalidateAndCheck(currMovieData.getNumRecords()-1); - } else RedrawList(); + } else tasedit_list.RedrawList(); } } //the column set operation, for setting a button/Marker for a span of selected values void ColumnSet(int column) { + SelectionFrames* current_selection = selection.MakeStrobe(); + if (current_selection->size() == 0) return; + + SelectionFrames::iterator current_selection_begin(current_selection->begin()); + SelectionFrames::iterator current_selection_end(current_selection->end()); if (column == COLUMN_FRAMENUM || column == COLUMN_FRAMENUM2) { // Markers column - //inspect the selected frames, if they are all set, then unset all, else set all + // inspect the selected frames, if they are all set, then unset all, else set all bool unset_found = false; - for(SelectionFrames::iterator it(selection.CurrentSelection().begin()); it != selection.CurrentSelection().end(); it++) + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) { if(!(markers.markers_array[*it] & MARKER_FLAG_BIT)) { @@ -643,15 +442,15 @@ void ColumnSet(int column) if (unset_found) { // set all - for(SelectionFrames::iterator it(selection.CurrentSelection().begin()); it != selection.CurrentSelection().end(); it++) + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) markers.markers_array[*it] |= MARKER_FLAG_BIT; - history.RegisterChanges(MODTYPE_MARKER_SET, *selection.CurrentSelection().begin(), *selection.CurrentSelection().rbegin()); + history.RegisterChanges(MODTYPE_MARKER_SET, *current_selection_begin, *current_selection->rbegin()); } else { // unset all - for(SelectionFrames::iterator it(selection.CurrentSelection().begin()); it != selection.CurrentSelection().end(); it++) + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) markers.markers_array[*it] &= ~MARKER_FLAG_BIT; - history.RegisterChanges(MODTYPE_MARKER_UNSET, *selection.CurrentSelection().begin(), *selection.CurrentSelection().rbegin()); + history.RegisterChanges(MODTYPE_MARKER_UNSET, *current_selection_begin, *current_selection->rbegin()); } project.SetProjectChanged(); selection.ClearSelection(); @@ -664,7 +463,7 @@ void ColumnSet(int column) int button = (column - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS; //inspect the selected frames, if they are all set, then unset all, else set all bool newValue = false; - for(SelectionFrames::iterator it(selection.CurrentSelection().begin()); it != selection.CurrentSelection().end(); it++) + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) { if(!(currMovieData.records[*it].checkBit(joy,button))) { @@ -673,32 +472,37 @@ void ColumnSet(int column) } } // apply newValue - for(SelectionFrames::iterator it(selection.CurrentSelection().begin()); it != selection.CurrentSelection().end(); it++) + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) currMovieData.records[*it].setBitValue(joy,button,newValue); if (newValue) - greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_SET, *selection.CurrentSelection().begin(), *selection.CurrentSelection().rbegin())); + greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_SET, *current_selection_begin, *current_selection->rbegin())); else - greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_UNSET, *selection.CurrentSelection().begin(), *selection.CurrentSelection().rbegin())); + greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_UNSET, *current_selection_begin, *current_selection->rbegin())); } } -bool Copy() +bool Copy(SelectionFrames* current_selection) { - if (selection.CurrentSelection().size() == 0) return false; + if (!current_selection) + { + current_selection = selection.MakeStrobe(); + if (current_selection->size() == 0) return false; + } - int cframe = *selection.CurrentSelection().begin()-1; + SelectionFrames::iterator current_selection_begin(current_selection->begin()); + SelectionFrames::iterator current_selection_end(current_selection->end()); + int cframe = (*current_selection_begin) - 1; try { - int range = *selection.CurrentSelection().rbegin() - *selection.CurrentSelection().begin()+1; - //std::string outbuf clipString("TAS"); + int range = (*current_selection->rbegin() - *current_selection_begin) + 1; std::stringstream clipString; clipString << "TAS " << range << std::endl; - for(SelectionFrames::iterator it(selection.CurrentSelection().begin()); it != selection.CurrentSelection().end(); it++) + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) { - if (*it>cframe+1) + if (*it > cframe+1) { clipString << '+' << (*it-cframe) << '|'; } @@ -752,22 +556,24 @@ bool Copy() } void Cut() { - if (Copy()) + SelectionFrames* current_selection = selection.MakeStrobe(); + if (current_selection->size() == 0) return; + + if (Copy(current_selection)) { - ClearFrames(true); + ClearFrames(current_selection); } } bool Paste() { + SelectionFrames* current_selection = selection.MakeStrobe(); + if (current_selection->size() == 0) return false; + + if (!OpenClipboard(hwndTasEdit)) return false; + + SelectionFrames::iterator current_selection_begin(current_selection->begin()); bool result = false; - if (selection.CurrentSelection().size()==0) - return false; - - int pos = *selection.CurrentSelection().begin(); - - if (!OpenClipboard(hwndTasEdit)) - return false; - + int pos = *current_selection_begin; HANDLE hGlobal = GetClipboardData(CF_TEXT); if (hGlobal) { @@ -832,206 +638,15 @@ bool Paste() pGlobal = strchr(pGlobal, '\n'); } - greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_PASTE, *selection.CurrentSelection().begin())); + greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_PASTE, *current_selection_begin)); result = true; } GlobalUnlock(hGlobal); } - CloseClipboard(); return result; } -// --------------------------------------------------------------------------------- -//The subclass wndproc for the listview header -LRESULT APIENTRY HeaderWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_SETCURSOR: - return true; // no column resizing - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - { - if (selection.CurrentSelection().size()) - { - //perform hit test - HD_HITTESTINFO info; - info.pt.x = GET_X_LPARAM(lParam); - info.pt.y = GET_Y_LPARAM(lParam); - SendMessage(hWnd,HDM_HITTEST,0,(LPARAM)&info); - if(info.iItem >= COLUMN_FRAMENUM && info.iItem <= COLUMN_FRAMENUM2) - ColumnSet(info.iItem); - } - } - return true; - } - return CallWindowProc(hwndHeader_oldWndproc, hWnd, msg, wParam, lParam); -} - -//The subclass wndproc for the listview -LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_CHAR: - case WM_KILLFOCUS: - return 0; - case WM_NOTIFY: - { - switch (((LPNMHDR)lParam)->code) - { - case HDN_BEGINTRACKW: - case HDN_BEGINTRACKA: - case HDN_TRACK: - return true; // no column resizing - } - break; - } - case WM_SYSKEYDOWN: - { - if (wParam == VK_F10) - return 0; - break; - } - } - return CallWindowProc(hwndList_oldWndProc, hWnd, msg, wParam, lParam); -} - -LRESULT APIENTRY BookmarksListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_CHAR: - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SETFOCUS: - case WM_KILLFOCUS: - return 0; - case WM_MOUSEMOVE: - { - if (!bookmarks.mouse_over_bookmarkslist) - { - bookmarks.mouse_over_bookmarkslist = true; - bookmarks.list_tme.hwndTrack = hWnd; - TrackMouseEvent(&bookmarks.list_tme); - } - bookmarks.MouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - break; - } - case WM_MOUSELEAVE: - { - bookmarks.mouse_over_bookmarkslist = false; - bookmarks.MouseMove(-1, -1); - break; - } - case WM_SYSKEYDOWN: - { - if (wParam == VK_F10) - return 0; - break; - } - } - return CallWindowProc(hwndBookmarksList_oldWndProc, hWnd, msg, wParam, lParam); -} - -LRESULT APIENTRY HistoryListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_CHAR: - case WM_KEYDOWN: - case WM_KEYUP: - case WM_KILLFOCUS: - return 0; - case WM_SYSKEYDOWN: - { - if (wParam == VK_F10) - return 0; - break; - } - } - return CallWindowProc(hwndHistoryList_oldWndProc, hWnd, msg, wParam, lParam); -} - -LRESULT APIENTRY BranchesBitmapWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_MOUSEMOVE: - { - if (!bookmarks.mouse_over_bitmap) - { - bookmarks.mouse_over_bitmap = true; - bookmarks.tme.hwndTrack = hWnd; - TrackMouseEvent(&bookmarks.tme); - } - bookmarks.MouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - break; - } - case WM_MOUSELEAVE: - { - bookmarks.mouse_over_bitmap = false; - bookmarks.MouseMove(-1, -1); - break; - } - case WM_SYSKEYDOWN: - { - if (wParam == VK_F10) - return 0; - break; - } - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hWnd, &ps); - bookmarks.PaintBranchesBitmap(hdc); - EndPaint(hWnd, &ps); - return 0; - } - } - return CallWindowProc(hwndBranchesBitmap_oldWndProc, hWnd, msg, wParam, lParam); -} - -void AddFourscore() -{ - // add list columns - LVCOLUMN lvc; - lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT; - lvc.fmt = LVCFMT_CENTER; - lvc.cx = 21; - int colidx = COLUMN_JOYPAD3_A; - for (int joy = 0; joy < 2; ++joy) - { - for (int btn = 0; btn < NUM_JOYPAD_BUTTONS; ++btn) - { - lvc.pszText = buttonNames[btn]; - ListView_InsertColumn(hwndList, colidx++, &lvc); - } - } - // frame number column again - lvc.cx = 75; - lvc.pszText = "Frame#"; - ListView_InsertColumn(hwndList, colidx++, &lvc); - // enable radiobuttons for 3P/4P multitracking - EnableWindow(hwndRB_Rec3P, true); - EnableWindow(hwndRB_Rec4P, true); - // change eoptions - FCEUI_SetInputFourscore(true); -} -void RemoveFourscore() -{ - // remove list columns - for (int i = COLUMN_FRAMENUM2; i >= COLUMN_JOYPAD3_A; --i) - { - ListView_DeleteColumn (hwndList, i); - } - // disable radiobuttons for 3P/4P multitracking - EnableWindow(hwndRB_Rec3P, false); - EnableWindow(hwndRB_Rec4P, false); - // change eoptions - FCEUI_SetInputFourscore(false); -} void UncheckRecordingRadioButtons() { @@ -1119,10 +734,10 @@ void OpenProject() project.LoadProject(project.GetProjectFile()); // update fourscore status if (last_fourscore && !currMovieData.fourscore) - RemoveFourscore(); + tasedit_list.RemoveFourscore(); else if (!last_fourscore && currMovieData.fourscore) - AddFourscore(); - FollowPlayback(); + tasedit_list.AddFourscore(); + tasedit_list.FollowPlayback(); RedrawTasedit(); RedrawWindowCaption(); } @@ -1235,11 +850,6 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar if (TasEdit_wndy==-32000) TasEdit_wndy=0; SetWindowPos(hwndDlg, 0, TasEdit_wndx, TasEdit_wndy, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); // save references to dialog items - hwndList = GetDlgItem(hwndDlg, IDC_LIST1); - listItems = ListView_GetCountPerPage(hwndList); - hwndHistoryList = GetDlgItem(hwndDlg, IDC_HISTORYLIST); - hwndBookmarksList = GetDlgItem(hwndDlg, IDC_BOOKMARKSLIST); - hwndBookmarks = GetDlgItem(hwndDlg, IDC_BOOKMARKS_BOX); hwndProgressbar = GetDlgItem(hwndDlg, IDC_PROGRESS1); SendMessage(hwndProgressbar, PBM_SETRANGE, 0, MAKELPARAM(0, PROGRESSBAR_WIDTH)); hwndRewind = GetDlgItem(hwndDlg, TASEDIT_REWIND); @@ -1252,10 +862,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar hwndRB_Rec2P = GetDlgItem(hwndDlg, IDC_RADIO4); hwndRB_Rec3P = GetDlgItem(hwndDlg, IDC_RADIO5); hwndRB_Rec4P = GetDlgItem(hwndDlg, IDC_RADIO6); - hwndBranchesBitmap = GetDlgItem(hwndDlg, IDC_BRANCHES_BITMAP); - break; - case WM_MOVE: { if (!IsIconic(hwndDlg)) @@ -1266,24 +873,22 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar TasEdit_wndy = wrect.top; WindowBoundsCheckNoResize(TasEdit_wndx,TasEdit_wndy,wrect.right); // also move screenshot bitmap if it's open - if (hwndScrBmp) - SetWindowPos(hwndScrBmp, 0, TasEdit_wndx + bookmarks.scr_bmp_x, TasEdit_wndy + bookmarks.scr_bmp_y, 0, 0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); + if (bookmarks.hwndScrBmp) + SetWindowPos(bookmarks.hwndScrBmp, 0, TasEdit_wndx + bookmarks.scr_bmp_x, TasEdit_wndy + bookmarks.scr_bmp_y, 0, 0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); } break; } - case WM_NOTIFY: - switch(wParam) { case IDC_LIST1: switch(((LPNMHDR)lParam)->code) { case NM_CUSTOMDRAW: - SetWindowLong(hwndDlg, DWL_MSGRESULT, CustomDraw((NMLVCUSTOMDRAW*)lParam)); + SetWindowLong(hwndDlg, DWL_MSGRESULT, tasedit_list.CustomDraw((NMLVCUSTOMDRAW*)lParam)); return TRUE; case LVN_GETDISPINFO: - GetDispInfo((NMLVDISPINFO*)lParam); + tasedit_list.GetDispInfo((NMLVDISPINFO*)lParam); break; case NM_CLICK: SingleClick((LPNMITEMACTIVATE)lParam); @@ -1355,19 +960,16 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar break; } break; - case WM_CLOSE: case WM_QUIT: ExitTasEdit(); break; - case WM_ACTIVATE: if(LOWORD(wParam)) GotFocus(); else LostFocus(); break; - case WM_COMMAND: switch(LOWORD(wParam)) { @@ -1447,11 +1049,11 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar CheckDlgButton(hwndTasEdit, CHECK_FOLLOW_CURSOR, TASEdit_follow_playback?MF_CHECKED : MF_UNCHECKED); // if switched off then jump to selection if (TASEdit_follow_playback) - FollowPlayback(); - else if (selection.CurrentSelection().size()) - FollowSelection(); - else if (playback.pauseframe) - FollowPauseframe(); + tasedit_list.FollowPlayback(); + else if (selection.GetCurrentSelectionSize()) + tasedit_list.FollowSelection(); + else if (playback.GetPauseFrame()) + tasedit_list.FollowPauseframe(); break; case ID_VIEW_SHOW_LAG_FRAMES: //switch "Highlight lag frames" flag @@ -1463,7 +1065,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar //switch "Show Markers" flag TASEdit_show_markers ^= 1; CheckMenuItem(hmenu, ID_VIEW_SHOW_MARKERS, TASEdit_show_markers?MF_CHECKED : MF_UNCHECKED); - RedrawList(); // no need to redraw Bookmarks, as Markers are only shown in main list + tasedit_list.RedrawList(); // no need to redraw Bookmarks, as Markers are only shown in main list break; case ID_VIEW_SHOWBRANCHSCREENSHOTS: //switch "Show Branch Screenshots" flag @@ -1473,7 +1075,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar case ID_VIEW_ENABLEHOTCHANGES: TASEdit_enable_hot_changes ^= 1; CheckMenuItem(hmenu, ID_VIEW_ENABLEHOTCHANGES, TASEdit_enable_hot_changes?MF_CHECKED : MF_UNCHECKED); - RedrawList(); // redraw buttons text + tasedit_list.RedrawList(); // redraw buttons text break; case ID_VIEW_JUMPWHENMAKINGUNDO: TASEdit_jump_to_undo ^= 1; @@ -1517,7 +1119,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar history.init(TasEdit_undo_levels); selection.init(TasEdit_undo_levels); // hot changes were cleared, so update list - RedrawList(); + tasedit_list.RedrawList(); } } break; @@ -1563,7 +1165,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar break; case IDC_PROGRESS_BUTTON: // click on progressbar - stop seeking - if (playback.pauseframe) playback.SeekingStop(); + if (playback.GetPauseFrame()) playback.SeekingStop(); break; case IDC_BRANCHES_BUTTON: // click on "Bookmarks/Branches" - switch "View Tree of branches" @@ -1615,8 +1217,8 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar int result = history.undo(); if (result >= 0) { - UpdateList(); - FollowUndo(); + tasedit_list.update(); + tasedit_list.FollowUndo(); greenzone.InvalidateAndCheck(result); } break; @@ -1627,8 +1229,8 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar int result = history.redo(); if (result >= 0) { - UpdateList(); - FollowUndo(); + tasedit_list.update(); + tasedit_list.FollowUndo(); greenzone.InvalidateAndCheck(result); } break; @@ -1637,21 +1239,21 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar case ACCEL_CTRL_Q: { selection.undo(); - FollowSelection(); + tasedit_list.FollowSelection(); break; } case ID_EDIT_SELECTIONREDO: case ACCEL_CTRL_W: { selection.redo(); - FollowSelection(); + tasedit_list.FollowSelection(); break; } case ID_EDIT_RESELECTCLIPBOARD: case ACCEL_CTRL_B: { selection.ReselectClipboard(); - FollowSelection(); + tasedit_list.FollowSelection(); break; } @@ -1663,109 +1265,12 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar return 0; break; } - default: break; } return FALSE; } -bool CheckItemVisible(int frame) -{ - int top = ListView_GetTopIndex(hwndList); - // in fourscore there's horizontal scrollbar which takes one row for itself - if (frame >= top && frame < top + listItems - (currMovieData.fourscore)?1:0) - return true; - return false; -} - -void FollowPlayback() -{ - if (TASEdit_follow_playback) ListView_EnsureVisible(hwndList,currFrameCounter,FALSE); -} -void FollowUndo() -{ - int jump_frame = history.GetUndoHint(); - if (TASEdit_jump_to_undo && jump_frame >= 0) - { - if (!CheckItemVisible(jump_frame)) - { - // center list at jump_frame - int list_items = listItems; - if (currMovieData.fourscore) list_items--; - int lower_border = (list_items - 1) / 2; - int upper_border = (list_items - 1) - lower_border; - int index = jump_frame + lower_border; - if (index >= currMovieData.getNumRecords()) - index = currMovieData.getNumRecords()-1; - ListView_EnsureVisible(hwndList, index, false); - index = jump_frame - upper_border; - if (index < 0) - index = 0; - ListView_EnsureVisible(hwndList, index, false); - } - } -} -void FollowSelection() -{ - if (selection.CurrentSelection().size() == 0) return; - - int list_items = listItems; - if (currMovieData.fourscore) list_items--; - int selection_start = *selection.CurrentSelection().begin(); - int selection_end = *selection.CurrentSelection().rbegin(); - int selection_items = 1 + selection_end - selection_start; - - if (selection_items <= list_items) - { - // selected region can fit in screen - int lower_border = (list_items - selection_items) / 2; - int upper_border = (list_items - selection_items) - lower_border; - int index = selection_end + lower_border; - if (index >= currMovieData.getNumRecords()) - index = currMovieData.getNumRecords()-1; - ListView_EnsureVisible(hwndList, index, false); - index = selection_start - upper_border; - if (index < 0) - index = 0; - ListView_EnsureVisible(hwndList, index, false); - } else - { - // selected region is too big to fit in screen - // just center at selection_start - int lower_border = (list_items - 1) / 2; - int upper_border = (list_items - 1) - lower_border; - int index = selection_start + lower_border; - if (index >= currMovieData.getNumRecords()) - index = currMovieData.getNumRecords()-1; - ListView_EnsureVisible(hwndList, index, false); - index = selection_start - upper_border; - if (index < 0) - index = 0; - ListView_EnsureVisible(hwndList, index, false); - } -} -void FollowPauseframe() -{ - int jump_frame = playback.pauseframe; - if (jump_frame >= 0) - { - // center list at jump_frame - int list_items = listItems; - if (currMovieData.fourscore) list_items--; - int lower_border = (list_items - 1) / 2; - int upper_border = (list_items - 1) - lower_border; - int index = jump_frame + lower_border; - if (index >= currMovieData.getNumRecords()) - index = currMovieData.getNumRecords()-1; - ListView_EnsureVisible(hwndList, index, false); - index = jump_frame - upper_border; - if (index < 0) - index = 0; - ListView_EnsureVisible(hwndList, index, false); - } -} - void EnterTasEdit() { if(!FCEU_IsValidUI(FCEUI_TASEDIT)) return; @@ -1786,8 +1291,6 @@ void EnterTasEdit() // switch off autosaves saved_EnableAutosave = EnableAutosave; EnableAutosave = 0; - - UpdateCheckedMenuItems(); hmenu = GetMenu(hwndTasEdit); @@ -1807,7 +1310,6 @@ void EnterTasEdit() CheckDlgButton(hwndTasEdit,CHECK_AUTORESTORE_PLAYBACK,TASEdit_restore_position?BST_CHECKED:BST_UNCHECKED); SetWindowPos(hwndTasEdit, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER); - // init modules greenzone.init(); playback.init(); @@ -1828,172 +1330,18 @@ void EnterTasEdit() movie_readonly = true; multitrack_recording_joypad = MULTITRACK_RECORDING_ALL; RecheckRecordingRadioButtons(); - // switch to tasedit mode movieMode = MOVIEMODE_TASEDIT; - - // create fonts for main listview - hMainListFont = CreateFont(15, 10, /*Height,Width*/ - 0, 0, /*escapement,orientation*/ - FW_BOLD, FALSE, FALSE, FALSE, /*weight, italic, underline, strikeout*/ - ANSI_CHARSET, OUT_DEVICE_PRECIS, CLIP_MASK, /*charset, precision, clipping*/ - DEFAULT_QUALITY, DEFAULT_PITCH, /*quality, and pitch*/ - "Courier"); /*font name*/ - hMainListSelectFont = CreateFont(14, 7, /*Height,Width*/ - 0, 0, /*escapement,orientation*/ - FW_BOLD, FALSE, FALSE, FALSE, /*weight, italic, underline, strikeout*/ - ANSI_CHARSET, OUT_DEVICE_PRECIS, CLIP_MASK, /*charset, precision, clipping*/ - DEFAULT_QUALITY, DEFAULT_PITCH, /*quality, and pitch*/ - "Arial"); /*font name*/ - - // prepare the main listview - ListView_SetExtendedListViewStyleEx(hwndList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); - // subclass the header - hwndHeader = ListView_GetHeader(hwndList); - hwndHeader_oldWndproc = (WNDPROC)SetWindowLong(hwndHeader, GWL_WNDPROC, (LONG)HeaderWndProc); - // subclass the whole listview - hwndList_oldWndProc = (WNDPROC)SetWindowLong(hwndList, GWL_WNDPROC, (LONG)ListWndProc); - // setup images for the listview - HIMAGELIST himglist = ImageList_Create(9, 13, ILC_COLOR8 | ILC_MASK, 1, 1); - HBITMAP bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP0)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP1)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP2)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP3)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP4)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP5)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP6)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP7)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP8)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP9)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP10)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP11)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP12)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP13)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP14)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP15)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP16)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP17)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP18)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP19)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_TE_ARROW)); - ImageList_AddMasked(himglist, bmp, 0xFFFFFF); - DeleteObject(bmp); - ListView_SetImageList(hwndList, himglist, LVSIL_SMALL); - // setup columns - LVCOLUMN lvc; - int colidx=0; - // icons column - lvc.mask = LVCF_WIDTH; - lvc.cx = 13; - ListView_InsertColumn(hwndList, colidx++, &lvc); - // frame number column - lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT; - lvc.fmt = LVCFMT_CENTER; - lvc.cx = 75; - lvc.pszText = "Frame#"; - ListView_InsertColumn(hwndList, colidx++, &lvc); - // pads columns - lvc.cx = 21; - // add pads 1 and 2 - for (int joy = 0; joy < 2; ++joy) - { - for (int btn = 0; btn < NUM_JOYPAD_BUTTONS; ++btn) - { - lvc.pszText = buttonNames[btn]; - ListView_InsertColumn(hwndList, colidx++, &lvc); - } - } - // add pads 3 and 4 and frame_number2 - if (currMovieData.fourscore) AddFourscore(); - UpdateList(); - // calculate scr_bmp coordinates (relative to the listview top-left corner - RECT temp_rect, parent_rect; - GetWindowRect(hwndTasEdit, &parent_rect); - GetWindowRect(hwndHeader, &temp_rect); - bookmarks.scr_bmp_x = temp_rect.left - parent_rect.left; - bookmarks.scr_bmp_y = temp_rect.bottom - parent_rect.top; - - // prepare bookmarks listview - ListView_SetExtendedListViewStyleEx(hwndBookmarksList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); - // subclass the listview - hwndBookmarksList_oldWndProc = (WNDPROC)SetWindowLong(hwndBookmarksList, GWL_WNDPROC, (LONG)BookmarksListWndProc); - // setup same images for the listview - ListView_SetImageList(hwndBookmarksList, himglist, LVSIL_SMALL); - // setup columns - // icons column - lvc.mask = LVCF_WIDTH; - lvc.cx = 13; - ListView_InsertColumn(hwndBookmarksList, 0, &lvc); - // jump_frame column - lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT; - lvc.fmt = LVCFMT_CENTER; - lvc.cx = 74; - ListView_InsertColumn(hwndBookmarksList, 1, &lvc); - // time column - lvc.cx = 80; - ListView_InsertColumn(hwndBookmarksList, 2, &lvc); - - // subclass BranchesBitmap - hwndBranchesBitmap_oldWndProc = (WNDPROC)SetWindowLong(hwndBranchesBitmap, GWL_WNDPROC, (LONG)BranchesBitmapWndProc); - - // prepare the history listview - ListView_SetExtendedListViewStyleEx(hwndHistoryList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); - // subclass the listview - hwndHistoryList_oldWndProc = (WNDPROC)SetWindowLong(hwndHistoryList, GWL_WNDPROC, (LONG)HistoryListWndProc); - lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT; - lvc.cx = 200; - lvc.fmt = LVCFMT_LEFT; - ListView_InsertColumn(hwndHistoryList, 0, &lvc); - // init variables + tasedit_list.init(); markers.init(); project.init(); bookmarks.init(); history.init(TasEdit_undo_levels); selection.init(TasEdit_undo_levels); - SetFocus(hwndHistoryList); // to show darkblue cursor - SetFocus(hwndList); - FCEU_DispMessage("Tasedit engaged",0); + SetFocus(history.hwndHistoryList); // set focus only once, to show selection cursor + SetFocus(tasedit_list.hwndList); + FCEU_DispMessage("Tasedit engaged", 0); } } @@ -2008,23 +1356,22 @@ bool ExitTasEdit() eoptions = saved_eoptions; // restore autosaves EnableAutosave = saved_EnableAutosave; - DoPriority(); UpdateCheckedMenuItems(); // clear "Background TASEdit input" KeyboardClearBackgroundAccessBit(KEYBACKACCESS_TASEDIT); JoystickClearBackgroundAccessBit(JOYBACKACCESS_TASEDIT); - // release memory + tasedit_list.free(); markers.free(); greenzone.clearGreenzone(); bookmarks.free(); history.free(); playback.SeekingStop(); selection.free(); - + // switch off tasedit mode movieMode = MOVIEMODE_INACTIVE; - FCEU_DispMessage("Tasedit disengaged",0); + FCEU_DispMessage("Tasedit disengaged", 0); CreateCleanMovie(); return true; } diff --git a/src/drivers/win/tasedit.h b/src/drivers/win/tasedit.h index dbd4e14b..a1ca199f 100644 --- a/src/drivers/win/tasedit.h +++ b/src/drivers/win/tasedit.h @@ -1,136 +1,41 @@ -#define CDDS_SUBITEMPREPAINT (CDDS_SUBITEM | CDDS_ITEMPREPAINT) -#define CDDS_SUBITEMPOSTPAINT (CDDS_SUBITEM | CDDS_ITEMPOSTPAINT) -#define CDDS_SUBITEMPREERASE (CDDS_SUBITEM | CDDS_ITEMPREERASE) -#define CDDS_SUBITEMPOSTERASE (CDDS_SUBITEM | CDDS_ITEMPOSTERASE) - -#define NUM_JOYPADS 4 -#define NUM_JOYPAD_BUTTONS 8 #define PROGRESSBAR_WIDTH 200 #define GREENZONE_CAPACITY_DEFAULT 10000 #define GREENZONE_CAPACITY_MIN 1 #define GREENZONE_CAPACITY_MAX 50000 +#define UNDO_LEVELS_MIN 1 +#define UNDO_LEVELS_MAX 999 +#define UNDO_LEVELS_DEFAULT 100 + #define AUTOSAVE_PERIOD_SCALE 60000 // = 1 minute in milliseconds #define AUTOSAVE_PERIOD_DEFAULT 10 // in minutes #define AUTOSAVE_PERIOD_MIN 0 // 0 = no autosave #define AUTOSAVE_PERIOD_MAX 60 // 1 hour -#define UNDO_LEVELS_MIN 1 -#define UNDO_LEVELS_MAX 999 -#define UNDO_LEVELS_DEFAULT 100 - -// multitrack +// multitracking #define MULTITRACK_RECORDING_ALL 0 #define MULTITRACK_RECORDING_1P 1 #define MULTITRACK_RECORDING_2P 2 #define MULTITRACK_RECORDING_3P 3 #define MULTITRACK_RECORDING_4P 4 -// listview column names -#define COLUMN_ICONS 0 -#define COLUMN_FRAMENUM 1 -#define COLUMN_JOYPAD1_A 2 -#define COLUMN_JOYPAD1_B 3 -#define COLUMN_JOYPAD1_S 4 -#define COLUMN_JOYPAD1_T 5 -#define COLUMN_JOYPAD1_U 6 -#define COLUMN_JOYPAD1_D 7 -#define COLUMN_JOYPAD1_L 8 -#define COLUMN_JOYPAD1_R 9 -#define COLUMN_JOYPAD2_A 10 -#define COLUMN_JOYPAD2_B 11 -#define COLUMN_JOYPAD2_S 12 -#define COLUMN_JOYPAD2_T 13 -#define COLUMN_JOYPAD2_U 14 -#define COLUMN_JOYPAD2_D 15 -#define COLUMN_JOYPAD2_L 16 -#define COLUMN_JOYPAD2_R 17 -#define COLUMN_JOYPAD3_A 18 -#define COLUMN_JOYPAD3_B 19 -#define COLUMN_JOYPAD3_S 20 -#define COLUMN_JOYPAD3_T 21 -#define COLUMN_JOYPAD3_U 22 -#define COLUMN_JOYPAD3_D 23 -#define COLUMN_JOYPAD3_L 24 -#define COLUMN_JOYPAD3_R 25 -#define COLUMN_JOYPAD4_A 26 -#define COLUMN_JOYPAD4_B 27 -#define COLUMN_JOYPAD4_S 28 -#define COLUMN_JOYPAD4_T 29 -#define COLUMN_JOYPAD4_U 30 -#define COLUMN_JOYPAD4_D 31 -#define COLUMN_JOYPAD4_L 32 -#define COLUMN_JOYPAD4_R 33 -#define COLUMN_FRAMENUM2 34 -#define DIGITS_IN_FRAMENUM 7 -#define ARROW_IMAGE_ID 20 -// listview colors -#define NORMAL_TEXT_COLOR 0x0 -#define NORMAL_FRAMENUM_COLOR 0xFFFFFF -#define NORMAL_INPUT_COLOR1 0xEDEDED -#define NORMAL_INPUT_COLOR2 0xDEDEDE - -#define GREENZONE_FRAMENUM_COLOR 0xDDFFDD -#define GREENZONE_INPUT_COLOR1 0xC8F7C4 -#define GREENZONE_INPUT_COLOR2 0xAEE2AE - -#define PALE_GREENZONE_FRAMENUM_COLOR 0xE4FFE4 -#define PALE_GREENZONE_INPUT_COLOR1 0xD5F9D4 -#define PALE_GREENZONE_INPUT_COLOR2 0xBAE6BA - -#define LAG_FRAMENUM_COLOR 0xDBDAFF -#define LAG_INPUT_COLOR1 0xCECBEF -#define LAG_INPUT_COLOR2 0xBEBAE4 - -#define PALE_LAG_FRAMENUM_COLOR 0xE1E1FF -#define PALE_LAG_INPUT_COLOR1 0xD6D3F1 -#define PALE_LAG_INPUT_COLOR2 0xC7C4E8 - -#define CUR_FRAMENUM_COLOR 0xFCF1CE -#define CUR_INPUT_COLOR1 0xF7E9B2 -#define CUR_INPUT_COLOR2 0xE4D8A8 - -#define UNDOHINT_FRAMENUM_COLOR 0xF9DDE6 -#define UNDOHINT_INPUT_COLOR1 0xF6CCDD -#define UNDOHINT_INPUT_COLOR2 0xE5B7CC - -#define MARKED_FRAMENUM_COLOR 0xC0FCFF -#define CUR_MARKED_FRAMENUM_COLOR 0xDEF7F3 -#define MARKED_UNDOHINT_FRAMENUM_COLOR 0xE1E7EC - -// greenzone cleaning masks -#define EVERY16TH 0xFFFFFFF0 -#define EVERY8TH 0xFFFFFFF8 -#define EVERY4TH 0xFFFFFFFC -#define EVERY2ND 0xFFFFFFFE -// ----------------------------- enum ECONTEXTMENU { CONTEXTMENU_STRAY = 0, CONTEXTMENU_SELECTED = 1, }; + void EnterTasEdit(); void InitDialog(); bool ExitTasEdit(); void UpdateTasEdit(); -void UpdateList(); -void InputChangedRec(); -bool CheckItemVisible(int frame); -void FollowPlayback(); -void FollowUndo(); -void FollowSelection(); -void FollowPauseframe(); -void AddFourscore(); -void RemoveFourscore(); void RedrawWindowCaption(); void RedrawTasedit(); -void RedrawList(); void RedrawListAndBookmarks(); -void RedrawRow(int index); void RedrawRowAndBookmark(int index); +void InputChangedRec(); void ToggleJoypadBit(int column_index, int row_index, UINT KeyFlags); -void SwitchToReadOnly(); void UncheckRecordingRadioButtons(); void RecheckRecordingRadioButtons(); void OpenProject(); @@ -141,10 +46,10 @@ void CloneFrames(); void InsertFrames(); void InsertNumFrames(); void DeleteFrames(); -void ClearFrames(bool cut = false); +void ClearFrames(SelectionFrames* current_selection = 0); void Truncate(); void ColumnSet(int column); -bool Copy(); +bool Copy(SelectionFrames* current_selection = 0); void Cut(); bool Paste(); void GotFocus(); diff --git a/src/drivers/win/taseditlib/bookmarks.cpp b/src/drivers/win/taseditlib/bookmarks.cpp index 3106c565..45380ce9 100644 --- a/src/drivers/win/taseditlib/bookmarks.cpp +++ b/src/drivers/win/taseditlib/bookmarks.cpp @@ -1,25 +1,24 @@ //Implementation file of Bookmarks class -#include "movie.h" -#include "../common.h" #include "taseditproj.h" -#include "../tasedit.h" #include "zlib.h" #include "utils/xstring.h" #pragma comment(lib, "msimg32.lib") -LRESULT CALLBACK ScrBmpWndProc(HWND, UINT, WPARAM, LPARAM); -char szClassName[] = "BmpTestApp"; -HWND hwndScrBmp, scr_bmp_pic; -WNDCLASSEX wincl; -BLENDFUNCTION blend; extern HWND hwndTasEdit; extern int TasEdit_wndx, TasEdit_wndy; +extern void RedrawRowAndBookmark(int index); +LRESULT APIENTRY BookmarksListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT APIENTRY BranchesBitmapWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +WNDPROC hwndBookmarksList_oldWndProc, hwndBranchesBitmap_oldWndProc; + +// resources +char szClassName[] = "ScrBmp"; char bookmarks_save_id[BOOKMARKS_ID_LEN] = "BOOKMARKS"; char bookmarksCaption[3][23] = { " Bookmarks ", " Bookmarks / Branches ", " Branches " }; - // color tables for flashing when saving/loading bookmarks COLORREF bookmark_flash_colors[3][FLASH_PHASE_MAX+1] = { // set @@ -36,10 +35,7 @@ extern GREENZONE greenzone; extern TASEDIT_PROJECT project; extern INPUT_HISTORY history; extern MARKERS markers; - -extern HWND hwndBookmarks; -extern HWND hwndBookmarksList; -extern HWND hwndBranchesBitmap; +extern TASEDIT_LIST tasedit_list; extern bool TASEdit_show_lag_frames; extern bool TASEdit_bind_markers; @@ -103,6 +99,34 @@ BOOKMARKS::BOOKMARKS() void BOOKMARKS::init() { free(); + hwndBookmarksList = GetDlgItem(hwndTasEdit, IDC_BOOKMARKSLIST); + hwndBookmarks = GetDlgItem(hwndTasEdit, IDC_BOOKMARKS_BOX); + hwndBranchesBitmap = GetDlgItem(hwndTasEdit, IDC_BRANCHES_BITMAP); + + // prepare bookmarks listview + ListView_SetExtendedListViewStyleEx(hwndBookmarksList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); + // subclass the listview + hwndBookmarksList_oldWndProc = (WNDPROC)SetWindowLong(hwndBookmarksList, GWL_WNDPROC, (LONG)BookmarksListWndProc); + // setup same images for the listview + ListView_SetImageList(hwndBookmarksList, tasedit_list.himglist, LVSIL_SMALL); + // setup columns + LVCOLUMN lvc; + // icons column + lvc.mask = LVCF_WIDTH; + lvc.cx = 13; + ListView_InsertColumn(hwndBookmarksList, 0, &lvc); + // jump_frame column + lvc.mask = LVCF_WIDTH | LVCF_FMT; + lvc.fmt = LVCFMT_CENTER; + lvc.cx = 74; + ListView_InsertColumn(hwndBookmarksList, 1, &lvc); + // time column + lvc.cx = 80; + ListView_InsertColumn(hwndBookmarksList, 2, &lvc); + + // subclass BranchesBitmap + hwndBranchesBitmap_oldWndProc = (WNDPROC)SetWindowLong(hwndBranchesBitmap, GWL_WNDPROC, (LONG)BranchesBitmapWndProc); + // init arrays BranchX.resize(TOTAL_BOOKMARKS+1); BranchY.resize(TOTAL_BOOKMARKS+1); @@ -134,7 +158,7 @@ void BOOKMARKS::init() // find rows top/height (for mouseover hittest calculations) RECT temp_rect; - if (ListView_GetSubItemRect(hwndBookmarksList, 0, 2, LVIR_BOUNDS, &temp_rect)) + if (ListView_GetSubItemRect(hwndBookmarksList, 0, 2, LVIR_BOUNDS, &temp_rect) && temp_rect.bottom != temp_rect.top) { branch_row_top = temp_rect.top; branch_row_left = temp_rect.left; @@ -405,6 +429,8 @@ void BOOKMARKS::set(int slot) if (previous_frame >= 0 && previous_frame != currFrameCounter) RedrawRowAndBookmark(previous_frame); RedrawRowAndBookmark(currFrameCounter); + + FCEU_DispMessage("Branch %d saved.", 0, slot); } void BOOKMARKS::jump(int slot) @@ -414,10 +440,10 @@ void BOOKMARKS::jump(int slot) { int frame = bookmarks_array[slot].snapshot.jump_frame; playback.jump(frame); - if (playback.pauseframe) - FollowPauseframe(); + if (playback.GetPauseFrame()) + tasedit_list.FollowPauseframe(); else - FollowPlayback(); + tasedit_list.FollowPlayback(); bookmarks_array[slot].jump(); } } @@ -454,14 +480,14 @@ void BOOKMARKS::unleash(int slot) // restore entire movie currMovieData.records.resize(bookmarks_array[slot].snapshot.size); bookmarks_array[slot].snapshot.toMovie(currMovieData, first_change); - UpdateList(); + tasedit_list.update(); history.RegisterBranching(MODTYPE_BRANCH_0 + slot, first_change, slot); greenzone.Invalidate(first_change); bookmarks_array[slot].unleashed(); } else if (markers_changed) { history.RegisterBranching(MODTYPE_BRANCH_MARKERS_0 + slot, first_change, slot); - RedrawList(); + tasedit_list.RedrawList(); bookmarks_array[slot].unleashed(); } else { @@ -487,14 +513,14 @@ void BOOKMARKS::unleash(int slot) // restore movie up to and not including bookmarked frame (imitating old TASing method) if (currMovieData.getNumRecords() <= jump_frame) currMovieData.records.resize(jump_frame+1); // but if old movie is shorter, include last frame as blank frame bookmarks_array[slot].snapshot.toMovie(currMovieData, first_change, jump_frame-1); - UpdateList(); + tasedit_list.update(); history.RegisterBranching(MODTYPE_BRANCH_0 + slot, first_change, slot); greenzone.Invalidate(first_change); bookmarks_array[slot].unleashed(); } else if (markers_changed) { history.RegisterBranching(MODTYPE_BRANCH_MARKERS_0 + slot, first_change, slot); - RedrawList(); + tasedit_list.RedrawList(); bookmarks_array[slot].unleashed(); } else { @@ -532,6 +558,8 @@ void BOOKMARKS::unleash(int slot) current_branch = slot; changes_since_current_branch = false; must_recalculate_branches_tree = true; + + FCEU_DispMessage("Branch %d loaded.", 0, slot); } void BOOKMARKS::save(EMUFILE *os) @@ -946,7 +974,7 @@ LONG BOOKMARKS::CustomDraw(NMLVCUSTOMDRAW* msg) // frame number SelectObject(msg->nmcd.hdc, hBookmarksFont); int frame = bookmarks_array[cell_y].snapshot.jump_frame; - if (frame == currFrameCounter || frame == playback.GetPauseFrame()) + if (frame == currFrameCounter || frame == (playback.GetPauseFrame() - 1)) { // current frame msg->clrTextBk = CUR_FRAMENUM_COLOR; @@ -977,7 +1005,7 @@ LONG BOOKMARKS::CustomDraw(NMLVCUSTOMDRAW* msg) // frame number SelectObject(msg->nmcd.hdc, hBookmarksFont); int frame = bookmarks_array[cell_y].snapshot.jump_frame; - if (frame == currFrameCounter || frame == playback.GetPauseFrame()) + if (frame == currFrameCounter || frame == (playback.GetPauseFrame() - 1)) { // current frame msg->clrTextBk = CUR_INPUT_COLOR1; @@ -1309,14 +1337,92 @@ void BOOKMARKS::RecursiveSetYPos(int parent, int parentY) } } // ---------------------------------------------------------------------------------------- -LRESULT CALLBACK ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +LRESULT APIENTRY BookmarksListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { + extern BOOKMARKS bookmarks; + switch(msg) + { + case WM_CHAR: + case WM_KEYDOWN: + case WM_KEYUP: + case WM_SETFOCUS: + case WM_KILLFOCUS: + return 0; + case WM_MOUSEMOVE: + { + if (!bookmarks.mouse_over_bookmarkslist) + { + bookmarks.mouse_over_bookmarkslist = true; + bookmarks.list_tme.hwndTrack = hWnd; + TrackMouseEvent(&bookmarks.list_tme); + } + bookmarks.MouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + } + case WM_MOUSELEAVE: + { + bookmarks.mouse_over_bookmarkslist = false; + bookmarks.MouseMove(-1, -1); + break; + } + case WM_SYSKEYDOWN: + { + if (wParam == VK_F10) + return 0; + break; + } + } + return CallWindowProc(hwndBookmarksList_oldWndProc, hWnd, msg, wParam, lParam); +} +LRESULT APIENTRY BranchesBitmapWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + extern BOOKMARKS bookmarks; + switch(msg) + { + case WM_MOUSEMOVE: + { + if (!bookmarks.mouse_over_bitmap) + { + bookmarks.mouse_over_bitmap = true; + bookmarks.tme.hwndTrack = hWnd; + TrackMouseEvent(&bookmarks.tme); + } + bookmarks.MouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + } + case WM_MOUSELEAVE: + { + bookmarks.mouse_over_bitmap = false; + bookmarks.MouseMove(-1, -1); + break; + } + case WM_SYSKEYDOWN: + { + if (wParam == VK_F10) + return 0; + break; + } + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hWnd, &ps); + bookmarks.PaintBranchesBitmap(hdc); + EndPaint(hWnd, &ps); + return 0; + } + } + return CallWindowProc(hwndBranchesBitmap_oldWndProc, hWnd, msg, wParam, lParam); +} +// ---------------------------------------------------------------------------------------- +LRESULT APIENTRY ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + extern BOOKMARKS bookmarks; switch(message) { case WM_CREATE: { // create static bitmap placeholder - scr_bmp_pic = CreateWindow(WC_STATIC, NULL, SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 255, 255, hwnd, NULL, NULL, NULL); + bookmarks.scr_bmp_pic = CreateWindow(WC_STATIC, NULL, SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 255, 255, hwnd, NULL, NULL, NULL); return 0; } default: diff --git a/src/drivers/win/taseditlib/bookmarks.h b/src/drivers/win/taseditlib/bookmarks.h index 71787dd4..88ae8b10 100644 --- a/src/drivers/win/taseditlib/bookmarks.h +++ b/src/drivers/win/taseditlib/bookmarks.h @@ -135,11 +135,10 @@ public: std::vector bookmarks_array; // not saved vars - bool mouse_over_bitmap, mouse_over_bookmarkslist; - TRACKMOUSEEVENT tme, list_tme; int branch_row_top; int branch_row_left; int branch_row_height; + bool mouse_over_bitmap, mouse_over_bookmarkslist; // screenshot bmp stuff LPBITMAPINFO scr_bmi; HBITMAP scr_bmp; @@ -148,6 +147,10 @@ public: int scr_bmp_y; int scr_bmp_phase; int screenshot_currently_shown; + HWND hwndScrBmp, scr_bmp_pic; + WNDCLASSEX wincl; + BLENDFUNCTION blend; + TRACKMOUSEEVENT tme, list_tme; private: void SetCurrentPosTime(); @@ -179,6 +182,9 @@ private: int mouse_x, mouse_y; int item_under_mouse; + HWND hwndBookmarksList, hwndBookmarks; + HWND hwndBranchesBitmap; + // GDI stuff HFONT hBookmarksFont; HBRUSH normal_brush; diff --git a/src/drivers/win/taseditlib/greenzone.cpp b/src/drivers/win/taseditlib/greenzone.cpp index 91e7bc99..e205a293 100644 --- a/src/drivers/win/taseditlib/greenzone.cpp +++ b/src/drivers/win/taseditlib/greenzone.cpp @@ -1,11 +1,8 @@ //Implementation file of Greenzone class -#include "movie.h" -#include "state.h" -#include "../common.h" -#include "zlib.h" #include "taseditproj.h" #include "../tasedit.h" +#include "state.h" #include "zlib.h" extern TASEDIT_PROJECT project; diff --git a/src/drivers/win/taseditlib/greenzone.h b/src/drivers/win/taseditlib/greenzone.h index d2eb0bf6..0ef2c5d9 100644 --- a/src/drivers/win/taseditlib/greenzone.h +++ b/src/drivers/win/taseditlib/greenzone.h @@ -5,6 +5,12 @@ #define GREENZONE_ID_LEN 10 +// greenzone cleaning masks +#define EVERY16TH 0xFFFFFFF0 +#define EVERY8TH 0xFFFFFFF8 +#define EVERY4TH 0xFFFFFFFC +#define EVERY2ND 0xFFFFFFFE + class GREENZONE { public: diff --git a/src/drivers/win/taseditlib/inputhistory.cpp b/src/drivers/win/taseditlib/inputhistory.cpp index a98a6a0c..2cfbbad9 100644 --- a/src/drivers/win/taseditlib/inputhistory.cpp +++ b/src/drivers/win/taseditlib/inputhistory.cpp @@ -3,18 +3,20 @@ #include "taseditproj.h" #include "../tasedit.h" // just for mainlist functions, later this should be deleted -extern void FCEU_printf(char *format, ...); - -extern HWND hwndHistoryList; +extern HWND hwndTasEdit; extern bool TASEdit_bind_markers; extern bool TASEdit_enable_hot_changes; extern bool TASEdit_branch_full_movie; +LRESULT APIENTRY HistoryListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +WNDPROC hwndHistoryList_oldWndProc; + extern MARKERS markers; extern BOOKMARKS bookmarks; extern PLAYBACK playback; extern GREENZONE greenzone; extern TASEDIT_PROJECT project; +extern TASEDIT_LIST tasedit_list; char history_save_id[HISTORY_ID_LEN] = "HISTORY"; char modCaptions[36][20] = {" Init", @@ -57,11 +59,20 @@ char joypadCaptions[4][5] = {"(1P)", "(2P)", "(3P)", "(4P)"}; INPUT_HISTORY::INPUT_HISTORY() { - } void INPUT_HISTORY::init(int new_size) { + // prepare the history listview + hwndHistoryList = GetDlgItem(hwndTasEdit, IDC_HISTORYLIST); + ListView_SetExtendedListViewStyleEx(hwndHistoryList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); + // subclass the listview + hwndHistoryList_oldWndProc = (WNDPROC)SetWindowLong(hwndHistoryList, GWL_WNDPROC, (LONG)HistoryListWndProc); + LVCOLUMN lvc; + lvc.mask = LVCF_WIDTH | LVCF_FMT; + lvc.cx = 200; + lvc.fmt = LVCFMT_LEFT; + ListView_InsertColumn(hwndHistoryList, 0, &lvc); // init vars if (new_size > 0) history_size = new_size + 1; @@ -92,7 +103,7 @@ void INPUT_HISTORY::update() { // update undo_hint if (old_undo_hint_pos != undo_hint_pos && old_undo_hint_pos >= 0) - RedrawRow(old_undo_hint_pos); // not changing bookmarks list + tasedit_list.RedrawRow(old_undo_hint_pos); // not changing bookmarks list old_undo_hint_pos = undo_hint_pos; old_show_undo_hint = show_undo_hint; show_undo_hint = false; @@ -104,7 +115,7 @@ void INPUT_HISTORY::update() undo_hint_pos = -1; // finished hinting } if (old_show_undo_hint != show_undo_hint) - RedrawRow(undo_hint_pos); // not changing bookmarks list + tasedit_list.RedrawRow(undo_hint_pos); // not changing bookmarks list @@ -155,11 +166,11 @@ int INPUT_HISTORY::jump(int new_pos) { markers.update(); bookmarks.ChangesMadeSinceBranch(); - RedrawList(); + tasedit_list.RedrawList(); } else if (TASEdit_enable_hot_changes) { // when using Hot Changes, list should be always redrawn, because old changes become less hot - RedrawList(); + tasedit_list.RedrawList(); } return first_change; @@ -484,8 +495,8 @@ void INPUT_HISTORY::Click(LPNMITEMACTIVATE info) int result = jump(item); if (result >= 0) { - UpdateList(); - FollowUndo(); + tasedit_list.update(); + tasedit_list.FollowUndo(); greenzone.InvalidateAndCheck(result); return; } @@ -534,4 +545,24 @@ int INPUT_HISTORY::GetUndoHint() else return -1; } +// --------------------------------------------------------------------------------- +LRESULT APIENTRY HistoryListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_CHAR: + case WM_KEYDOWN: + case WM_KEYUP: + case WM_KILLFOCUS: + return 0; + case WM_SYSKEYDOWN: + { + if (wParam == VK_F10) + return 0; + break; + } + } + return CallWindowProc(hwndHistoryList_oldWndProc, hWnd, msg, wParam, lParam); +} + diff --git a/src/drivers/win/taseditlib/inputhistory.h b/src/drivers/win/taseditlib/inputhistory.h index 0ac1728e..a6cf6c4d 100644 --- a/src/drivers/win/taseditlib/inputhistory.h +++ b/src/drivers/win/taseditlib/inputhistory.h @@ -78,6 +78,8 @@ public: void RedrawHistoryList(); void UpdateHistoryList(); + HWND hwndHistoryList; + private: std::vector input_snapshots; diff --git a/src/drivers/win/taseditlib/inputsnapshot.cpp b/src/drivers/win/taseditlib/inputsnapshot.cpp index d3a7f691..c84dd82f 100644 --- a/src/drivers/win/taseditlib/inputsnapshot.cpp +++ b/src/drivers/win/taseditlib/inputsnapshot.cpp @@ -470,10 +470,10 @@ void INPUT_SNAPSHOT::inheritHotChanges_DeleteSelection(INPUT_SNAPSHOT* source_of int bytes = bytes_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; int frame = 0, pos = 0, source_pos = 0; int this_size = hot_changes.size(), source_size = source_of_hotchanges->hot_changes.size(); - SelectionFrames::iterator it(selection.CurrentSelection().begin()); + SelectionFrames::iterator it(selection.GetStrobedSelection().begin()); while (pos < this_size && source_pos < source_size) { - if (it != selection.CurrentSelection().end() && frame == *it) + if (it != selection.GetStrobedSelection().end() && frame == *it) { // this frame is selected it++; @@ -499,10 +499,11 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of int bytes = bytes_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; int frame = 0, region_len = 0, pos = 0, source_pos = 0; int this_size = hot_changes.size(), source_size = source_of_hotchanges->hot_changes.size(); - SelectionFrames::iterator it(selection.CurrentSelection().begin()); + SelectionFrames::iterator it(selection.GetStrobedSelection().begin()); + SelectionFrames::iterator current_selection_end(selection.GetStrobedSelection().end()); while (pos < this_size && source_pos < source_size) { - if (it != selection.CurrentSelection().end() && frame == *it) + if (it != current_selection_end && frame == *it) { // this frame is selected it++; @@ -529,10 +530,11 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of int bytes = bytes_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; int frame = 0, region_len = 0, pos = 0; int this_size = hot_changes.size(); - SelectionFrames::iterator it(selection.CurrentSelection().begin()); + SelectionFrames::iterator it(selection.GetStrobedSelection().begin()); + SelectionFrames::iterator current_selection_end(selection.GetStrobedSelection().end()); while (pos < this_size) { - if (it != selection.CurrentSelection().end() && frame == *it) + if (it != current_selection_end && frame == *it) { // this frame is selected it++; @@ -541,7 +543,7 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of memset(&hot_changes[pos], 0xFF, bytes); pos += bytes; // exit loop when all selection frames are handled - if (it == selection.CurrentSelection().end()) break; + if (it == current_selection_end) break; } else { // this frame is not selected diff --git a/src/drivers/win/taseditlib/markers.cpp b/src/drivers/win/taseditlib/markers.cpp index 947256fd..966a8451 100644 --- a/src/drivers/win/taseditlib/markers.cpp +++ b/src/drivers/win/taseditlib/markers.cpp @@ -1,7 +1,5 @@ //Implementation file of Markers class -#include "movie.h" -#include "../common.h" #include "taseditproj.h" //#include "../tasedit.h" #include "zlib.h" diff --git a/src/drivers/win/taseditlib/playback.cpp b/src/drivers/win/taseditlib/playback.cpp index b56236d7..2d7afaae 100644 --- a/src/drivers/win/taseditlib/playback.cpp +++ b/src/drivers/win/taseditlib/playback.cpp @@ -1,7 +1,5 @@ //Implementation file of Playback class -#include "movie.h" -#include "../common.h" #include "taseditproj.h" #include "../tasedit.h" @@ -9,16 +7,18 @@ extern void ForceExecuteLuaFrameFunctions(); #endif -extern HWND hwndProgressbar, hwndList, hwndRewind, hwndForward, hwndRewindFull, hwndForwardFull; +extern HWND hwndProgressbar, hwndRewind, hwndForward, hwndRewindFull, hwndForwardFull; extern void FCEU_printf(char *format, ...); extern bool turbo; + extern MARKERS markers; extern GREENZONE greenzone; +extern TASEDIT_LIST tasedit_list; + extern bool Tasedit_rewind_now; PLAYBACK::PLAYBACK() { - } void PLAYBACK::init() @@ -29,7 +29,7 @@ void PLAYBACK::init() void PLAYBACK::reset() { lastCursor = -1; - pauseframe = old_pauseframe = 0; + pause_frame = old_pauseframe = 0; old_show_pauseframe = show_pauseframe = false; old_rewind_button_state = rewind_button_state = false; old_forward_button_state = forward_button_state = false; @@ -40,31 +40,31 @@ void PLAYBACK::reset() } void PLAYBACK::update() { - // pause when seeking hit pauseframe + // pause when seeking hit pause_frame if(!FCEUI_EmulationPaused()) - if(pauseframe && pauseframe <= currFrameCounter + 1) + if(pause_frame && pause_frame <= currFrameCounter + 1) SeekingStop(); // update flashing pauseframe - if (old_pauseframe != pauseframe && old_pauseframe) RedrawRowAndBookmark(old_pauseframe-1); - old_pauseframe = pauseframe; + if (old_pauseframe != pause_frame && old_pauseframe) RedrawRowAndBookmark(old_pauseframe-1); + old_pauseframe = pause_frame; old_show_pauseframe = show_pauseframe; - if (pauseframe) + if (pause_frame) { if (emu_paused) show_pauseframe = (int)(clock() / PAUSEFRAME_BLINKING_PERIOD_PAUSED) & 1; else show_pauseframe = (int)(clock() / PAUSEFRAME_BLINKING_PERIOD_SEEKING) & 1; } else show_pauseframe = false; - if (old_show_pauseframe != show_pauseframe) RedrawRowAndBookmark(pauseframe-1); + if (old_show_pauseframe != show_pauseframe) RedrawRowAndBookmark(pause_frame-1); // update seeking progressbar old_emu_paused = emu_paused; emu_paused = (FCEUI_EmulationPaused() != 0); - if (pauseframe) + if (pause_frame) { if (old_show_pauseframe != show_pauseframe) - SetProgressbar(currFrameCounter - seeking_start_frame, pauseframe-seeking_start_frame); + SetProgressbar(currFrameCounter - seeking_start_frame, pause_frame - seeking_start_frame); } else if (old_emu_paused != emu_paused) { // emulator got paused/unpaused externally @@ -79,42 +79,39 @@ void PLAYBACK::update() //update the playback cursor if(currFrameCounter != lastCursor) { - FollowPlayback(); + tasedit_list.FollowPlayback(); //update the old and new rows RedrawRowAndBookmark(lastCursor); RedrawRowAndBookmark(currFrameCounter); - UpdateWindow(hwndList); + UpdateWindow(tasedit_list.hwndList); lastCursor = currFrameCounter; } // update < and > buttons - if(emu_paused) + old_rewind_button_state = rewind_button_state; + rewind_button_state = ((Button_GetState(hwndRewind) & BST_PUSHED) != 0 || Tasedit_rewind_now); + if (rewind_button_state) { - old_rewind_button_state = rewind_button_state; - rewind_button_state = ((Button_GetState(hwndRewind) & BST_PUSHED) != 0 || Tasedit_rewind_now); - if (rewind_button_state) + if (!old_rewind_button_state) { - if (!old_rewind_button_state) - { - button_hold_time = clock(); - RewindFrame(); - } else if (button_hold_time + HOLD_REPEAT_DELAY < clock()) - { - RewindFrame(); - } + button_hold_time = clock(); + RewindFrame(); + } else if (button_hold_time + HOLD_REPEAT_DELAY < clock()) + { + RewindFrame(); } - old_forward_button_state = forward_button_state; - forward_button_state = (Button_GetState(hwndForward) & BST_PUSHED) != 0; - if (forward_button_state && !rewind_button_state) + } + old_forward_button_state = forward_button_state; + forward_button_state = (Button_GetState(hwndForward) & BST_PUSHED) != 0; + if (forward_button_state && !rewind_button_state) + { + if (!old_forward_button_state) { - if (!old_forward_button_state) - { - button_hold_time = clock(); - ForwardFrame(); - } else if (button_hold_time + HOLD_REPEAT_DELAY < clock()) - { - ForwardFrame(); - } + button_hold_time = clock(); + ForwardFrame(); + } else if (button_hold_time + HOLD_REPEAT_DELAY < clock()) + { + ForwardFrame(); } } // update << and >> buttons @@ -149,9 +146,9 @@ void PLAYBACK::update() void PLAYBACK::updateProgressbar() { - if (pauseframe) + if (pause_frame) { - SetProgressbar(currFrameCounter - seeking_start_frame, pauseframe-seeking_start_frame); + SetProgressbar(currFrameCounter - seeking_start_frame, pause_frame - seeking_start_frame); } else { if (emu_paused) @@ -183,13 +180,13 @@ void PLAYBACK::UnpauseEmulation() void PLAYBACK::SeekingStart(int finish_frame) { seeking_start_frame = currFrameCounter; - pauseframe = finish_frame; + pause_frame = finish_frame; turbo = true; UnpauseEmulation(); } void PLAYBACK::SeekingStop() { - pauseframe = 0; + pause_frame = 0; turbo = false; PauseEmulation(); SetProgressbar(1, 1); @@ -199,10 +196,12 @@ void PLAYBACK::SeekingStop() void PLAYBACK::RewindFrame() { if (currFrameCounter > 0) jump(currFrameCounter-1); + if (!pause_frame) PauseEmulation(); } void PLAYBACK::ForwardFrame() { jump(currFrameCounter+1); + if (!pause_frame) PauseEmulation(); turbo = false; } void PLAYBACK::RewindFull() @@ -247,13 +246,13 @@ void PLAYBACK::jump(int frame) if (JumpToFrame(frame)) { ForceExecuteLuaFrameFunctions(); - FollowPlayback(); + tasedit_list.FollowPlayback(); } } void PLAYBACK::restorePosition() { - if (pauseframe) - jump(pauseframe-1); + if (pause_frame) + jump(pause_frame-1); else jump(currFrameCounter); } @@ -276,7 +275,7 @@ bool PLAYBACK::JumpToFrame(int index) { turbo = false; // if playback was seeking, pause emulation right here - if (pauseframe) SeekingStop(); + if (pause_frame) SeekingStop(); return true; } //Search for an earlier frame with savestate @@ -298,9 +297,9 @@ bool PLAYBACK::JumpToFrame(int index) int PLAYBACK::GetPauseFrame() { if (show_pauseframe) - return pauseframe-1; + return pause_frame; else - return -1; + return 0; } void PLAYBACK::SetProgressbar(int a, int b) diff --git a/src/drivers/win/taseditlib/playback.h b/src/drivers/win/taseditlib/playback.h index 2f983232..7a6f1748 100644 --- a/src/drivers/win/taseditlib/playback.h +++ b/src/drivers/win/taseditlib/playback.h @@ -36,11 +36,12 @@ public: int GetPauseFrame(); void SetProgressbar(int a, int b); - int pauseframe; private: bool JumpToFrame(int index); + int pause_frame; + int lastCursor; // for currentCursor we use external variable currFrameCounter bool old_emu_paused, emu_paused; int old_pauseframe; diff --git a/src/drivers/win/taseditlib/tasedit_list.cpp b/src/drivers/win/taseditlib/tasedit_list.cpp new file mode 100644 index 00000000..8a8935d8 --- /dev/null +++ b/src/drivers/win/taseditlib/tasedit_list.cpp @@ -0,0 +1,573 @@ +//Implementation file of TASEDIT_LIST class + +#include "taseditproj.h" +//#include "../tasedit.h" +#include "utils/xstring.h" + +extern HWND hwndTasEdit, hwndRB_Rec3P, hwndRB_Rec4P; +extern char buttonNames[NUM_JOYPAD_BUTTONS][2]; +extern void ColumnSet(int column); + +extern BOOKMARKS bookmarks; +extern PLAYBACK playback; +extern GREENZONE greenzone; +extern INPUT_HISTORY history; +extern MARKERS markers; +extern TASEDIT_SELECTION selection; + +extern bool TASEdit_enable_hot_changes; +extern bool TASEdit_show_markers; +extern bool TASEdit_show_lag_frames; +extern bool TASEdit_follow_playback; +extern bool TASEdit_jump_to_undo; + + +LRESULT APIENTRY HeaderWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +WNDPROC hwndList_oldWndProc, hwndHeader_oldWndproc; + +// resources +COLORREF hot_changes_colors[16] = { 0x0, 0x661212, 0x842B4E, 0x652C73, 0x48247D, 0x383596, 0x2947AE, 0x1E53C1, 0x135DD2, 0x116EDA, 0x107EE3, 0x0F8EEB, 0x209FF4, 0x3DB1FD, 0x51C2FF, 0x4DCDFF }; + +TASEDIT_LIST::TASEDIT_LIST() +{ + + // create fonts for main listview + hMainListFont = CreateFont(15, 10, /*Height,Width*/ + 0, 0, /*escapement,orientation*/ + FW_BOLD, FALSE, FALSE, FALSE, /*weight, italic, underline, strikeout*/ + ANSI_CHARSET, OUT_DEVICE_PRECIS, CLIP_MASK, /*charset, precision, clipping*/ + DEFAULT_QUALITY, DEFAULT_PITCH, /*quality, and pitch*/ + "Courier"); /*font name*/ + hMainListSelectFont = CreateFont(14, 7, /*Height,Width*/ + 0, 0, /*escapement,orientation*/ + FW_BOLD, FALSE, FALSE, FALSE, /*weight, italic, underline, strikeout*/ + ANSI_CHARSET, OUT_DEVICE_PRECIS, CLIP_MASK, /*charset, precision, clipping*/ + DEFAULT_QUALITY, DEFAULT_PITCH, /*quality, and pitch*/ + "Arial"); /*font name*/ + +} + +void TASEDIT_LIST::init() +{ + //free(); + hwndList = GetDlgItem(hwndTasEdit, IDC_LIST1); + + // prepare the main listview + ListView_SetExtendedListViewStyleEx(hwndList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); + // subclass the header + hwndHeader = ListView_GetHeader(hwndList); + hwndHeader_oldWndproc = (WNDPROC)SetWindowLong(hwndHeader, GWL_WNDPROC, (LONG)HeaderWndProc); + // subclass the whole listview + hwndList_oldWndProc = (WNDPROC)SetWindowLong(hwndList, GWL_WNDPROC, (LONG)ListWndProc); + // setup images for the listview + himglist = ImageList_Create(9, 13, ILC_COLOR8 | ILC_MASK, 1, 1); + HBITMAP bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP0)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP1)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP2)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP3)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP4)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP5)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP6)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP7)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP8)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP9)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP10)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP11)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP12)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP13)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP14)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP15)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP16)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP17)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP18)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BITMAP19)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + bmp = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_TE_ARROW)); + ImageList_AddMasked(himglist, bmp, 0xFFFFFF); + DeleteObject(bmp); + ListView_SetImageList(hwndList, himglist, LVSIL_SMALL); + // setup columns + LVCOLUMN lvc; + int colidx=0; + // icons column + lvc.mask = LVCF_WIDTH; + lvc.cx = 13; + ListView_InsertColumn(hwndList, colidx++, &lvc); + // frame number column + lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT; + lvc.fmt = LVCFMT_CENTER; + lvc.cx = 75; + lvc.pszText = "Frame#"; + ListView_InsertColumn(hwndList, colidx++, &lvc); + // pads columns + lvc.cx = 21; + // add pads 1 and 2 + for (int joy = 0; joy < 2; ++joy) + { + for (int btn = 0; btn < NUM_JOYPAD_BUTTONS; ++btn) + { + lvc.pszText = buttonNames[btn]; + ListView_InsertColumn(hwndList, colidx++, &lvc); + } + } + // add pads 3 and 4 and frame_number2 + if (currMovieData.fourscore) AddFourscore(); + + listItems = ListView_GetCountPerPage(hwndList); + // calculate scr_bmp coordinates (relative to the listview top-left corner + RECT temp_rect, parent_rect; + GetWindowRect(hwndTasEdit, &parent_rect); + GetWindowRect(hwndHeader, &temp_rect); + bookmarks.scr_bmp_x = temp_rect.left - parent_rect.left; + bookmarks.scr_bmp_y = temp_rect.bottom - parent_rect.top; + + update(); +} +void TASEDIT_LIST::free() +{ + + +} + +void TASEDIT_LIST::update() +{ + //update the number of items in the list + int currLVItemCount = ListView_GetItemCount(hwndList); + int movie_size = currMovieData.getNumRecords(); + if(currLVItemCount != movie_size) + ListView_SetItemCountEx(hwndList, movie_size, LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL); + + +} +// ---------------------------------------------------------------------- +void TASEDIT_LIST::AddFourscore() +{ + // add list columns + LVCOLUMN lvc; + lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT; + lvc.fmt = LVCFMT_CENTER; + lvc.cx = 21; + int colidx = COLUMN_JOYPAD3_A; + for (int joy = 0; joy < 2; ++joy) + { + for (int btn = 0; btn < NUM_JOYPAD_BUTTONS; ++btn) + { + lvc.pszText = buttonNames[btn]; + ListView_InsertColumn(hwndList, colidx++, &lvc); + } + } + // frame number column again + lvc.cx = 75; + lvc.pszText = "Frame#"; + ListView_InsertColumn(hwndList, colidx++, &lvc); + // enable radiobuttons for 3P/4P multitracking + EnableWindow(hwndRB_Rec3P, true); + EnableWindow(hwndRB_Rec4P, true); + // change eoptions + FCEUI_SetInputFourscore(true); +} +void TASEDIT_LIST::RemoveFourscore() +{ + // remove list columns + for (int i = COLUMN_FRAMENUM2; i >= COLUMN_JOYPAD3_A; --i) + { + ListView_DeleteColumn (hwndList, i); + } + // disable radiobuttons for 3P/4P multitracking + EnableWindow(hwndRB_Rec3P, false); + EnableWindow(hwndRB_Rec4P, false); + // change eoptions + FCEUI_SetInputFourscore(false); +} + +void TASEDIT_LIST::RedrawList() +{ + InvalidateRect(hwndList, 0, FALSE); +} +void TASEDIT_LIST::RedrawRow(int index) +{ + ListView_RedrawItems(hwndList, index, index); +} + + +// ------------------------------------------------------------------------- +bool TASEDIT_LIST::CheckItemVisible(int frame) +{ + int top = ListView_GetTopIndex(hwndList); + // in fourscore there's horizontal scrollbar which takes one row for itself + if (frame >= top && frame < top + listItems - (currMovieData.fourscore)?1:0) + return true; + return false; +} + +void TASEDIT_LIST::FollowPlayback() +{ + if (TASEdit_follow_playback) ListView_EnsureVisible(hwndList,currFrameCounter,FALSE); +} +void TASEDIT_LIST::FollowUndo() +{ + int jump_frame = history.GetUndoHint(); + if (TASEdit_jump_to_undo && jump_frame >= 0) + { + if (!CheckItemVisible(jump_frame)) + { + // center list at jump_frame + int list_items = listItems; + if (currMovieData.fourscore) list_items--; + int lower_border = (list_items - 1) / 2; + int upper_border = (list_items - 1) - lower_border; + int index = jump_frame + lower_border; + if (index >= currMovieData.getNumRecords()) + index = currMovieData.getNumRecords()-1; + ListView_EnsureVisible(hwndList, index, false); + index = jump_frame - upper_border; + if (index < 0) + index = 0; + ListView_EnsureVisible(hwndList, index, false); + } + } +} +void TASEDIT_LIST::FollowSelection() +{ + SelectionFrames* current_selection = selection.MakeStrobe(); + if (current_selection->size() == 0) return; + + int list_items = listItems; + if (currMovieData.fourscore) list_items--; + int selection_start = *current_selection->begin(); + int selection_end = *current_selection->rbegin(); + int selection_items = 1 + selection_end - selection_start; + + if (selection_items <= list_items) + { + // selected region can fit in screen + int lower_border = (list_items - selection_items) / 2; + int upper_border = (list_items - selection_items) - lower_border; + int index = selection_end + lower_border; + if (index >= currMovieData.getNumRecords()) + index = currMovieData.getNumRecords()-1; + ListView_EnsureVisible(hwndList, index, false); + index = selection_start - upper_border; + if (index < 0) + index = 0; + ListView_EnsureVisible(hwndList, index, false); + } else + { + // selected region is too big to fit in screen + // just center at selection_start + int lower_border = (list_items - 1) / 2; + int upper_border = (list_items - 1) - lower_border; + int index = selection_start + lower_border; + if (index >= currMovieData.getNumRecords()) + index = currMovieData.getNumRecords()-1; + ListView_EnsureVisible(hwndList, index, false); + index = selection_start - upper_border; + if (index < 0) + index = 0; + ListView_EnsureVisible(hwndList, index, false); + } +} +void TASEDIT_LIST::FollowPauseframe() +{ + int jump_frame = playback.GetPauseFrame(); + if (jump_frame >= 0) + { + // center list at jump_frame + int list_items = listItems; + if (currMovieData.fourscore) list_items--; + int lower_border = (list_items - 1) / 2; + int upper_border = (list_items - 1) - lower_border; + int index = jump_frame + lower_border; + if (index >= currMovieData.getNumRecords()) + index = currMovieData.getNumRecords()-1; + ListView_EnsureVisible(hwndList, index, false); + index = jump_frame - upper_border; + if (index < 0) + index = 0; + ListView_EnsureVisible(hwndList, index, false); + } +} + +void TASEDIT_LIST::GetDispInfo(NMLVDISPINFO* nmlvDispInfo) +{ + LVITEM& item = nmlvDispInfo->item; + if(item.mask & LVIF_TEXT) + { + switch(item.iSubItem) + { + case COLUMN_ICONS: + { + if(item.iImage == I_IMAGECALLBACK) + { + item.iImage = bookmarks.FindBookmarkAtFrame(item.iItem); + if (item.iImage < 0) + { + if (item.iItem == currFrameCounter) + item.iImage = ARROW_IMAGE_ID; + } + } + break; + } + case COLUMN_FRAMENUM: + case COLUMN_FRAMENUM2: + { + U32ToDecStr(item.pszText, item.iItem, DIGITS_IN_FRAMENUM); + break; + } + case COLUMN_JOYPAD1_A: case COLUMN_JOYPAD1_B: case COLUMN_JOYPAD1_S: case COLUMN_JOYPAD1_T: + case COLUMN_JOYPAD1_U: case COLUMN_JOYPAD1_D: case COLUMN_JOYPAD1_L: case COLUMN_JOYPAD1_R: + case COLUMN_JOYPAD2_A: case COLUMN_JOYPAD2_B: case COLUMN_JOYPAD2_S: case COLUMN_JOYPAD2_T: + case COLUMN_JOYPAD2_U: case COLUMN_JOYPAD2_D: case COLUMN_JOYPAD2_L: case COLUMN_JOYPAD2_R: + case COLUMN_JOYPAD3_A: case COLUMN_JOYPAD3_B: case COLUMN_JOYPAD3_S: case COLUMN_JOYPAD3_T: + case COLUMN_JOYPAD3_U: case COLUMN_JOYPAD3_D: case COLUMN_JOYPAD3_L: case COLUMN_JOYPAD3_R: + case COLUMN_JOYPAD4_A: case COLUMN_JOYPAD4_B: case COLUMN_JOYPAD4_S: case COLUMN_JOYPAD4_T: + case COLUMN_JOYPAD4_U: case COLUMN_JOYPAD4_D: case COLUMN_JOYPAD4_L: case COLUMN_JOYPAD4_R: + { + int joy = (item.iSubItem - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS; + int bit = (item.iSubItem - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS; + uint8 data = currMovieData.records[item.iItem].joysticks[joy]; + if(data & (1<nmcd.dwDrawStage) + { + case CDDS_PREPAINT: + return CDRF_NOTIFYITEMDRAW; + case CDDS_ITEMPREPAINT: + return CDRF_NOTIFYSUBITEMDRAW; + case CDDS_SUBITEMPREPAINT: + cell_x = msg->iSubItem; + cell_y = msg->nmcd.dwItemSpec; + + + + if(cell_x > COLUMN_ICONS) + { + SelectObject(msg->nmcd.hdc, hMainListFont); + // text color + if(TASEdit_enable_hot_changes && cell_x >= COLUMN_JOYPAD1_A && cell_x <= COLUMN_JOYPAD4_R) + { + msg->clrText = hot_changes_colors[history.GetCurrentSnapshot().GetHotChangeInfo(cell_y, cell_x - COLUMN_JOYPAD1_A)]; + } else msg->clrText = NORMAL_TEXT_COLOR; + // bg color + if(cell_x == COLUMN_FRAMENUM || cell_x == COLUMN_FRAMENUM2) + { + // frame number + if (cell_y == history.GetUndoHint()) + { + // undo hint here + if(TASEdit_show_markers && (int)markers.markers_array.size() > cell_y && (markers.markers_array[cell_y] & MARKER_FLAG_BIT)) + msg->clrTextBk = MARKED_UNDOHINT_FRAMENUM_COLOR; + else + msg->clrTextBk = UNDOHINT_FRAMENUM_COLOR; + } else if (cell_y == currFrameCounter || cell_y == (playback.GetPauseFrame() - 1)) + { + // current frame + if(TASEdit_show_markers && (int)markers.markers_array.size() > cell_y && (markers.markers_array[cell_y] & MARKER_FLAG_BIT)) + // this frame is also marked + msg->clrTextBk = CUR_MARKED_FRAMENUM_COLOR; + else + msg->clrTextBk = CUR_FRAMENUM_COLOR; + } else if(TASEdit_show_markers && (int)markers.markers_array.size() > cell_y && (markers.markers_array[cell_y] & MARKER_FLAG_BIT)) + { + // marked frame + msg->clrTextBk = MARKED_FRAMENUM_COLOR; + } else if(cell_y < greenzone.greenZoneCount) + { + if (!greenzone.savestates[cell_y].empty()) + { + if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) + msg->clrTextBk = LAG_FRAMENUM_COLOR; + else + msg->clrTextBk = GREENZONE_FRAMENUM_COLOR; + } else if ((!greenzone.savestates[cell_y & EVERY16TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0xF) + 1 && !greenzone.savestates[(cell_y | 0xF) + 1].empty()) + || (!greenzone.savestates[cell_y & EVERY8TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x7) + 1 && !greenzone.savestates[(cell_y | 0x7) + 1].empty()) + || (!greenzone.savestates[cell_y & EVERY4TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x3) + 1 && !greenzone.savestates[(cell_y | 0x3) + 1].empty()) + || (!greenzone.savestates[cell_y & EVERY2ND].empty() && !greenzone.savestates[(cell_y | 0x1) + 1].empty())) + { + if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) + msg->clrTextBk = PALE_LAG_FRAMENUM_COLOR; + else + msg->clrTextBk = PALE_GREENZONE_FRAMENUM_COLOR; + } else msg->clrTextBk = NORMAL_FRAMENUM_COLOR; + } else msg->clrTextBk = NORMAL_FRAMENUM_COLOR; + } else if((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 0 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 2) + { + // pad 1 or 3 + if (cell_y == history.GetUndoHint()) + { + // undo hint here + msg->clrTextBk = UNDOHINT_INPUT_COLOR1; + } else if (cell_y == currFrameCounter || cell_y == (playback.GetPauseFrame() - 1)) + { + // current frame + msg->clrTextBk = CUR_INPUT_COLOR1; + } else if(cell_y < greenzone.greenZoneCount) + { + if (!greenzone.savestates[cell_y].empty()) + { + if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) + msg->clrTextBk = LAG_INPUT_COLOR1; + else + msg->clrTextBk = GREENZONE_INPUT_COLOR1; + } else if ((!greenzone.savestates[cell_y & EVERY16TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0xF) + 1 && !greenzone.savestates[(cell_y | 0xF) + 1].empty()) + || (!greenzone.savestates[cell_y & EVERY8TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x7) + 1 && !greenzone.savestates[(cell_y | 0x7) + 1].empty()) + || (!greenzone.savestates[cell_y & EVERY4TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x3) + 1 && !greenzone.savestates[(cell_y | 0x3) + 1].empty()) + || (!greenzone.savestates[cell_y & EVERY2ND].empty() && !greenzone.savestates[(cell_y | 0x1) + 1].empty())) + { + if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) + msg->clrTextBk = PALE_LAG_INPUT_COLOR1; + else + msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR1; + } else msg->clrTextBk = NORMAL_INPUT_COLOR1; + } else msg->clrTextBk = NORMAL_INPUT_COLOR1; + } else if((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 1 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 3) + { + // pad 2 or 4 + if (cell_y == history.GetUndoHint()) + { + // undo hint here + msg->clrTextBk = UNDOHINT_INPUT_COLOR2; + } else if (cell_y == currFrameCounter || cell_y == (playback.GetPauseFrame() - 1)) + { + // current frame + msg->clrTextBk = CUR_INPUT_COLOR2; + } else if(cell_y < greenzone.greenZoneCount) + { + if (!greenzone.savestates[cell_y].empty()) + { + if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) + msg->clrTextBk = LAG_INPUT_COLOR2; + else + msg->clrTextBk = GREENZONE_INPUT_COLOR2; + } else if ((!greenzone.savestates[cell_y & EVERY16TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0xF) + 1 && !greenzone.savestates[(cell_y | 0xF) + 1].empty()) + || (!greenzone.savestates[cell_y & EVERY8TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x7) + 1 && !greenzone.savestates[(cell_y | 0x7) + 1].empty()) + || (!greenzone.savestates[cell_y & EVERY4TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x3) + 1 && !greenzone.savestates[(cell_y | 0x3) + 1].empty()) + || (!greenzone.savestates[cell_y & EVERY2ND].empty() && !greenzone.savestates[(cell_y | 0x1) + 1].empty())) + { + if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y]) + msg->clrTextBk = PALE_LAG_INPUT_COLOR2; + else + msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR2; + } else msg->clrTextBk = NORMAL_INPUT_COLOR2; + } else msg->clrTextBk = NORMAL_INPUT_COLOR2; + } + } + default: + return CDRF_DODEFAULT; + } +} +// ------------------------------------------------------------------------- +LRESULT APIENTRY HeaderWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_SETCURSOR: + return true; // no column resizing + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + { + if (selection.GetCurrentSelectionSize()) + { + //perform hit test + HD_HITTESTINFO info; + info.pt.x = GET_X_LPARAM(lParam); + info.pt.y = GET_Y_LPARAM(lParam); + SendMessage(hWnd,HDM_HITTEST,0,(LPARAM)&info); + if(info.iItem >= COLUMN_FRAMENUM && info.iItem <= COLUMN_FRAMENUM2) + ColumnSet(info.iItem); + } + } + return true; + } + return CallWindowProc(hwndHeader_oldWndproc, hWnd, msg, wParam, lParam); +} + +//The subclass wndproc for the listview +LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_CHAR: + case WM_KILLFOCUS: + return 0; + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + case HDN_BEGINTRACKW: + case HDN_BEGINTRACKA: + case HDN_TRACK: + return true; // no column resizing + } + break; + } + case WM_SYSKEYDOWN: + { + if (wParam == VK_F10) + return 0; + break; + } + } + return CallWindowProc(hwndList_oldWndProc, hWnd, msg, wParam, lParam); +} + + diff --git a/src/drivers/win/taseditlib/tasedit_list.h b/src/drivers/win/taseditlib/tasedit_list.h new file mode 100644 index 00000000..90811f36 --- /dev/null +++ b/src/drivers/win/taseditlib/tasedit_list.h @@ -0,0 +1,121 @@ +//Specification file for TASEDIT_LIST class +#define CDDS_SUBITEMPREPAINT (CDDS_SUBITEM | CDDS_ITEMPREPAINT) +#define CDDS_SUBITEMPOSTPAINT (CDDS_SUBITEM | CDDS_ITEMPOSTPAINT) +#define CDDS_SUBITEMPREERASE (CDDS_SUBITEM | CDDS_ITEMPREERASE) +#define CDDS_SUBITEMPOSTERASE (CDDS_SUBITEM | CDDS_ITEMPOSTERASE) + +#define NUM_JOYPADS 4 +#define NUM_JOYPAD_BUTTONS 8 + +#define COLUMN_ICONS 0 +#define COLUMN_FRAMENUM 1 +#define COLUMN_JOYPAD1_A 2 +#define COLUMN_JOYPAD1_B 3 +#define COLUMN_JOYPAD1_S 4 +#define COLUMN_JOYPAD1_T 5 +#define COLUMN_JOYPAD1_U 6 +#define COLUMN_JOYPAD1_D 7 +#define COLUMN_JOYPAD1_L 8 +#define COLUMN_JOYPAD1_R 9 +#define COLUMN_JOYPAD2_A 10 +#define COLUMN_JOYPAD2_B 11 +#define COLUMN_JOYPAD2_S 12 +#define COLUMN_JOYPAD2_T 13 +#define COLUMN_JOYPAD2_U 14 +#define COLUMN_JOYPAD2_D 15 +#define COLUMN_JOYPAD2_L 16 +#define COLUMN_JOYPAD2_R 17 +#define COLUMN_JOYPAD3_A 18 +#define COLUMN_JOYPAD3_B 19 +#define COLUMN_JOYPAD3_S 20 +#define COLUMN_JOYPAD3_T 21 +#define COLUMN_JOYPAD3_U 22 +#define COLUMN_JOYPAD3_D 23 +#define COLUMN_JOYPAD3_L 24 +#define COLUMN_JOYPAD3_R 25 +#define COLUMN_JOYPAD4_A 26 +#define COLUMN_JOYPAD4_B 27 +#define COLUMN_JOYPAD4_S 28 +#define COLUMN_JOYPAD4_T 29 +#define COLUMN_JOYPAD4_U 30 +#define COLUMN_JOYPAD4_D 31 +#define COLUMN_JOYPAD4_L 32 +#define COLUMN_JOYPAD4_R 33 +#define COLUMN_FRAMENUM2 34 +#define DIGITS_IN_FRAMENUM 7 +#define ARROW_IMAGE_ID 20 + +// listview colors +#define NORMAL_TEXT_COLOR 0x0 + +#define NORMAL_FRAMENUM_COLOR 0xFFFFFF +#define NORMAL_INPUT_COLOR1 0xEDEDED +#define NORMAL_INPUT_COLOR2 0xDEDEDE + +#define GREENZONE_FRAMENUM_COLOR 0xDDFFDD +#define GREENZONE_INPUT_COLOR1 0xC8F7C4 +#define GREENZONE_INPUT_COLOR2 0xAEE2AE + +#define PALE_GREENZONE_FRAMENUM_COLOR 0xE4FFE4 +#define PALE_GREENZONE_INPUT_COLOR1 0xD5F9D4 +#define PALE_GREENZONE_INPUT_COLOR2 0xBAE6BA + +#define LAG_FRAMENUM_COLOR 0xDBDAFF +#define LAG_INPUT_COLOR1 0xCECBEF +#define LAG_INPUT_COLOR2 0xBEBAE4 + +#define PALE_LAG_FRAMENUM_COLOR 0xE1E1FF +#define PALE_LAG_INPUT_COLOR1 0xD6D3F1 +#define PALE_LAG_INPUT_COLOR2 0xC7C4E8 + +#define CUR_FRAMENUM_COLOR 0xFCF1CE +#define CUR_INPUT_COLOR1 0xF7E9B2 +#define CUR_INPUT_COLOR2 0xE4D8A8 + +#define UNDOHINT_FRAMENUM_COLOR 0xF9DDE6 +#define UNDOHINT_INPUT_COLOR1 0xF6CCDD +#define UNDOHINT_INPUT_COLOR2 0xE5B7CC + +#define MARKED_FRAMENUM_COLOR 0xC0FCFF +#define CUR_MARKED_FRAMENUM_COLOR 0xDEF7F3 +#define MARKED_UNDOHINT_FRAMENUM_COLOR 0xE1E7EC + + + +class TASEDIT_LIST +{ +public: + TASEDIT_LIST(); + void init(); + void free(); + void update(); + + void AddFourscore(); + void RemoveFourscore(); + + void RedrawList(); + void RedrawRow(int index); + + bool CheckItemVisible(int frame); + + void FollowPlayback(); + void FollowUndo(); + void FollowSelection(); + void FollowPauseframe(); + + void GetDispInfo(NMLVDISPINFO* nmlvDispInfo); + LONG CustomDraw(NMLVCUSTOMDRAW* msg); + + + HWND hwndList, hwndHeader; + HIMAGELIST himglist; + +private: + int listItems; // number of items per list page + + + // GDI stuff + HFONT hMainListFont, hMainListSelectFont; + + +}; diff --git a/src/drivers/win/taseditlib/tasedit_sel.cpp b/src/drivers/win/taseditlib/tasedit_sel.cpp index 3210d056..ed3b3811 100644 --- a/src/drivers/win/taseditlib/tasedit_sel.cpp +++ b/src/drivers/win/taseditlib/tasedit_sel.cpp @@ -7,9 +7,7 @@ char selection_save_id[SELECTION_ID_LEN] = "SELECTION"; extern MARKERS markers; - -extern HWND hwndList; -extern void RedrawList(); +extern TASEDIT_LIST tasedit_list; TASEDIT_SELECTION::TASEDIT_SELECTION() { @@ -40,7 +38,7 @@ void TASEDIT_SELECTION::free() void TASEDIT_SELECTION::update() { - // keep selection within list limits + // keep selection within movie limits if (CurrentSelection().size()) { int delete_index; @@ -56,13 +54,6 @@ void TASEDIT_SELECTION::update() } -bool TASEDIT_SELECTION::CheckFrameSelected(int frame) -{ - if(CurrentSelection().find(frame) == CurrentSelection().end()) - return false; - return true; -} - void TASEDIT_SELECTION::save(EMUFILE *os) { // write "SELECTION" string @@ -228,11 +219,6 @@ void TASEDIT_SELECTION::AddNewSelectionToHistory() selections_history[(history_start_pos + history_cursor_pos) % history_size] = selectionFrames; } -SelectionFrames& TASEDIT_SELECTION::CurrentSelection() -{ - return selections_history[(history_start_pos + history_cursor_pos) % history_size]; -} - void TASEDIT_SELECTION::jump(int new_pos) { if (new_pos < 0) new_pos = 0; else if (new_pos >= history_total_items) new_pos = history_total_items-1; @@ -256,8 +242,8 @@ void TASEDIT_SELECTION::redo() void TASEDIT_SELECTION::MemorizeClipboardSelection() { - // copy current selection data to clipboard_selection - clipboard_selection = CurrentSelection(); + // copy currently strobed selection data to clipboard_selection + clipboard_selection = temp_selection; } void TASEDIT_SELECTION::ReselectClipboard() { @@ -272,11 +258,11 @@ void TASEDIT_SELECTION::ReselectClipboard() // ---------------------------------------------------------- void TASEDIT_SELECTION::ClearSelection() { - ListView_SetItemState(hwndList, -1, 0, LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, -1, 0, LVIS_FOCUSED|LVIS_SELECTED); } void TASEDIT_SELECTION::ClearRowSelection(int index) { - ListView_SetItemState(hwndList, index, 0, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, index, 0, LVIS_SELECTED); } void TASEDIT_SELECTION::EnforceSelectionToList() @@ -285,24 +271,24 @@ void TASEDIT_SELECTION::EnforceSelectionToList() ClearSelection(); for(SelectionFrames::reverse_iterator it(CurrentSelection().rbegin()); it != CurrentSelection().rend(); it++) { - ListView_SetItemState(hwndList, *it, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, *it, LVIS_SELECTED, LVIS_SELECTED); } track_selection_changes = true; } void TASEDIT_SELECTION::SelectAll() { - ListView_SetItemState(hwndList, -1, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, -1, LVIS_SELECTED, LVIS_SELECTED); //RedrawList(); } void TASEDIT_SELECTION::SetRowSelection(int index) { - ListView_SetItemState(hwndList, index, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, index, LVIS_SELECTED, LVIS_SELECTED); } void TASEDIT_SELECTION::SetRegionSelection(int start, int end) { for (int i = start; i <= end; ++i) - ListView_SetItemState(hwndList, i, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, i, LVIS_SELECTED, LVIS_SELECTED); } void TASEDIT_SELECTION::SelectMidMarkers() { @@ -326,7 +312,7 @@ void TASEDIT_SELECTION::SelectMidMarkers() if (markers.markers_array[lower_marker] & MARKER_FLAG_BIT) break; // clear selection without clearing focused, because otherwise there's strange bug when quickly pressing Ctrl+A right after clicking on already selected row - ListView_SetItemState(hwndList, -1, 0, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, -1, 0, LVIS_SELECTED); // special case if (upper_marker == -1 && lower_marker == movie_size) @@ -341,7 +327,7 @@ void TASEDIT_SELECTION::SelectMidMarkers() // default: select all between markers for (int i = upper_marker+1; i < lower_marker; ++i) { - ListView_SetItemState(hwndList, i, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, i, LVIS_SELECTED, LVIS_SELECTED); } } else if (upper_border == upper_marker+1 && lower_border == lower_marker-1) { @@ -350,14 +336,14 @@ void TASEDIT_SELECTION::SelectMidMarkers() if (lower_marker >= movie_size) lower_marker = movie_size - 1; for (int i = upper_marker; i <= lower_marker; ++i) { - ListView_SetItemState(hwndList, i, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, i, LVIS_SELECTED, LVIS_SELECTED); } } else if (upper_border <= upper_marker && lower_border >= lower_marker) { // selected all between markers and both markers selected too - now deselect lower marker for (int i = upper_marker; i < lower_marker; ++i) { - ListView_SetItemState(hwndList, i, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, i, LVIS_SELECTED, LVIS_SELECTED); } } else if (upper_border == upper_marker && lower_border == lower_marker-1) { @@ -365,22 +351,48 @@ void TASEDIT_SELECTION::SelectMidMarkers() if (lower_marker >= movie_size) lower_marker = movie_size - 1; for (int i = upper_marker+1; i <= lower_marker; ++i) { - ListView_SetItemState(hwndList, i, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, i, LVIS_SELECTED, LVIS_SELECTED); } } else if (upper_border == upper_marker+1 && lower_border == lower_marker) { // selected all between markers and lower marker selected too - now deselect lower marker (return to "selected all between markers") for (int i = upper_marker + 1; i < lower_marker; ++i) { - ListView_SetItemState(hwndList, i, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(tasedit_list.hwndList, i, LVIS_SELECTED, LVIS_SELECTED); } } } - - - - - - - +// getters +int TASEDIT_SELECTION::GetCurrentSelectionSize() +{ + return selections_history[(history_start_pos + history_cursor_pos) % history_size].size(); +} +int TASEDIT_SELECTION::GetCurrentSelectionBeginning() +{ + if (selections_history[(history_start_pos + history_cursor_pos) % history_size].size()) + return *selections_history[(history_start_pos + history_cursor_pos) % history_size].begin(); + else + return -1; +} +bool TASEDIT_SELECTION::CheckFrameSelected(int frame) +{ + if(CurrentSelection().find(frame) == CurrentSelection().end()) + return false; + return true; +} +SelectionFrames* TASEDIT_SELECTION::MakeStrobe() +{ + // copy current selection to temp_selection + temp_selection = selections_history[(history_start_pos + history_cursor_pos) % history_size]; + return &temp_selection; +} +SelectionFrames& TASEDIT_SELECTION::GetStrobedSelection() +{ + return temp_selection; +} +// this getter is only for inside-class use +SelectionFrames& TASEDIT_SELECTION::CurrentSelection() +{ + return selections_history[(history_start_pos + history_cursor_pos) % history_size]; +} diff --git a/src/drivers/win/taseditlib/tasedit_sel.h b/src/drivers/win/taseditlib/tasedit_sel.h index c5636c7a..4ace8763 100644 --- a/src/drivers/win/taseditlib/tasedit_sel.h +++ b/src/drivers/win/taseditlib/tasedit_sel.h @@ -20,7 +20,6 @@ public: void ItemChanged(NMLISTVIEW* info); void AddNewSelectionToHistory(); - SelectionFrames& CurrentSelection(); void undo(); void redo(); @@ -39,10 +38,16 @@ public: void SetRegionSelection(int start, int end); void SelectMidMarkers(); - + // getters + int GetCurrentSelectionSize(); + int GetCurrentSelectionBeginning(); bool CheckFrameSelected(int frame); + SelectionFrames* MakeStrobe(); + SelectionFrames& GetStrobedSelection(); private: + SelectionFrames& CurrentSelection(); + bool track_selection_changes; std::vector selections_history; @@ -53,5 +58,6 @@ private: int history_total_items; int history_size; + SelectionFrames temp_selection; }; diff --git a/src/drivers/win/taseditlib/taseditproj.cpp b/src/drivers/win/taseditlib/taseditproj.cpp index 4c1ded27..fc14907c 100644 --- a/src/drivers/win/taseditlib/taseditproj.cpp +++ b/src/drivers/win/taseditlib/taseditproj.cpp @@ -9,6 +9,7 @@ extern BOOKMARKS bookmarks; extern GREENZONE greenzone; extern PLAYBACK playback; extern INPUT_HISTORY history; +extern TASEDIT_LIST tasedit_list; extern TASEDIT_SELECTION selection; extern void FCEU_printf(char *format, ...); @@ -81,7 +82,7 @@ bool TASEDIT_PROJECT::LoadProject(std::string PFN) bool error; LoadFM2(currMovieData, &ifs, ifs.size(), false); LoadSubtitles(currMovieData); - UpdateList(); + tasedit_list.update(); // try to load markers error = markers.load(&ifs); if (error) diff --git a/src/drivers/win/taseditlib/taseditproj.h b/src/drivers/win/taseditlib/taseditproj.h index 46d91719..fe4ec303 100644 --- a/src/drivers/win/taseditlib/taseditproj.h +++ b/src/drivers/win/taseditlib/taseditproj.h @@ -11,6 +11,7 @@ typedef std::set SelectionFrames; #include "greenzone.h" #include "markers.h" #include "bookmarks.h" +#include "tasedit_list.h" #include "tasedit_sel.h" class TASEDIT_PROJECT diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index fdb310e4..3af47dde 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -50,7 +50,6 @@ #include "cdlogger.h" #include "throttle.h" #include "monitor.h" -#include "tasedit.h" #include "keyboard.h" #include "joystick.h" #include "oldmovie.h" @@ -1923,6 +1922,7 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) // break; // Removing this tool since it is redundant to both case MENU_TASEDIT: + extern void EnterTasEdit(); EnterTasEdit(); break; case MENU_CONVERT_MOVIE: diff --git a/src/input.cpp b/src/input.cpp index 64fefff6..d8444b28 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -589,6 +589,7 @@ void FCEUI_ResetNES(void) return; FCEU_QSimpleCommand(FCEUNPCMD_RESET); ResetFrameCounter(); + FCEU_DispMessage("Soft reset", 0); } //Powers off the NES @@ -598,6 +599,7 @@ void FCEUI_PowerNES(void) return; FCEU_QSimpleCommand(FCEUNPCMD_POWER); ResetFrameCounter(); + FCEU_DispMessage("Power switch", 0); } const char* FCEUI_CommandTypeNames[]= diff --git a/src/movie.h b/src/movie.h index 3c0d52b9..0ca1af87 100644 --- a/src/movie.h +++ b/src/movie.h @@ -252,7 +252,6 @@ extern bool subtitlesOnAVI; extern bool freshMovie; extern bool movie_readonly; extern bool autoMovieBackup; -extern int pauseframe; extern bool fullSaveStateLoads; //-------------------------------------------------- void FCEUI_MakeBackupMovie(bool dispMessage); diff --git a/vc/vc10_fceux.vcxproj b/vc/vc10_fceux.vcxproj index 7b84670f..4e29fd86 100644 --- a/vc/vc10_fceux.vcxproj +++ b/vc/vc10_fceux.vcxproj @@ -426,6 +426,7 @@ + @@ -739,6 +740,7 @@ + diff --git a/vc/vc10_fceux.vcxproj.filters b/vc/vc10_fceux.vcxproj.filters index e5db2ea7..66f4f317 100644 --- a/vc/vc10_fceux.vcxproj.filters +++ b/vc/vc10_fceux.vcxproj.filters @@ -929,6 +929,7 @@ drivers\win\taseditlib + @@ -1377,6 +1378,7 @@ drivers\win\taseditlib +