diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index 6c9b1f47..54beee84 100644 --- a/src/drivers/win/res.rc +++ b/src/drivers/win/res.rc @@ -232,7 +232,7 @@ BEGIN END POPUP "&Edit" BEGIN - MENUITEM "&Select All", ID_EDIT_SELECTALL + MENUITEM "Select &All", ID_EDIT_SELECTALL MENUITEM "Select mid &Markers\tCtrl+A", ID_EDIT_SELECTMIDMARKERS MENUITEM SEPARATOR MENUITEM "Cu&t\tCtrl+X", ID_TASEDIT_CUT @@ -241,8 +241,9 @@ BEGIN MENUITEM SEPARATOR MENUITEM "C&lear\tDelete", ID_EDIT_CLEAR MENUITEM "&Delete\tCtrl+Del", ID_TASEDIT_DELETE - MENUITEM "&Insert Frames\tCtrl+Ins", ID_EDIT_INSERTFRAMES + MENUITEM "&Insert\tCtrl+Ins", ID_EDIT_INSERTFRAMES MENUITEM "Insert # of Frames\tInsert", ID_EDIT_INSERT + MENUITEM "Cl&one\tShift+Ins", ID_EDIT_CLONEFRAMES MENUITEM SEPARATOR MENUITEM "T&runcate movie\tCtrl+T", ID_EDIT_TRUNCATE END @@ -346,10 +347,11 @@ BEGIN BEGIN MENUITEM "Select mid &Markers", ID_SELECTED_SELECTMIDMARKERS MENUITEM SEPARATOR - MENUITEM "&Insert Frame(s)", ID_CONTEXT_SELECTED_INSERTFRAMES + MENUITEM "C&lear", ID_CONTEXT_SELECTED_CLEARFRAMES + MENUITEM "&Delete", ID_CONTEXT_SELECTED_DELETEFRAMES + MENUITEM "&Insert", ID_CONTEXT_SELECTED_INSERTFRAMES MENUITEM "Insert # of Frames", ID_CONTEXT_SELECTED_INSERTFRAMES2 - MENUITEM "&Delete Frame(s)", ID_CONTEXT_SELECTED_DELETEFRAMES - MENUITEM "C&lear Frame(s)", ID_CONTEXT_SELECTED_CLEARFRAMES + MENUITEM "Cl&one", ID_SELECTED_CLONE MENUITEM SEPARATOR MENUITEM "T&runcate movie", ID_CONTEXT_SELECTED_TRUNCATE END @@ -1340,38 +1342,38 @@ BEGIN EDITTEXT IDC_LABEL_NEWPPUUSED,76,166,155,12,ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP END -TASEDIT DIALOGEX 0, 0, 445, 381 +TASEDIT DIALOGEX 0, 0, 433, 381 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "TAS Editor" MENU TASEDITMENU FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSORTHEADER | WS_BORDER,7,5,310,370 - GROUPBOX "Playback control",IDC_STATIC,322,5,118,62,BS_CENTER,WS_EX_RIGHT - PUSHBUTTON "<<",TASEDIT_REWIND_FULL,326,14,22,14,NOT WS_TABSTOP - PUSHBUTTON "<",TASEDIT_REWIND,348,14,22,14,NOT WS_TABSTOP - PUSHBUTTON "||",TASEDIT_PLAYSTOP,370,14,22,14,NOT WS_TABSTOP - PUSHBUTTON ">",TASEDIT_FORWARD,392,14,22,14,NOT WS_TABSTOP - PUSHBUTTON ">>",TASEDIT_FORWARD_FULL,414,14,22,14,NOT WS_TABSTOP - CONTROL "",IDC_PROGRESS_BUTTON,"Button",BS_OWNERDRAW | WS_TABSTOP,326,42,110,10 - CONTROL "",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,326,44,110,6 - CONTROL " Follow cursor",CHECK_FOLLOW_CURSOR,"Button",BS_AUTOCHECKBOX,327,30,105,12 + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSORTHEADER | WS_BORDER,6,5,298,370 + GROUPBOX "Playback control",IDC_STATIC,310,5,118,62,BS_CENTER,WS_EX_RIGHT + PUSHBUTTON "<<",TASEDIT_REWIND_FULL,314,14,22,14,NOT WS_TABSTOP + PUSHBUTTON "<",TASEDIT_REWIND,336,14,22,14,NOT WS_TABSTOP + PUSHBUTTON "||",TASEDIT_PLAYSTOP,358,14,22,14,NOT WS_TABSTOP + PUSHBUTTON ">",TASEDIT_FORWARD,380,14,22,14,NOT WS_TABSTOP + PUSHBUTTON ">>",TASEDIT_FORWARD_FULL,402,14,22,14,NOT WS_TABSTOP + CONTROL "",IDC_PROGRESS_BUTTON,"Button",BS_OWNERDRAW | WS_TABSTOP,314,42,110,10 + CONTROL "",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,314,44,110,6 + CONTROL " Follow cursor",CHECK_FOLLOW_CURSOR,"Button",BS_AUTOCHECKBOX,315,30,105,12 CONTROL " Auto-restore last position",CHECK_AUTORESTORE_PLAYBACK, - "Button",BS_AUTOCHECKBOX,327,53,105,12 - GROUPBOX "Recording input",IDC_STATIC,322,68,118,48,BS_CENTER,WS_EX_RIGHT - GROUPBOX "Editing",IDC_STATIC,322,118,118,29,BS_CENTER,WS_EX_RIGHT - GROUPBOX "Bookmarks",IDC_STATIC,322,148,118,103,BS_CENTER,WS_EX_RIGHT - CONTROL "",IDC_LIST3,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,327,159,108,88 - GROUPBOX "Project Input Logs",IDC_STATIC,322,252,118,123,BS_CENTER,WS_EX_RIGHT - CONTROL "",IDC_LIST2,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,327,263,108,108,WS_EX_LEFTSCROLLBAR - CONTROL " OFF",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,328,78,29,10 - CONTROL " ON",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,328,91,29,10 - CONTROL " 1P",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,380,78,25,10 - CONTROL " 2P",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,409,78,23,10 - CONTROL " 3P",IDC_RADIO5,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,380,91,25,10 - CONTROL " 4P",IDC_RADIO6,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,409,91,23,10 - CONTROL " Superimpose",IDC_SUPERIMPOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,328,104,55,10 - CONTROL " Omit blank",IDC_OMITBLANK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,387,104,49,10 + "Button",BS_AUTOCHECKBOX,315,53,105,12 + GROUPBOX "Recording input",IDC_STATIC,310,68,118,48,BS_CENTER,WS_EX_RIGHT + GROUPBOX "Editing",IDC_STATIC,310,118,118,29,BS_CENTER,WS_EX_RIGHT + GROUPBOX "Bookmarks",IDC_STATIC,310,148,118,103,BS_CENTER,WS_EX_RIGHT + CONTROL "",IDC_LIST3,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,315,159,108,88 + GROUPBOX "Project Input Logs",IDC_STATIC,310,252,118,123,BS_CENTER,WS_EX_RIGHT + CONTROL "",IDC_LIST2,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,315,263,108,108,WS_EX_LEFTSCROLLBAR + CONTROL " OFF",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,316,78,29,10 + CONTROL " ON",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,316,91,29,10 + CONTROL " 1P",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,368,78,25,10 + CONTROL " 2P",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,397,78,23,10 + CONTROL " 3P",IDC_RADIO5,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,368,91,25,10 + CONTROL " 4P",IDC_RADIO6,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,397,91,23,10 + CONTROL " Superimpose",IDC_SUPERIMPOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,316,104,55,10 + CONTROL " Omit blank",IDC_OMITBLANK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,375,104,49,10 END ASSEMBLER DIALOGEX 0, 0, 202, 135 @@ -2014,6 +2016,7 @@ END IDR_ACCELERATOR1 ACCELERATORS BEGIN + "A", ACCEL_CTRL_A, VIRTKEY, CONTROL, NOINVERT "C", ACCEL_CTRL_C, VIRTKEY, CONTROL, NOINVERT VK_DELETE, ACCEL_CTRL_DELETE, VIRTKEY, CONTROL, NOINVERT "F", ACCEL_CTRL_F, VIRTKEY, CONTROL, NOINVERT @@ -2025,7 +2028,7 @@ BEGIN "X", ACCEL_CTRL_X, VIRTKEY, CONTROL, NOINVERT VK_DELETE, ACCEL_DEL, VIRTKEY, NOINVERT VK_INSERT, ACCEL_INS, VIRTKEY, NOINVERT - "A", ACCEL_CTRL_A, VIRTKEY, CONTROL, NOINVERT + VK_INSERT, ACCEL_SHIFT_INS, VIRTKEY, SHIFT, NOINVERT END IDR_RWACCELERATOR ACCELERATORS diff --git a/src/drivers/win/resource.h b/src/drivers/win/resource.h index 7ef27d30..4f468474 100644 --- a/src/drivers/win/resource.h +++ b/src/drivers/win/resource.h @@ -847,6 +847,10 @@ #define ACCEL_CTRL_A 40455 #define ID_EDIT_SELECTMIDMARKERS 40457 #define ID_SELECTED_SELECTMIDMARKERS 40458 +#define ID_EDIT_CLONEFRAME 40459 +#define ID_EDIT_CLONEFRAMES 40460 +#define ACCEL_SHIFT_INS 40461 +#define ID_SELECTED_CLONE 40463 #define IDC_DEBUGGER_ICONTRAY 55535 #define MW_ValueLabel2 65423 #define MW_ValueLabel1 65426 @@ -856,7 +860,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 160 -#define _APS_NEXT_COMMAND_VALUE 40459 +#define _APS_NEXT_COMMAND_VALUE 40464 #define _APS_NEXT_CONTROL_VALUE 1263 #define _APS_NEXT_SYMED_VALUE 101 #endif diff --git a/src/drivers/win/tasedit.cpp b/src/drivers/win/tasedit.cpp index dd59a3af..9d159ebc 100644 --- a/src/drivers/win/tasedit.cpp +++ b/src/drivers/win/tasedit.cpp @@ -35,6 +35,7 @@ bool old_forward_button_state, forward_button_state; int button_hold_time; int seeking_start_frame = 0; bool TASEdit_focus = false; +int listItems; // number of items in list // saved FCEU config int saved_eoptions; int saved_EnableAutosave; @@ -91,8 +92,10 @@ static void GetDispInfo(NMLVDISPINFO* nmlvDispInfo) break; case COLUMN_FRAMENUM: case COLUMN_FRAMENUM2: - U32ToDecStr(item.pszText,item.iItem); - break; + { + 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: @@ -586,7 +589,8 @@ void SingleClick(LPNMITEMACTIVATE info) else currMovieData.frames_flags[row_index] |= MARKER_FLAG_BIT; MarkersChanged(); - RedrawList(); // just to flicker-indicate that something has changed + ListView_SetItemState(hwndList,row_index,0,LVIS_SELECTED); + //RedrawList(); } } else if(column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R) @@ -613,8 +617,34 @@ void DoubleClick(LPNMITEMACTIVATE info) } } -//insert frames at the currently selected positions. -static void InsertFrames() +void CloneFrames() +{ + int frames = selectionFrames.size(); + + currMovieData.records.reserve(currMovieData.records.size()+frames); + currMovieData.frames_flags.reserve(currMovieData.frames_flags.size()+frames); + + //insert frames before each selection, but consecutive selection lines are accounted as single region + frames = 1; + TSelectionFrames::reverse_iterator next_it; + for(TSelectionFrames::reverse_iterator it(selectionFrames.rbegin()); it != selectionFrames.rend(); it++) + { + next_it = it; + next_it++; + if (next_it == selectionFrames.rend() || (int)*next_it < ((int)*it - 1)) + { + // end of current region + currMovieData.cloneRegion(*it,frames); + frames = 1; + } else frames++; + } + + UpdateList(); + InputChanged(); + InvalidateGreenZone(*selectionFrames.begin()); +} + +void InsertFrames() { int frames = selectionFrames.size(); @@ -644,7 +674,7 @@ static void InsertFrames() InvalidateGreenZone(*selectionFrames.begin()); } -static void DeleteFrames() +void DeleteFrames() { //delete frames on each selection, going backwards for(TSelectionFrames::reverse_iterator it(selectionFrames.rbegin()); it != selectionFrames.rend(); it++) @@ -671,7 +701,6 @@ static void DeleteFrames() if (!selectionFrames.size()) break; } // reduce greenzone - if (index>0) index--; InvalidateGreenZone(index); } @@ -716,7 +745,8 @@ static void ColumnSet(int column) currMovieData.frames_flags[*it] &= ~MARKER_FLAG_BIT; } MarkersChanged(); - RedrawList(); // just to flicker-indicate that something has changed + ClearSelection(); + RedrawList(); } else { // buttons column @@ -743,20 +773,16 @@ static void ColumnSet(int column) void ClearSelection() { - ListView_SetItemState(hwndList,-1,0, LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(hwndList,-1,0, LVIS_SELECTED); } void ClearRowSelection(int index) { - ListView_SetItemState(hwndList,index,0, LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(hwndList,index,0, LVIS_SELECTED); } void SelectAll() { - ListView_SetItemState(hwndList,-1,LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED); - for(int i = 0; i < currMovieData.records.size(); i++) - { - selectionFrames.insert(i); - } + ListView_SetItemState(hwndList,-1,LVIS_SELECTED, LVIS_SELECTED); RedrawList(); } void SelectMidMarkers() @@ -771,7 +797,6 @@ void SelectMidMarkers() upper_border = center = *selectionFrames.begin(); lower_border = *selectionFrames.rbegin(); } else lower_border = upper_border = center = currFrameCounter; - ClearSelection(); // find markers // searching up starting from center-0 @@ -786,13 +811,15 @@ void SelectMidMarkers() SelectAll(); return; } + + ClearSelection(); // selecting circle: if (upper_border > upper_marker+1 || lower_border < lower_marker-1 || lower_border > lower_marker) { // default: select all between markers for (int i = upper_marker+1; i < lower_marker; ++i) { - ListView_SetItemState(hwndList,i,LVIS_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(hwndList,i,LVIS_SELECTED,LVIS_SELECTED); } } else if (upper_border == upper_marker+1 && lower_border == lower_marker-1) { @@ -801,32 +828,32 @@ void 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_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(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 - ListView_SetItemState(hwndList,lower_marker,0,LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(hwndList,lower_marker,0,LVIS_SELECTED); for (int i = upper_marker; i < lower_marker; ++i) { - ListView_SetItemState(hwndList,i,LVIS_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(hwndList,i,LVIS_SELECTED,LVIS_SELECTED); } } else if (upper_border == upper_marker && lower_border == lower_marker-1) { // selected all between markers and upper marker selected too - now deselect upper marker and (if lower marker < movie_size) reselect lower marker - ListView_SetItemState(hwndList,upper_marker,0,LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(hwndList,upper_marker,0,LVIS_SELECTED); 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_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(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") - ListView_SetItemState(hwndList,lower_marker,0,LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(hwndList,lower_marker,0,LVIS_SELECTED); for (int i = upper_marker + 1; i < lower_marker; ++i) { - ListView_SetItemState(hwndList,i,LVIS_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED); + ListView_SetItemState(hwndList,i,LVIS_SELECTED,LVIS_SELECTED); } } } @@ -1030,6 +1057,8 @@ static LRESULT APIENTRY ListWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lPar { case WM_CHAR: return 0; + case WM_KILLFOCUS: + return 0; case WM_NOTIFY: { switch (((LPNMHDR)lParam)->code) @@ -1080,7 +1109,7 @@ static void InitDialog() // frame number column lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT; lvc.fmt = LVCFMT_CENTER; - lvc.cx = 92; + lvc.cx = 75; lvc.pszText = "Frame#"; ListView_InsertColumn(hwndList, colidx++, &lvc); // pads columns @@ -1118,7 +1147,7 @@ void AddFourscore() } } // frame number column again - lvc.cx = 92; + lvc.cx = 75; lvc.pszText = "Frame#"; ListView_InsertColumn(hwndList, colidx++, &lvc); // enable radiobuttons for 3P/4P multitracking @@ -1405,10 +1434,16 @@ static void ItemChanged(NMLISTVIEW* info) { if(OFF) { + // clear all selectionFrames.clear(); + } else if (ON) + { + // select all + for(int i = 0; i < currMovieData.records.size(); i++) + { + selectionFrames.insert(i); + } } - else - FCEUD_PrintError("Unexpected condition in TasEdit ItemChanged. Please report."); } else { @@ -1433,6 +1468,9 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar 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); + FCEU_printf("listItems = %d\n\n",listItems); + hwndProgressbar = GetDlgItem(hwndDlg, IDC_PROGRESS1); SendMessage(hwndProgressbar, PBM_SETRANGE, 0, MAKELPARAM(0, PROGRESSBAR_WIDTH)); hwndRewind = GetDlgItem(hwndDlg, TASEDIT_REWIND); @@ -1488,6 +1526,16 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar case LVN_ODSTATECHANGED: ItemRangeChanged((LPNMLVODSTATECHANGE) lParam); break; + /* + case LVN_ENDSCROLL: + // redraw upper and lower list rows (fix for known WinXP bug) + int start = ListView_GetTopIndex(hwndList); + ListView_RedrawItems(hwndList,start,start); + int end = start + listItems - 1; + ListView_RedrawItems(hwndList,end,end); + break; + */ + } break; case TASEDIT_PLAYSTOP: @@ -1720,6 +1768,11 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar case ID_SELECTED_SELECTMIDMARKERS: SelectMidMarkers(); break; + case ACCEL_SHIFT_INS: + case ID_EDIT_CLONEFRAMES: + case ID_SELECTED_CLONE: + if (selectionFrames.size()) CloneFrames(); + break; } break; diff --git a/src/drivers/win/tasedit.h b/src/drivers/win/tasedit.h index 3f0d72d6..973078ab 100644 --- a/src/drivers/win/tasedit.h +++ b/src/drivers/win/tasedit.h @@ -51,7 +51,7 @@ #define COLUMN_JOYPAD4_L 32 #define COLUMN_JOYPAD4_R 33 #define COLUMN_FRAMENUM2 34 - +#define DIGITS_IN_FRAMENUM 7 // listview colors #define NORMAL_FRAMENUM_COLOR 0xFFFFFF #define MARKED_FRAMENUM_COLOR 0xC0FCFF @@ -105,4 +105,6 @@ bool SaveProjectAs(); bool AskSaveProject(); void SelectAll(); void SelectMidMarkers(); - +void CloneFrames(); +void InsertFrames(); +void DeleteFrames(); diff --git a/src/movie.cpp b/src/movie.cpp index 912496a4..65027f70 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -140,6 +140,20 @@ void MovieData::insertEmpty(int at, int frames) } } +void MovieData::cloneRegion(int at, int frames) +{ + if(at == -1) return; + + records.insert(records.begin()+at,frames,MovieRecord()); +#ifdef WIN32 + if (TASEdit_bind_markers) +#endif + frames_flags.insert(frames_flags.begin()+at,frames,0); + + for(int i = 0; i < frames; i++) + records[i+at].Clone(records[i+at+frames]); +} + void MovieData::TryDumpIncremental() { if(movieMode == MOVIEMODE_TASEDIT) @@ -225,9 +239,6 @@ bool MovieRecord::Compare(MovieRecord& compareRec) if (this->joysticks != compareRec.joysticks) return false; - - //if (this->commands != compareRec.commands) - // return false; //if new commands are ever recordable, they need to be added here if we go with this method if(this->command_reset() != compareRec.command_reset()) return false; @@ -247,9 +258,29 @@ bool MovieRecord::Compare(MovieRecord& compareRec) if (this->zappers[1].b != compareRec.zappers[1].b) return false; if (this->zappers[1].bogo != compareRec.zappers[1].bogo) return false; - return true; } +void MovieRecord::Clone(MovieRecord& sourceRec) +{ + this->joysticks[0] = sourceRec.joysticks[0]; + this->joysticks[1] = sourceRec.joysticks[1]; + this->joysticks[2] = sourceRec.joysticks[2]; + this->joysticks[3] = sourceRec.joysticks[3]; + + this->zappers[0].x = sourceRec.zappers[0].x; + this->zappers[0].y = sourceRec.zappers[0].y; + this->zappers[0].zaphit = sourceRec.zappers[0].zaphit; + this->zappers[0].b = sourceRec.zappers[0].b; + this->zappers[0].bogo = sourceRec.zappers[0].bogo; + + this->zappers[1].x = sourceRec.zappers[1].x; + this->zappers[1].y = sourceRec.zappers[1].y; + this->zappers[1].zaphit = sourceRec.zappers[1].zaphit; + this->zappers[1].b = sourceRec.zappers[1].b; + this->zappers[1].bogo = sourceRec.zappers[1].bogo; + + this->commands = sourceRec.commands; +} const char MovieRecord::mnemonics[8] = {'A','B','S','T','U','D','L','R'}; void MovieRecord::dumpJoy(EMUFILE* os, uint8 joystate) diff --git a/src/movie.h b/src/movie.h index ab518abb..076750cc 100644 --- a/src/movie.h +++ b/src/movie.h @@ -147,6 +147,7 @@ public: } bool Compare(MovieRecord& compareRec); + void Clone(MovieRecord& sourceRec); void clear(); void parse(MovieData* md, EMUFILE* is); @@ -240,6 +241,7 @@ public: void clearRecordRange(int start, int len); void insertEmpty(int at, int frames); + void cloneRegion(int at, int frames); static bool loadSavestateFrom(std::vector* buf); static void dumpSavestateTo(std::vector* buf, int compressionLevel); diff --git a/src/utils/xstring.cpp b/src/utils/xstring.cpp index 7af0c846..a65a7d5a 100644 --- a/src/utils/xstring.cpp +++ b/src/utils/xstring.cpp @@ -526,6 +526,21 @@ char *U32ToDecStr(uint32 a) { return U32ToDecStr(TempArray,a); } +char *U32ToDecStr(char* buf, uint32 a, int digits) +{ + if (digits < 1) + digits = 1; + else if (digits > 10) + digits = 10; + + for (int i = 1; i <= digits; ++i) + { + buf[digits - i] = '0' + (a % 10); + a /= 10; + } + buf[digits] = 0; + return buf; +} char *U16ToHexStr(uint16 a) { diff --git a/src/utils/xstring.h b/src/utils/xstring.h index a841ba74..627cfa33 100644 --- a/src/utils/xstring.h +++ b/src/utils/xstring.h @@ -57,6 +57,7 @@ uint16 FastStrToU16(char* s, bool& valid); char *U16ToDecStr(uint16 a); char *U32ToDecStr(uint32 a); char *U32ToDecStr(char* buf, uint32 a); +char *U32ToDecStr(char* buf, uint32 a, int digits); char *U8ToDecStr(uint8 a); char *U8ToHexStr(uint8 a); char *U16ToHexStr(uint16 a);