diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index 9ae26396..386c4ada 100644 --- a/src/drivers/win/res.rc +++ b/src/drivers/win/res.rc @@ -275,8 +275,8 @@ BEGIN MENUITEM SEPARATOR MENUITEM "&Bind Markers to Input", ID_CONFIG_BINDMARKERSTOINPUT MENUITEM SEPARATOR - MENUITEM "&Use 1P keys for all single Recordings", ID_CONFIG_USE1PFORRECORDING MENUITEM "&Combine consecutive Recordings", ID_CONFIG_COMBINECONSECUTIVERECORDINGS + MENUITEM "&Use 1P keys for all single Recordings", ID_CONFIG_USE1PFORRECORDING MENUITEM "&Superimpose affects copy/paste", ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE MENUITEM SEPARATOR MENUITEM "Mute &Turbo", ID_CONFIG_MUTETURBO @@ -368,6 +368,8 @@ BEGIN END POPUP "Selected" BEGIN + MENUITEM "Set Marker", ID_SELECTED_SETMARKER + MENUITEM "Remove Marker", ID_SELECTED_REMOVEMARKER MENUITEM "Select mid &Markers", ID_SELECTED_SELECTMIDMARKERS MENUITEM SEPARATOR MENUITEM "C&lear", ID_CONTEXT_SELECTED_CLEARFRAMES diff --git a/src/drivers/win/resource.h b/src/drivers/win/resource.h index 5080c17a..09aad912 100644 --- a/src/drivers/win/resource.h +++ b/src/drivers/win/resource.h @@ -913,6 +913,9 @@ #define ID_EDIT_PASTEINSERT 40495 #define ID_CONFIG_SUPERIMPOSEAFFECTSCOPY 40496 #define ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE 40497 +#define ID_SELECTED_SETMARKER 40498 +#define ID_SELECTED_CLEARMARKER 40499 +#define ID_SELECTED_REMOVEMARKER40500 40500 #define IDC_DEBUGGER_ICONTRAY 55535 #define MW_ValueLabel2 65423 #define MW_ValueLabel1 65426 @@ -922,7 +925,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 185 -#define _APS_NEXT_COMMAND_VALUE 40498 +#define _APS_NEXT_COMMAND_VALUE 40501 #define _APS_NEXT_CONTROL_VALUE 1269 #define _APS_NEXT_SYMED_VALUE 101 #endif diff --git a/src/drivers/win/tasedit.cpp b/src/drivers/win/tasedit.cpp index bab3cb31..6748b4bf 100644 --- a/src/drivers/win/tasedit.cpp +++ b/src/drivers/win/tasedit.cpp @@ -108,39 +108,53 @@ void RedrawTasedit() InvalidateRect(hwndTasEdit, 0, FALSE); } -void ShowMenu(ECONTEXTMENU which, POINT& pt) -{ - HMENU sub = GetSubMenu(hrmenu,(int)which); - TrackPopupMenu(sub,0,pt.x,pt.y,TPM_RIGHTBUTTON,hwndTasEdit,0); -} - void StrayClickMenu(LPNMITEMACTIVATE info) { POINT pt = info->ptAction; ClientToScreen(tasedit_list.hwndList, &pt); - ShowMenu(CONTEXTMENU_STRAY, pt); + HMENU sub = GetSubMenu(hrmenu, CONTEXTMENU_STRAY); + TrackPopupMenu(sub, 0, pt.x, pt.y, 0, hwndTasEdit, 0); } - void RightClickMenu(LPNMITEMACTIVATE info) { POINT pt = info->ptAction; ClientToScreen(tasedit_list.hwndList, &pt); - ShowMenu(CONTEXTMENU_SELECTED, pt); -} -void RightClick(LPNMITEMACTIVATE info) -{ - int index = info->iItem; - int column = info->iSubItem; - - //stray clicks give a context menu: - if(index == -1) + SelectionFrames* current_selection = selection.MakeStrobe(); + if (current_selection->size() == 0) { StrayClickMenu(info); return; } + HMENU sub = GetSubMenu(hrmenu, CONTEXTMENU_SELECTED); + // inspect current selection and disable inappropriate menu items + SelectionFrames::iterator current_selection_begin(current_selection->begin()); + SelectionFrames::iterator current_selection_end(current_selection->end()); + bool set_found = false, unset_found = false; + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) + { + if(markers.GetMarker(*it)) + set_found = true; + else + unset_found = true; + } + if (set_found) + EnableMenuItem(sub, ID_SELECTED_REMOVEMARKER, MF_BYCOMMAND | MF_ENABLED); + else + EnableMenuItem(sub, ID_SELECTED_REMOVEMARKER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + if (unset_found) + EnableMenuItem(sub, ID_SELECTED_SETMARKER, MF_BYCOMMAND | MF_ENABLED); + else + EnableMenuItem(sub, ID_SELECTED_SETMARKER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); - if (selection.CheckFrameSelected(index)) + TrackPopupMenu(sub, 0, pt.x, pt.y, 0, hwndTasEdit, 0); +} +void RightClick(LPNMITEMACTIVATE info) +{ + int index = info->iItem; + if(index == -1) + StrayClickMenu(info); + else if (selection.CheckFrameSelected(index)) RightClickMenu(info); } @@ -382,74 +396,93 @@ void Truncate() } } -//the column set operation, for setting a button/Marker for a span of selected values void ColumnSet(int column) +{ + if (column == COLUMN_FRAMENUM || column == COLUMN_FRAMENUM2) + FrameColumnSet(); + else + InputColumnSet(column); +} +void FrameColumnSet() { 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) + + // inspect the selected frames, if they are all set, then unset all, else set all + bool unset_found = false, changes_made = false; + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) { - // Markers column - // inspect the selected frames, if they are all set, then unset all, else set all - bool unset_found = false; + if(!markers.GetMarker(*it)) + { + unset_found = true; + break; + } + } + if (unset_found) + { + + // set all for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) { if(!markers.GetMarker(*it)) { - unset_found = true; - break; - } - } - if (unset_found) - { - // set all - for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) - { + changes_made = true; markers.SetMarker(*it); tasedit_list.RedrawRow(*it); } + } + if (changes_made) history.RegisterChanges(MODTYPE_MARKER_SET, *current_selection_begin, *current_selection->rbegin()); - } else + } else + { + // unset all + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) { - // unset all - for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) + if(markers.GetMarker(*it)) { + changes_made = true; markers.ClearMarker(*it); tasedit_list.RedrawRow(*it); } - history.RegisterChanges(MODTYPE_MARKER_UNSET, *current_selection_begin, *current_selection->rbegin()); } + if (changes_made) + history.RegisterChanges(MODTYPE_MARKER_UNSET, *current_selection_begin, *current_selection->rbegin()); + } + if (changes_made) project.SetProjectChanged(); - // no need to RedrawList(); +} +void InputColumnSet(int column) +{ + int joy = (column - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS; + if (joy < 0 || joy >= NUM_JOYPADS) return; + int button = (column - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS; + + 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()); + + //inspect the selected frames, if they are all set, then unset all, else set all + bool newValue = false; + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) + { + if(!(currMovieData.records[*it].checkBit(joy,button))) + { + newValue = true; + break; + } + } + // apply newValue + 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, *current_selection_begin, *current_selection->rbegin())); } else { - // buttons column - int joy = (column - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS; - if (joy < 0 || joy >= NUM_JOYPADS) return; - 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(current_selection_begin); it != current_selection_end; it++) - { - if(!(currMovieData.records[*it].checkBit(joy,button))) - { - newValue = true; - break; - } - } - // apply newValue - 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, *current_selection_begin, *current_selection->rbegin())); - } else - { - greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_UNSET, *current_selection_begin, *current_selection->rbegin())); - } + greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_UNSET, *current_selection_begin, *current_selection->rbegin())); } } @@ -551,7 +584,7 @@ bool Paste() { char *pGlobal = (char*)GlobalLock((HGLOBAL)hGlobal); - // TAS recording info starts with "TAS ". + // TAS recording info starts with "TAS " if (pGlobal[0]=='T' && pGlobal[1]=='A' && pGlobal[2]=='S') { // Extract number of frames @@ -567,12 +600,11 @@ bool Paste() int joy = 0; uint8 new_buttons = 0; char* frame; - --pos; while (pGlobal++ && *pGlobal!='\0') { + // Detect skipped frames in paste frame = pGlobal; - // Detect skipped frames in paste. if (frame[0]=='+') { pos += atoi(frame+1); @@ -653,7 +685,7 @@ bool PasteInsert() { char *pGlobal = (char*)GlobalLock((HGLOBAL)hGlobal); - // TAS recording info starts with "TAS ". + // TAS recording info starts with "TAS " if (pGlobal[0]=='T' && pGlobal[1]=='A' && pGlobal[2]=='S') { // make sure markers have the same size as movie @@ -667,14 +699,13 @@ bool PasteInsert() pGlobal = strchr(pGlobal, '\n'); + char* frame; int joy=0; --pos; - while (pGlobal++ && *pGlobal!='\0') { - char *frame = pGlobal; - - // Detect skipped frames in paste. + // Detect skipped frames in paste + frame = pGlobal; if (frame[0]=='+') { pos += atoi(frame+1); @@ -1322,6 +1353,57 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar tasedit_list.FollowSelection(); break; } + case ID_SELECTED_SETMARKER: + { + SelectionFrames* current_selection = selection.MakeStrobe(); + if (current_selection->size()) + { + SelectionFrames::iterator current_selection_begin(current_selection->begin()); + SelectionFrames::iterator current_selection_end(current_selection->end()); + bool changes_made = false; + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) + { + if(!markers.GetMarker(*it)) + { + changes_made = true; + markers.SetMarker(*it); + tasedit_list.RedrawRow(*it); + } + } + if (changes_made) + { + history.RegisterChanges(MODTYPE_MARKER_SET, *current_selection_begin, *current_selection->rbegin()); + project.SetProjectChanged(); + } + } + break; + } + case ID_SELECTED_REMOVEMARKER: + { + SelectionFrames* current_selection = selection.MakeStrobe(); + if (current_selection->size()) + { + SelectionFrames::iterator current_selection_begin(current_selection->begin()); + SelectionFrames::iterator current_selection_end(current_selection->end()); + bool changes_made = false; + for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) + { + if(markers.GetMarker(*it)) + { + changes_made = true; + markers.ClearMarker(*it); + tasedit_list.RedrawRow(*it); + } + } + if (changes_made) + { + history.RegisterChanges(MODTYPE_MARKER_UNSET, *current_selection_begin, *current_selection->rbegin()); + project.SetProjectChanged(); + } + } + break; + } + } break; @@ -1382,17 +1464,9 @@ void EnterTasEdit() SetWindowPos(hwndTasEdit, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER); // init modules - FCEU_printf("1"); greenzone.init(); - FCEU_printf("2"); playback.init(); // either start new movie or use current movie - if (currMovieData.savestate.size() != 0) - { - FCEUD_PrintError("This version of TAS Editor doesn't work with movies starting from savestate."); - // delete savestate, but preserve input - currMovieData.savestate.clear(); - } if (FCEUMOV_Mode(MOVIEMODE_INACTIVE)) { FCEUI_StopMovie(); @@ -1401,6 +1475,12 @@ void EnterTasEdit() } else { // use current movie to create a new project + if (currMovieData.savestate.size() != 0) + { + FCEUD_PrintError("This version of TAS Editor doesn't work with movies starting from savestate."); + // delete savestate, but preserve input + currMovieData.savestate.clear(); + } FCEUI_StopMovie(); greenzone.TryDumpIncremental(lagFlag != 0); } diff --git a/src/drivers/win/tasedit.h b/src/drivers/win/tasedit.h index bd101926..10734426 100644 --- a/src/drivers/win/tasedit.h +++ b/src/drivers/win/tasedit.h @@ -36,6 +36,8 @@ void DeleteFrames(); void ClearFrames(SelectionFrames* current_selection = 0); void Truncate(); void ColumnSet(int column); +void InputColumnSet(int column); +void FrameColumnSet(); bool Copy(SelectionFrames* current_selection = 0); void Cut(); bool Paste(); diff --git a/src/drivers/win/taseditlib/bookmarks.cpp b/src/drivers/win/taseditlib/bookmarks.cpp index 75f85295..6ea5a6f9 100644 --- a/src/drivers/win/taseditlib/bookmarks.cpp +++ b/src/drivers/win/taseditlib/bookmarks.cpp @@ -272,17 +272,18 @@ void BOOKMARKS::set(int slot) bookmarks_array[slot].set(); - // if this screenshot is shown on screen - reinit and redraw it + // if this screenshot is currently shown - reinit and redraw it if (screenshot_display.screenshot_currently_shown == slot) screenshot_display.screenshot_currently_shown = ITEM_UNDER_MOUSE_NONE; + int parent; // inherit current branch if (slot != current_branch) { - int parent = bookmarks_array[slot].parent_branch; + parent = bookmarks_array[slot].parent_branch; if (parent == -1 && saved_time[0]) { - // check if this is the only child of cloud parent, if so then set cloud time to the saved_time + // check if this was the only child of cloud parent, if so then set cloud time to the saved_time int i = 0; for (; i < TOTAL_BOOKMARKS; ++i) { @@ -293,7 +294,7 @@ void BOOKMARKS::set(int slot) // didn't find another child of cloud strcpy(cloud_time, saved_time); } - // before disconnecting from old parent, connect all childs to the parent + // before disconnecting from old parent, connect all childs to the old parent for (int i = 0; i < TOTAL_BOOKMARKS; ++i) { if (bookmarks_array[i].not_empty && bookmarks_array[i].parent_branch == slot) @@ -302,6 +303,69 @@ void BOOKMARKS::set(int slot) bookmarks_array[slot].parent_branch = current_branch; } + // if parent is invalid (first_change < parent.jump_frame) then find better parent + int factor; + // also if parent == cloud, then try to find better parent + parent = bookmarks_array[slot].parent_branch; + if (parent >= 0) + factor = bookmarks_array[slot].snapshot.findFirstChange(bookmarks_array[parent].snapshot); + if (parent < 0 || (factor >= 0 && factor < bookmarks_array[parent].snapshot.jump_frame)) + { + // find highest frame of change + std::vector DecisiveFactor(TOTAL_BOOKMARKS); + int best_branch = -1; + for (int i = TOTAL_BOOKMARKS-1; i >= 0; i--) + { + if (i != slot && i != parent && bookmarks_array[i].not_empty && bookmarks_array[slot].snapshot.size >= bookmarks_array[i].snapshot.jump_frame) + { + factor = bookmarks_array[slot].snapshot.findFirstChange(bookmarks_array[i].snapshot); + if (factor < 0) + { + // this branch is identical to this slot + DecisiveFactor[i] = 2 * bookmarks_array[i].snapshot.size; + } else if (factor >= bookmarks_array[i].snapshot.jump_frame) + { + // hey, this branch could be our new parent... + DecisiveFactor[i] = 2 * factor; + } else + DecisiveFactor[i] = 0; + } else + { + DecisiveFactor[i] = 0; + } + } + // add +1 as a bonus to current parents and grandparents (a bit of nepotism!) + while (parent >= 0) + { + if (DecisiveFactor[parent]) + DecisiveFactor[parent]++; + parent = bookmarks_array[parent].parent_branch; + } + // find max + factor = 0; + for (int i = TOTAL_BOOKMARKS-1; i >= 0; i--) + { + if (DecisiveFactor[i] && DecisiveFactor[i] > factor) + { + factor = DecisiveFactor[i]; + best_branch = i; + } + } + parent = bookmarks_array[slot].parent_branch; + if (parent != best_branch) + { + // before disconnecting from old parent, connect all childs to the old parent + for (int i = 0; i < TOTAL_BOOKMARKS; ++i) + { + if (bookmarks_array[i].not_empty && bookmarks_array[i].parent_branch == slot) + bookmarks_array[i].parent_branch = parent; + } + // found new parent + bookmarks_array[slot].parent_branch = best_branch; + must_recalculate_branches_tree = true; + } + } + // switch current branch to this branch if (slot != current_branch && current_branch >= 0) { @@ -1041,7 +1105,7 @@ void BOOKMARKS::RecalculateBranchesTree() // also define "current_pos" GridX if (current_branch >= 0) { - if (Children[current_branch+1].size() < MAX_NUM_CHILDREN) + if (Children[current_branch+1].size() < MAX_NUM_CHILDREN_ON_CANVAS_HEIGHT) { // "current_pos" becomes a child of current_branch GridX[TOTAL_BOOKMARKS] = GridX[current_branch] + 1; @@ -1053,8 +1117,8 @@ void BOOKMARKS::RecalculateBranchesTree() RecursiveAddHeight(current_branch, 1); } else { - // special case 0: if there's too many items on one level (more than canvas can show) - // "current_pos" becomes special branch above current_branch + // special case 0: if there's too many children on one level (more than canvas can show) + // then "current_pos" becomes special branch above current_branch GridX[TOTAL_BOOKMARKS] = GridX[current_branch]; GridY[TOTAL_BOOKMARKS] = GridY[current_branch] - 7; } @@ -1135,6 +1199,37 @@ void BOOKMARKS::RecalculateBranchesTree() } } } + // special case 4: if cloud has all 10 children, then one child will be out of canvas + if (Children[0].size() == TOTAL_BOOKMARKS) + { + // find this child and move it to be visible + for (int t = TOTAL_BOOKMARKS - 1; t >= 0; t--) + { + if (GridY[t] > MAX_GRID_Y_POS) + { + GridY[t] = MAX_GRID_Y_POS; + GridX[t] -= 2; + // also move fireball to position near this branch + if (changes_since_current_branch && current_branch == t) + { + GridY[TOTAL_BOOKMARKS] = GridY[t]; + GridX[TOTAL_BOOKMARKS] = GridX[t] + 1; + } + break; + } else if (GridY[t] < -MAX_GRID_Y_POS) + { + GridY[t] = -MAX_GRID_Y_POS; + GridX[t] -= 2; + // also move fireball to position near this branch + if (changes_since_current_branch && current_branch == t) + { + GridY[TOTAL_BOOKMARKS] = GridY[t]; + GridX[TOTAL_BOOKMARKS] = GridX[t] + 1; + } + break; + } + } + } // 3. Set pixel positions of branches int max_x = 0; diff --git a/src/drivers/win/taseditlib/bookmarks.h b/src/drivers/win/taseditlib/bookmarks.h index 8aa55dc0..b54d34e6 100644 --- a/src/drivers/win/taseditlib/bookmarks.h +++ b/src/drivers/win/taseditlib/bookmarks.h @@ -35,7 +35,7 @@ #define EMPTY_BRANCHES_X -6 #define EMPTY_BRANCHES_Y_BASE 8 #define EMPTY_BRANCHES_Y_FACTOR 14 -#define MAX_NUM_CHILDREN 9 +#define MAX_NUM_CHILDREN_ON_CANVAS_HEIGHT 9 #define MAX_CHAIN_LEN 10 #define MAX_GRID_Y_POS 8 // spritesheet diff --git a/src/drivers/win/taseditlib/screenshot_display.cpp b/src/drivers/win/taseditlib/screenshot_display.cpp index b115ddae..2480df5d 100644 --- a/src/drivers/win/taseditlib/screenshot_display.cpp +++ b/src/drivers/win/taseditlib/screenshot_display.cpp @@ -62,12 +62,12 @@ void SCREENSHOT_DISPLAY::init() } HDC win_hdc = GetWindowDC(tasedit_list.hwndList); scr_bmp = CreateDIBSection(win_hdc, scr_bmi, DIB_RGB_COLORS, (void**)&scr_ptr, 0, 0); - // calculate coordinates (relative to the listview top-left corner) + // calculate coordinates (relative to IDC_BOOKMARKS_BOX top-left corner) RECT temp_rect, parent_rect; GetWindowRect(hwndTasEdit, &parent_rect); - GetWindowRect(tasedit_list.hwndHeader, &temp_rect); - scr_bmp_x = temp_rect.left - parent_rect.left; - scr_bmp_y = temp_rect.bottom - parent_rect.top; + GetWindowRect(GetDlgItem(hwndTasEdit, IDC_BOOKMARKS_BOX), &temp_rect); + scr_bmp_x = temp_rect.left - SCREENSHOT_WIDTH - SCR_BMP_DX - parent_rect.left; + scr_bmp_y = ((temp_rect.bottom + temp_rect.top - SCREENSHOT_HEIGHT) / 2) - parent_rect.top; } void SCREENSHOT_DISPLAY::free() { diff --git a/src/drivers/win/taseditlib/screenshot_display.h b/src/drivers/win/taseditlib/screenshot_display.h index 8a61b59f..0a2521e3 100644 --- a/src/drivers/win/taseditlib/screenshot_display.h +++ b/src/drivers/win/taseditlib/screenshot_display.h @@ -1,7 +1,8 @@ //Specification file for SCREENSHOT_DISPLAY class -#define SCR_BMP_PHASE_MAX 13 +#define SCR_BMP_PHASE_MAX 12 #define SCR_BMP_PHASE_ALPHA_MAX 10 +#define SCR_BMP_DX 7 #define DISPLAY_UPDATE_TICK 40 // update at 25FPS diff --git a/src/drivers/win/taseditlib/tasedit_list.cpp b/src/drivers/win/taseditlib/tasedit_list.cpp index c633cfc5..9c0777c7 100644 --- a/src/drivers/win/taseditlib/tasedit_list.cpp +++ b/src/drivers/win/taseditlib/tasedit_list.cpp @@ -26,7 +26,9 @@ 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 }; +COLORREF hot_changes_colors[16] = { 0x0, 0x5c4c44, 0x854604, 0xab2500, 0xc20006, 0xd6006f, 0xd40091, 0xba00a4, 0x9500ba, 0x7a00cc, 0x5800d4, 0x0045e2, 0x0063ea, 0x0079f4, 0x0092fa, 0x00aaff }; +//COLORREF hot_changes_colors[16] = { 0x0, 0x661212, 0x842B4E, 0x652C73, 0x48247D, 0x383596, 0x2947AE, 0x1E53C1, 0x135DD2, 0x116EDA, 0x107EE3, 0x0F8EEB, 0x209FF4, 0x3DB1FD, 0x51C2FF, 0x4DCDFF }; + char list_save_id[LIST_ID_LEN] = "LIST"; TASEDIT_LIST::TASEDIT_LIST() @@ -52,7 +54,6 @@ 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 diff --git a/src/drivers/win/taseditlib/tasedit_sel.cpp b/src/drivers/win/taseditlib/tasedit_sel.cpp index 4c04e038..73b0db1b 100644 --- a/src/drivers/win/taseditlib/tasedit_sel.cpp +++ b/src/drivers/win/taseditlib/tasedit_sel.cpp @@ -43,6 +43,9 @@ void TASEDIT_SELECTION::init(int new_size) AddNewSelectionToHistory(); track_selection_changes = true; reset(); + + if (clipboard_selection.empty()) + CheckClipboard(); RedrawTextClipboard(); } void TASEDIT_SELECTION::free() @@ -51,7 +54,6 @@ void TASEDIT_SELECTION::free() selections_history.resize(0); history_total_items = 0; temp_selection.clear(); - clipboard_selection.clear(); } void TASEDIT_SELECTION::reset() { @@ -414,6 +416,48 @@ void TASEDIT_SELECTION::ReselectClipboard() // also keep selection within list update(); } +// retrieves some information from clipboard to clipboard_selection +void TASEDIT_SELECTION::CheckClipboard() +{ + if (OpenClipboard(hwndTasEdit)) + { + // check if clipboard contains TAS Editor input data + HANDLE hGlobal = GetClipboardData(CF_TEXT); + if (hGlobal) + { + clipboard_selection.clear(); + int current_pos = -1; + char *pGlobal = (char*)GlobalLock((HGLOBAL)hGlobal); + // TAS recording info starts with "TAS " + if (pGlobal[0]=='T' && pGlobal[1]=='A' && pGlobal[2]=='S') + { + // Extract number of frames + int range; + sscanf (pGlobal+3, "%d", &range); + pGlobal = strchr(pGlobal, '\n'); + + while (pGlobal++ && *pGlobal!='\0') + { + // Detect skipped frames in paste + char *frame = pGlobal; + if (frame[0]=='+') + { + current_pos += atoi(frame+1); + while (*frame && *frame != '\n' && *frame != '|') + ++frame; + if (*frame=='|') ++frame; + } else + current_pos++; + clipboard_selection.insert(current_pos); + // skip input + pGlobal = strchr(pGlobal, '\n'); + } + } + GlobalUnlock(hGlobal); + } + CloseClipboard(); + } +} // ---------------------------------------------------------- void TASEDIT_SELECTION::ClearSelection() { diff --git a/src/drivers/win/taseditlib/tasedit_sel.h b/src/drivers/win/taseditlib/tasedit_sel.h index bf37606f..0e271dbb 100644 --- a/src/drivers/win/taseditlib/tasedit_sel.h +++ b/src/drivers/win/taseditlib/tasedit_sel.h @@ -56,6 +56,7 @@ public: private: SelectionFrames& CurrentSelection(); + void CheckClipboard(); bool track_selection_changes; bool must_redraw_text;