From 16a625561c3c6e51350bf325721f9b556dd22f87 Mon Sep 17 00:00:00 2001 From: ansstuff Date: Fri, 25 Nov 2011 19:26:26 +0000 Subject: [PATCH] * Tasedit: refactoring * Tasedit: selection << and >> * Tasedit: Turbo Seek checkbox * Tasedit: PasteInsert (Shift-V) * Tasedit: Config->Superimpose affects copy/paste * Tasedit: list save/load (currently only restoring vscroll position) * Tasedit: Editing info texts --- src/drivers/win/config.cpp | 4 + src/drivers/win/res.rc | 37 +-- src/drivers/win/resource.h | 17 +- src/drivers/win/tasedit.cpp | 232 ++++++++++++++---- src/drivers/win/tasedit.h | 13 +- src/drivers/win/taseditlib/bookmarks.cpp | 204 +++------------ src/drivers/win/taseditlib/bookmarks.h | 25 +- src/drivers/win/taseditlib/greenzone.cpp | 17 +- src/drivers/win/taseditlib/inputhistory.cpp | 6 +- src/drivers/win/taseditlib/inputsnapshot.cpp | 86 +++++-- src/drivers/win/taseditlib/inputsnapshot.h | 3 +- src/drivers/win/taseditlib/markers.cpp | 62 ++++- src/drivers/win/taseditlib/markers.h | 13 +- src/drivers/win/taseditlib/playback.cpp | 78 +++--- src/drivers/win/taseditlib/playback.h | 6 +- src/drivers/win/taseditlib/recorder.cpp | 4 +- src/drivers/win/taseditlib/recorder.h | 2 +- .../win/taseditlib/screenshot_display.cpp | 195 +++++++++++++++ .../win/taseditlib/screenshot_display.h | 37 +++ src/drivers/win/taseditlib/tasedit_list.cpp | 51 +++- src/drivers/win/taseditlib/tasedit_list.h | 5 + src/drivers/win/taseditlib/tasedit_sel.cpp | 173 ++++++++++++- src/drivers/win/taseditlib/tasedit_sel.h | 19 ++ src/drivers/win/taseditlib/taseditproj.cpp | 18 +- src/drivers/win/taseditlib/taseditproj.h | 1 + src/movie.cpp | 9 +- vc/vc10_fceux.vcxproj | 2 + vc/vc10_fceux.vcxproj.filters | 2 + 28 files changed, 953 insertions(+), 368 deletions(-) create mode 100644 src/drivers/win/taseditlib/screenshot_display.cpp create mode 100644 src/drivers/win/taseditlib/screenshot_display.h diff --git a/src/drivers/win/config.cpp b/src/drivers/win/config.cpp index e223a3d2..ab39af05 100644 --- a/src/drivers/win/config.cpp +++ b/src/drivers/win/config.cpp @@ -69,12 +69,14 @@ extern bool oldInputDisplay; extern bool fullSaveStateLoads; extern int frameSkipAmt; extern bool TASEdit_follow_playback; +extern bool TASEdit_turbo_seek; extern bool TASEdit_show_lag_frames; extern bool TASEdit_show_markers; extern bool TASEdit_show_branch_screenshots; extern bool TASEdit_bind_markers; extern bool TASEdit_use_1p_rec; extern bool TASEdit_combine_consecutive_rec; +extern bool TASEdit_superimpose_affects_paste; extern bool TASEdit_branch_full_movie; extern bool TASEdit_branch_only_when_rec; extern bool TASEdit_view_branches_tree; @@ -304,12 +306,14 @@ static CFGSTRUCT fceuconfig[] = { AC(AutoFireOffset), AC(DesynchAutoFire), AC(TASEdit_follow_playback), + AC(TASEdit_turbo_seek), AC(TASEdit_show_lag_frames), AC(TASEdit_show_markers), AC(TASEdit_show_branch_screenshots), AC(TASEdit_bind_markers), AC(TASEdit_use_1p_rec), AC(TASEdit_combine_consecutive_rec), + AC(TASEdit_superimpose_affects_paste), AC(TASEdit_branch_full_movie), AC(TASEdit_branch_only_when_rec), AC(TASEdit_view_branches_tree), diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index 7281096d..7b811e8b 100644 --- a/src/drivers/win/res.rc +++ b/src/drivers/win/res.rc @@ -243,6 +243,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "&Copy\tCtrl+C", ID_TASEDIT_COPY MENUITEM "&Paste\tCtrl+V", ID_TASEDIT_PASTE + MENUITEM "PasteInsert\tShift+V", ID_EDIT_PASTEINSERT MENUITEM "Cu&t\tCtrl+X", ID_TASEDIT_CUT MENUITEM SEPARATOR MENUITEM "C&lear\tDel", ID_EDIT_CLEAR @@ -257,7 +258,7 @@ BEGIN BEGIN MENUITEM "Highlight &Lag Frames", ID_VIEW_SHOW_LAG_FRAMES MENUITEM "Show &Markers", ID_VIEW_SHOW_MARKERS - MENUITEM "Show Branch &Screenshots", ID_VIEW_SHOWBRANCHSCREENSHOTS + MENUITEM "Display Branch &Screenshots", ID_VIEW_SHOWBRANCHSCREENSHOTS MENUITEM "Enable Hot &Changes", ID_VIEW_ENABLEHOTCHANGES MENUITEM SEPARATOR MENUITEM "&Follow undo context", ID_VIEW_JUMPWHENMAKINGUNDO @@ -276,6 +277,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "&Use 1P keys for all single Recordings", ID_CONFIG_USE1PFORRECORDING MENUITEM "&Combine consecutive Recordings", ID_CONFIG_COMBINECONSECUTIVERECORDINGS + MENUITEM "&Superimpose affects copy/paste", ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE MENUITEM SEPARATOR MENUITEM "Mute &Turbo", ID_CONFIG_MUTETURBO END @@ -1376,17 +1378,17 @@ BEGIN PUSHBUTTON "||",TASEDIT_PLAYSTOP,360,10,23,14,NOT WS_TABSTOP PUSHBUTTON ">",TASEDIT_FORWARD,383,10,23,14,NOT WS_TABSTOP PUSHBUTTON ">>",TASEDIT_FORWARD_FULL,406,10,23,14,NOT WS_TABSTOP - CONTROL "",IDC_PROGRESS_BUTTON,"Button",BS_OWNERDRAW,314,38,116,10 - CONTROL "",IDC_BRANCHES_BUTTON,"Button",BS_OWNERDRAW,320,151,104,11 + CONTROL "",IDC_PROGRESS_BUTTON,"Button",BS_OWNERDRAW,314,37,116,12 + CONTROL "",IDC_BRANCHES_BUTTON,"Button",BS_OWNERDRAW,320,149,104,11 CONTROL "",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,314,40,115,6 - CONTROL " Follow cursor",CHECK_FOLLOW_CURSOR,"Button",BS_AUTOCHECKBOX,316,26,105,12 + CONTROL " Follow cursor",CHECK_FOLLOW_CURSOR,"Button",BS_AUTOCHECKBOX,316,26,56,12 CONTROL " Auto-restore last position",CHECK_AUTORESTORE_PLAYBACK, "Button",BS_AUTOCHECKBOX,316,49,105,12 GROUPBOX " Recording ",IDC_STATIC,310,64,123,48,BS_CENTER,WS_EX_RIGHT - GROUPBOX " Editing ",IDC_STATIC,310,113,123,37,BS_CENTER,WS_EX_RIGHT - GROUPBOX " Bookmarks ",IDC_BOOKMARKS_BOX,310,152,123,103,BS_CENTER,WS_EX_RIGHT - CONTROL "",IDC_BOOKMARKSLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | NOT WS_VISIBLE | WS_BORDER,315,162,113,89 - CONTROL "",IDC_HISTORYLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOLABELWRAP | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,315,267,113,100 + GROUPBOX " Editing ",IDC_STATIC,310,113,123,35,BS_CENTER,WS_EX_RIGHT + GROUPBOX " Bookmarks ",IDC_BOOKMARKS_BOX,310,150,123,103,BS_CENTER,WS_EX_RIGHT + CONTROL "",IDC_BOOKMARKSLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | NOT WS_VISIBLE | WS_BORDER,315,160,113,89 + CONTROL "",IDC_HISTORYLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOLABELWRAP | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,315,265,113,102 CONTROL " OFF",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,316,74,27,10 CONTROL " ON",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,316,87,27,10 CONTROL " 1P",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,373,74,25,10 @@ -1394,16 +1396,20 @@ BEGIN CONTROL " 3P",IDC_RADIO5,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,373,87,25,10 CONTROL " 4P",IDC_RADIO6,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,402,87,23,10 CONTROL " Superimpose",IDC_SUPERIMPOSE,"Button",BS_AUTO3STATE,316,100,56,10 - GROUPBOX " History ",IDC_STATIC,310,257,123,114,BS_CENTER,WS_EX_RIGHT + GROUPBOX " History ",IDC_STATIC,310,255,123,116,BS_CENTER,WS_EX_RIGHT EDITTEXT IDC_EDIT1,54,377,251,13,ES_READONLY | NOT WS_TABSTOP - PUSHBUTTON "<<",TASEDIT_REWIND_FULL2,315,376,23,14,NOT WS_TABSTOP - PUSHBUTTON "Find",TASEDIT_REWIND_FULL3,338,376,34,14,WS_DISABLED | NOT WS_TABSTOP - PUSHBUTTON "Next",TASEDIT_REWIND_FULL4,372,376,34,14,WS_DISABLED | NOT WS_TABSTOP - PUSHBUTTON ">>",TASEDIT_REWIND_FULL5,405,376,23,14,NOT WS_TABSTOP + PUSHBUTTON "<<",TASEDIT_PREV_MARKER,315,376,23,14,NOT WS_TABSTOP + PUSHBUTTON "Find",TASEDIT_FIND_BEST_MARKER,338,376,34,14,WS_DISABLED | NOT WS_TABSTOP + PUSHBUTTON "Next",TASEDIT_FIND_NEXT_MARKER,372,376,34,14,WS_DISABLED | NOT WS_TABSTOP + PUSHBUTTON ">>",TASEDIT_NEXT_MARKER,405,376,23,14,NOT WS_TABSTOP RTEXT "Marker 99999",IDC_STATIC,6,379,45,10,0,WS_EX_RIGHT RTEXT "Marker 0",IDC_STATIC,6,3,45,10,0,WS_EX_RIGHT EDITTEXT IDC_EDIT2,54,1,251,13,ES_READONLY | NOT WS_TABSTOP - CONTROL "",IDC_BRANCHES_BITMAP,"Static",SS_OWNERDRAW | SS_NOTIFY | SS_REALSIZEIMAGE | NOT WS_VISIBLE,315,162,113,89 + CONTROL "",IDC_BRANCHES_BITMAP,"Static",SS_OWNERDRAW | SS_NOTIFY | SS_REALSIZEIMAGE | NOT WS_VISIBLE,315,160,113,89 + CONTROL " Turbo seek",CHECK_TURBO_SEEK,"Button",BS_AUTOCHECKBOX,379,26,50,12 + CONTROL "",IDC_TEXT_SELECTION_BUTTON,"Button",BS_OWNERDRAW,315,121,113,12 + LTEXT "Selection: 0 rows, 16 columns",IDC_TEXT_SELECTION,316,123,114,10 + LTEXT "Clipboard: 0 rows, 16 columns",IDC_TEXT_CLIPBOARD,316,134,114,10 END ASSEMBLER DIALOGEX 0, 0, 202, 135 @@ -2000,6 +2006,7 @@ END IDR_ACCELERATOR1 ACCELERATORS BEGIN "A", ACCEL_CTRL_A, VIRTKEY, CONTROL, NOINVERT + "B", ACCEL_CTRL_B, 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 @@ -2016,7 +2023,7 @@ BEGIN VK_DELETE, ACCEL_DEL, VIRTKEY, NOINVERT VK_INSERT, ACCEL_INS, VIRTKEY, NOINVERT VK_INSERT, ACCEL_SHIFT_INS, VIRTKEY, SHIFT, NOINVERT - "B", ACCEL_CTRL_B, VIRTKEY, CONTROL, NOINVERT + "V", ACCEL_SHIFT_V, VIRTKEY, SHIFT, NOINVERT END IDR_RWACCELERATOR ACCELERATORS diff --git a/src/drivers/win/resource.h b/src/drivers/win/resource.h index 4f9cae0b..4ad20cec 100644 --- a/src/drivers/win/resource.h +++ b/src/drivers/win/resource.h @@ -415,15 +415,21 @@ #define IDC_BUTTON7 1145 #define MEMW_EDIT03FORMULA 1145 #define TASEDIT_REWIND_FULL2 1145 +#define TASEDIT_PREV_MARKER 1145 #define IDC_BUTTON8 1146 #define TASEDIT_REWIND_FULL3 1146 +#define TASEDIT_FIND_BEST_MARKER 1146 #define IDC_EDIT1 1147 #define IDC_BUTTON9 1148 #define TASEDIT_REWIND_FULL4 1148 +#define TASEDIT_FIND_NEXT_MARKER 1148 #define IDC_HISTORYLIST 1149 #define IDC_BOOKMARKSLIST 1150 #define TASEDIT_REWIND_FULL5 1151 +#define TASEDIT_NEXT_MARKER 1151 #define IDC_BRANCHES_BUTTON 1152 +#define IDC_BRANCHES_BUTTON2 1153 +#define IDC_TEXT_SELECTION_BUTTON 1153 #define IDC_EDIT2 1154 #define CHECK_SOUND_MUTETURBO 1179 #define IDC_EDIT_AUTHOR 1180 @@ -530,6 +536,9 @@ #define IDC_BOOKMARKS_BOX 1264 #define IDC_BRANCHES_BITMAP 1265 #define IDC_SCREENSHOT_BITMAP 1266 +#define CHECK_TURBO_SEEK 1266 +#define IDC_TEXT_SELECTION 1267 +#define IDC_TEXT_CLIPBOARD 1268 #define MENU_NETWORK 40040 #define MENU_PALETTE 40041 #define MENU_SOUND 40042 @@ -904,6 +913,10 @@ #define ID_CONFIG_USE1PFORRECORDING2P 40490 #define ID_CONFIG_USE1PFORRECORDING 40491 #define ID_CONFIG_COMBINECONSECUTIVERECORDINGS 40492 +#define ACCEL_SHIFT_V 40493 +#define ID_EDIT_PASTEINSERT 40495 +#define ID_CONFIG_SUPERIMPOSEAFFECTSCOPY 40496 +#define ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE 40497 #define IDC_DEBUGGER_ICONTRAY 55535 #define MW_ValueLabel2 65423 #define MW_ValueLabel1 65426 @@ -913,8 +926,8 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 185 -#define _APS_NEXT_COMMAND_VALUE 40493 -#define _APS_NEXT_CONTROL_VALUE 1267 +#define _APS_NEXT_COMMAND_VALUE 40498 +#define _APS_NEXT_CONTROL_VALUE 1269 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/drivers/win/tasedit.cpp b/src/drivers/win/tasedit.cpp index bbfc38e4..90dfe533 100644 --- a/src/drivers/win/tasedit.cpp +++ b/src/drivers/win/tasedit.cpp @@ -1,13 +1,9 @@ -#include // #include #include #include "taseditlib/taseditproj.h" -#include "fceu.h" // -#include "replay.h" #include "utils/xstring.h" #include "Win32InputBox.h" -#include "window.h" // #include "keyboard.h" #include "joystick.h" #include "help.h" @@ -30,6 +26,7 @@ RECORDER recorder; GREENZONE greenzone; MARKERS markers; BOOKMARKS bookmarks; +SCREENSHOT_DISPLAY screenshot_display; TASEDIT_LIST tasedit_list; TASEDIT_SELECTION selection; @@ -39,16 +36,19 @@ int saved_EnableAutosave; extern int EnableAutosave; extern EMOVIEMODE movieMode; // maybe we need normal setter for movieMode, to encapsulate it +extern void UpdateCheckedMenuItems(); // vars saved in cfg file (need dedicated storage class?) int TasEdit_wndx, TasEdit_wndy; bool TASEdit_follow_playback = true; +bool TASEdit_turbo_seek = true; bool TASEdit_show_lag_frames = true; bool TASEdit_show_markers = true; bool TASEdit_show_branch_screenshots = true; bool TASEdit_bind_markers = true; bool TASEdit_use_1p_rec = true; bool TASEdit_combine_consecutive_rec = true; +bool TASEdit_superimpose_affects_paste = true; int TASEdit_superimpose = BST_UNCHECKED; bool TASEdit_branch_full_movie = true; bool TASEdit_branch_only_when_rec = false; @@ -66,7 +66,7 @@ bool TASEdit_jump_to_undo = true; string tasedithelp = "{16CDE0C4-02B0-4A60-A88D-076319909A4D}"; //Name of TASEdit Help page char buttonNames[NUM_JOYPAD_BUTTONS][2] = {"A", "B", "S", "T", "U", "D", "L", "R"}; char windowCaption[] = "TAS Editor"; -extern char windowCaptions[5][30]; +extern char recordingCaptions[5][30]; // enterframe function void UpdateTasEdit() @@ -79,6 +79,7 @@ void UpdateTasEdit() playback.update(); recorder.update(); bookmarks.update(); + screenshot_display.update(); selection.update(); history.update(); project.update(); @@ -89,7 +90,7 @@ void RedrawWindowCaption() char windowCapt[300]; strcpy(windowCapt, windowCaption); if (!movie_readonly) - strcat(windowCapt, windowCaptions[recorder.multitrack_recording_joypad]); + strcat(windowCapt, recordingCaptions[recorder.multitrack_recording_joypad]); // add project name std::string projectname = project.GetProjectName(); if (!projectname.empty()) @@ -106,16 +107,6 @@ void RedrawTasedit() { InvalidateRect(hwndTasEdit, 0, FALSE); } -void RedrawListAndBookmarks() -{ - tasedit_list.RedrawList(); - bookmarks.RedrawBookmarksList(); -} -void RedrawRowAndBookmark(int index) -{ - tasedit_list.RedrawRow(index); - bookmarks.RedrawChangedBookmarks(index); -} void ShowMenu(ECONTEXTMENU which, POINT& pt) { @@ -197,7 +188,7 @@ void SingleClick(LPNMITEMACTIVATE info) { // reverse MARKER_FLAG_BIT in pointed frame markers.ToggleMarker(row_index); - if (markers.markers_array[row_index]) + if (markers.GetMarker(row_index)) history.RegisterChanges(MODTYPE_MARKER_SET, row_index); else history.RegisterChanges(MODTYPE_MARKER_UNSET, row_index); @@ -254,7 +245,7 @@ void CloneFrames() frames = 1; } else frames++; } - //tasedit_list.update(); + markers.update(); greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_CLONE, *current_selection->begin())); } @@ -284,7 +275,7 @@ void InsertFrames() frames = 1; } else frames++; } - //tasedit_list.update(); + markers.update(); greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_INSERT, *current_selection->begin())); } @@ -331,7 +322,7 @@ void DeleteFrames() { currMovieData.records.erase(currMovieData.records.begin() + *it); if (TASEdit_bind_markers) - markers.markers_array.erase(markers.markers_array.begin() + *it); + markers.EraseMarker(*it); } // check if user deleted all frames if (!currMovieData.getNumRecords()) @@ -408,7 +399,7 @@ void ColumnSet(int column) bool unset_found = false; for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) { - if(!(markers.markers_array[*it] & MARKER_FLAG_BIT)) + if(!markers.GetMarker(*it)) { unset_found = true; break; @@ -418,13 +409,13 @@ void ColumnSet(int column) { // set all for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) - markers.markers_array[*it] |= MARKER_FLAG_BIT; + markers.SetMarker(*it); history.RegisterChanges(MODTYPE_MARKER_SET, *current_selection_begin, *current_selection->rbegin()); } else { // unset all for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) - markers.markers_array[*it] &= ~MARKER_FLAG_BIT; + markers.ClearMarker(*it); history.RegisterChanges(MODTYPE_MARKER_UNSET, *current_selection_begin, *current_selection->rbegin()); } project.SetProjectChanged(); @@ -484,7 +475,7 @@ bool Copy(SelectionFrames* current_selection) cframe=*it; int cjoy=0; - for (int joy=0; joysize() == 0) return false; + + if (!OpenClipboard(hwndTasEdit)) return false; + + SelectionFrames::iterator current_selection_begin(current_selection->begin()); + bool result = false; + int pos = *current_selection_begin; + HANDLE hGlobal = GetClipboardData(CF_TEXT); + if (hGlobal) + { + char *pGlobal = (char*)GlobalLock((HGLOBAL)hGlobal); + + // 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 + markers.update(); + // init inserted_set (for input history hot changes) + selection.GetInsertedSet().clear(); + + // Extract number of frames + int range; + sscanf (pGlobal+3, "%d", &range); + + pGlobal = strchr(pGlobal, '\n'); int joy=0; --pos; @@ -578,31 +672,39 @@ bool Paste() if (frame[0]=='+') { pos += atoi(frame+1); - while (*frame && *frame != '\n' && *frame!='|') + if (currMovieData.getNumRecords() < pos) + { + currMovieData.insertEmpty(currMovieData.getNumRecords(), pos - currMovieData.getNumRecords()); + markers.update(); + } + while (*frame && *frame != '\n' && *frame != '|') ++frame; if (*frame=='|') ++frame; } else { ++pos; } + + // insert new frame + currMovieData.insertEmpty(pos, 1); + if (TASEdit_bind_markers) markers.insertEmpty(pos, 1); + selection.GetInsertedSet().insert(pos); - currMovieData.records[pos].joysticks[0]=0; - currMovieData.records[pos].joysticks[1]=0; - int joy=0; - + // read this frame input + int joy = 0; while (*frame && *frame != '\n' && *frame !='\r') { switch (*frame) { - case '|': // Joystick marker + case '|': // Joystick mark ++joy; break; default: - for (int bit=0; bitbmiHeader.biSize = sizeof(scr_bmi->bmiHeader); - scr_bmi->bmiHeader.biWidth = SCREENSHOT_WIDTH; - scr_bmi->bmiHeader.biHeight = -SCREENSHOT_HEIGHT; // negative value = top-down bmp - scr_bmi->bmiHeader.biPlanes = 1; - scr_bmi->bmiHeader.biBitCount = 8; - scr_bmi->bmiHeader.biCompression = BI_RGB; - scr_bmi->bmiHeader.biSizeImage = 0; - - // register ScrBmp window class - wincl.hInstance = fceu_hInstance; - wincl.lpszClassName = szClassName; - wincl.lpfnWndProc = ScrBmpWndProc; - wincl.style = CS_DBLCLKS; - wincl.cbSize = sizeof(WNDCLASSEX); - wincl.hIcon = 0; - wincl.hIconSm = 0; - wincl.hCursor = 0; - wincl.lpszMenuName = 0; - wincl.cbClsExtra = 0; - wincl.cbWndExtra = 0; - wincl.hbrBackground = 0; - if(!RegisterClassEx(&wincl)) - FCEU_printf("Error registering ScrBmp window class\n"); - // create blendfunction - blend.BlendOp = AC_SRC_OVER; - blend.BlendFlags = 0; - blend.AlphaFormat = 0; - blend.SourceConstantAlpha = 255; - - } void BOOKMARKS::init() @@ -185,28 +147,16 @@ void BOOKMARKS::init() // create pens normal_pen = CreatePen(PS_SOLID, 1, 0x0); select_pen = CreatePen(PS_SOLID, 2, 0xFF9080); - // prepare screenshot bitmap - // fill scr_bmp palette with current palette colors - extern PALETTEENTRY *color_palette; - for (int i = 0; i < 256; ++i) - { - scr_bmi->bmiColors[i].rgbRed = color_palette[i].peRed; - scr_bmi->bmiColors[i].rgbGreen = color_palette[i].peGreen; - scr_bmi->bmiColors[i].rgbBlue = color_palette[i].peBlue; - } - scr_bmp = CreateDIBSection(win_hdc, scr_bmi, DIB_RGB_COLORS, (void**)&scr_ptr, 0, 0); RedrawBookmarksCaption(); next_animation_time = 0; update(); - } void BOOKMARKS::reset() { transition_phase = animation_frame = 0; mouse_x = mouse_y = -1; - screenshot_currently_shown = item_under_mouse = ITEM_UNDER_MOUSE_NONE; - scr_bmp_phase = 0; + item_under_mouse = ITEM_UNDER_MOUSE_NONE; mouse_over_bitmap = false; must_recalculate_branches_tree = must_redraw_branches_tree = must_check_item_under_mouse = true; check_flash_shedule = clock() + BOOKMARKS_FLASH_TICK; @@ -257,13 +207,6 @@ void BOOKMARKS::free() DeleteObject(branchesSpritesheet); branchesSpritesheet = NULL; } - if (scr_bmp) - { - DeleteObject(scr_bmp); - scr_bmp = NULL; - } - - } void BOOKMARKS::update() @@ -286,7 +229,7 @@ void BOOKMARKS::update() if (must_recalculate_branches_tree) RecalculateBranchesTree(); - // once per 50 milliseconds update branches_bitmap and scr_bmp + // once per 50 milliseconds update branches_bitmap if (clock() > next_animation_time) { // animate branches_bitmap @@ -321,58 +264,6 @@ void BOOKMARKS::update() // render branches_bitmap if (edit_mode == EDIT_MODE_BRANCHES && must_redraw_branches_tree) RedrawBranchesTree(); - - // change screenshot_bitmap alpha if needed - if (item_under_mouse >= 0 && item_under_mouse < TOTAL_BOOKMARKS && TASEdit_show_branch_screenshots) - { - if (!hwndScrBmp) - { - // create window - hwndScrBmp = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT, szClassName, szClassName, WS_POPUP, TasEdit_wndx + scr_bmp_x, TasEdit_wndy + scr_bmp_y, SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT, hwndTasEdit, NULL, fceu_hInstance, NULL); - RedrawScreenshotBitmap(); - ShowWindow(hwndScrBmp, SW_SHOWNA); - } - // change screenshot_bitmap pic if needed - if (item_under_mouse != screenshot_currently_shown) - { - if (bookmarks_array[item_under_mouse].not_empty) - ChangeScreenshotBitmap(); - } - if (scr_bmp_phase < SCR_BMP_PHASE_MAX) - { - scr_bmp_phase++; - // update alpha - int phase_alpha = scr_bmp_phase; - if (phase_alpha > SCR_BMP_PHASE_ALPHA_MAX) phase_alpha = SCR_BMP_PHASE_ALPHA_MAX; - SetLayeredWindowAttributes(hwndScrBmp, 0, (255 * phase_alpha) / SCR_BMP_PHASE_ALPHA_MAX, LWA_ALPHA); - UpdateLayeredWindow(hwndScrBmp, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA); - } - } else - { - // fade and finally hide screenshot - if (scr_bmp_phase > 0) - scr_bmp_phase--; - if (scr_bmp_phase > 0) - { - if (hwndScrBmp) - { - // update alpha - int phase_alpha = scr_bmp_phase; - if (phase_alpha > SCR_BMP_PHASE_ALPHA_MAX) phase_alpha = SCR_BMP_PHASE_ALPHA_MAX; - SetLayeredWindowAttributes(hwndScrBmp, 0, (255 * phase_alpha) / SCR_BMP_PHASE_ALPHA_MAX, LWA_ALPHA); - UpdateLayeredWindow(hwndScrBmp, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA); - } - } else - { - // destroy screenshot bitmap window - scr_bmp_phase = 0; - if (hwndScrBmp) - { - DestroyWindow(hwndScrBmp); - hwndScrBmp = 0; - } - } - } } } @@ -390,8 +281,8 @@ void BOOKMARKS::set(int slot) bookmarks_array[slot].set(); // if this screenshot is shown on screen - reinit and redraw it - if (screenshot_currently_shown == slot) - screenshot_currently_shown = ITEM_UNDER_MOUSE_NONE; + if (screenshot_display.screenshot_currently_shown == slot) + screenshot_display.screenshot_currently_shown = ITEM_UNDER_MOUSE_NONE; // inherit current branch if (slot != current_branch) @@ -421,7 +312,10 @@ void BOOKMARKS::set(int slot) // switch current branch to this branch if (slot != current_branch && current_branch >= 0) - RedrawRowAndBookmark(bookmarks_array[current_branch].snapshot.jump_frame); + { + tasedit_list.RedrawRow(bookmarks_array[current_branch].snapshot.jump_frame); + RedrawChangedBookmarks(bookmarks_array[current_branch].snapshot.jump_frame); + } if (slot != current_branch || changes_since_current_branch) must_recalculate_branches_tree = true; current_branch = slot; @@ -429,8 +323,12 @@ void BOOKMARKS::set(int slot) project.SetProjectChanged(); if (previous_frame >= 0 && previous_frame != currFrameCounter) - RedrawRowAndBookmark(previous_frame); - RedrawRowAndBookmark(currFrameCounter); + { + tasedit_list.RedrawRow(previous_frame); + RedrawChangedBookmarks(previous_frame); + } + tasedit_list.RedrawRow(currFrameCounter); + RedrawChangedBookmarks(currFrameCounter); FCEU_DispMessage("Branch %d saved.", 0, slot); } @@ -470,7 +368,7 @@ void BOOKMARKS::unleash(int slot) { if (bookmarks_array[slot].snapshot.checkMarkersDiff()) { - bookmarks_array[slot].snapshot.toMarkers(); + bookmarks_array[slot].snapshot.copyToMarkers(); project.SetProjectChanged(); markers_changed = true; } @@ -496,7 +394,7 @@ void BOOKMARKS::unleash(int slot) // didn't restore anything bookmarks_array[slot].jump(); } - } else + } else if (jump_frame > 0) { // update Markers if (TASEdit_bind_markers) @@ -554,8 +452,10 @@ void BOOKMARKS::unleash(int slot) // switch current branch to this branch if (slot != current_branch && current_branch >= 0) { - RedrawRowAndBookmark(bookmarks_array[current_branch].snapshot.jump_frame); - RedrawRowAndBookmark(bookmarks_array[slot].snapshot.jump_frame); + tasedit_list.RedrawRow(bookmarks_array[current_branch].snapshot.jump_frame); + RedrawChangedBookmarks(bookmarks_array[current_branch].snapshot.jump_frame); + tasedit_list.RedrawRow(bookmarks_array[slot].snapshot.jump_frame); + RedrawChangedBookmarks(bookmarks_array[slot].snapshot.jump_frame); } current_branch = slot; changes_since_current_branch = false; @@ -806,28 +706,6 @@ void BOOKMARKS::RedrawBranchesTree() InvalidateRect(hwndBranchesBitmap, 0, FALSE); } -void BOOKMARKS::ChangeScreenshotBitmap() -{ - // uncompress - uLongf destlen = SCREENSHOT_SIZE; - int e = uncompress(&scr_ptr[0], &destlen, &bookmarks_array[item_under_mouse].saved_screenshot[0], bookmarks_array[item_under_mouse].saved_screenshot.size()); - if (e != Z_OK && e != Z_BUF_ERROR) - { - // error decompressing - FCEU_printf("Error decompressing screenshot %d\n", item_under_mouse); - // at least fill bitmap with zeros - memset(&scr_ptr[0], 0, SCREENSHOT_SIZE); - } - screenshot_currently_shown = item_under_mouse; - RedrawScreenshotBitmap(); -} -void BOOKMARKS::RedrawScreenshotBitmap() -{ - HBITMAP temp_bmp = (HBITMAP)SendMessage(scr_bmp_pic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)scr_bmp); - if (temp_bmp && temp_bmp != scr_bmp) - DeleteObject(temp_bmp); -} - // this is called by wndproc on WM_PAINT void BOOKMARKS::PaintBranchesBitmap(HDC hdc) { @@ -1414,21 +1292,5 @@ LRESULT APIENTRY BranchesBitmapWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARA } 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 - 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: - return DefWindowProc(hwnd, message, wParam, lParam); - } -} diff --git a/src/drivers/win/taseditlib/bookmarks.h b/src/drivers/win/taseditlib/bookmarks.h index 88ae8b10..8aa55dc0 100644 --- a/src/drivers/win/taseditlib/bookmarks.h +++ b/src/drivers/win/taseditlib/bookmarks.h @@ -1,5 +1,4 @@ //Specification file for Bookmarks class - #include "bookmark.h" #define TOTAL_BOOKMARKS 10 @@ -85,10 +84,6 @@ #define BOOKMARKS_ID_LEN 10 #define TIME_DESC_LENGTH 9 // "HH:MM:SS" -// screenshot bitmap -#define SCR_BMP_PHASE_MAX 11 -#define SCR_BMP_PHASE_ALPHA_MAX 8 - class BOOKMARKS { public: @@ -129,9 +124,6 @@ public: void RecursiveAddHeight(int branch_num, int amount); void RecursiveSetYPos(int parent, int parentY); - void ChangeScreenshotBitmap(); - void RedrawScreenshotBitmap(); - std::vector bookmarks_array; // not saved vars @@ -139,17 +131,7 @@ public: int branch_row_left; int branch_row_height; bool mouse_over_bitmap, mouse_over_bookmarkslist; - // screenshot bmp stuff - LPBITMAPINFO scr_bmi; - HBITMAP scr_bmp; - uint8* scr_ptr; - int scr_bmp_x; - int scr_bmp_y; - int scr_bmp_phase; - int screenshot_currently_shown; - HWND hwndScrBmp, scr_bmp_pic; - WNDCLASSEX wincl; - BLENDFUNCTION blend; + int item_under_mouse; TRACKMOUSEEVENT tme, list_tme; private: @@ -164,7 +146,7 @@ private: // not saved vars int check_flash_shedule; int edit_mode; - int animation_frame; // 0-13 + int animation_frame; int next_animation_time; bool must_check_item_under_mouse; bool must_redraw_branches_tree; @@ -180,7 +162,6 @@ private: int transition_phase; int fireball_size; int mouse_x, mouse_y; - int item_under_mouse; HWND hwndBookmarksList, hwndBookmarks; HWND hwndBranchesBitmap; @@ -193,12 +174,10 @@ private: HBITMAP branches_hbitmap, hOldBitmap, buffer_hbitmap, hOldBitmap1, branchesSpritesheet, hOldBitmap2; HDC hBitmapDC, hBufferDC, hSpritesheetDC; - // temps std::vector GridX; // in grid units std::vector GridY; std::vector GridHeight; std::vector> Children; - }; diff --git a/src/drivers/win/taseditlib/greenzone.cpp b/src/drivers/win/taseditlib/greenzone.cpp index b0ca92c3..e1d811f0 100644 --- a/src/drivers/win/taseditlib/greenzone.cpp +++ b/src/drivers/win/taseditlib/greenzone.cpp @@ -6,11 +6,14 @@ extern TASEDIT_PROJECT project; extern PLAYBACK playback; +extern BOOKMARKS bookmarks; +extern TASEDIT_LIST tasedit_list; + + extern int TASEdit_greenzone_capacity; extern bool TASEdit_restore_position; extern void FCEU_printf(char *format, ...); -extern void RedrawListAndBookmarks(); char greenzone_save_id[GREENZONE_ID_LEN] = "GREENZONE"; @@ -151,7 +154,11 @@ void GREENZONE::GreenzoneCleaning() } } finish: - if (changed) RedrawListAndBookmarks(); + if (changed) + { + tasedit_list.RedrawList(); + bookmarks.RedrawBookmarksList(); + } // shedule next cleaning next_cleaning_time = clock() + TIME_BETWEEN_CLEANINGS; } @@ -334,7 +341,8 @@ void GREENZONE::InvalidateAndCheck(int after) } } // redraw list even if greenzone didn't change - RedrawListAndBookmarks(); + tasedit_list.RedrawList(); + bookmarks.RedrawBookmarksList(); } // This version doesn't restore playback, may be used only by Branching and Recording functions! void GREENZONE::Invalidate(int after) @@ -349,7 +357,8 @@ void GREENZONE::Invalidate(int after) } } // redraw list even if greenzone didn't change - RedrawListAndBookmarks(); + tasedit_list.RedrawList(); + bookmarks.RedrawBookmarksList(); } int GREENZONE::FindBeginningOfGreenZone(int starting_index) diff --git a/src/drivers/win/taseditlib/inputhistory.cpp b/src/drivers/win/taseditlib/inputhistory.cpp index 9aeecdd8..951fdb32 100644 --- a/src/drivers/win/taseditlib/inputhistory.cpp +++ b/src/drivers/win/taseditlib/inputhistory.cpp @@ -148,7 +148,7 @@ int INPUT_HISTORY::jump(int new_pos) { if (input_snapshots[real_pos].checkMarkersDiff()) { - input_snapshots[real_pos].toMarkers(); + input_snapshots[real_pos].copyToMarkers(); project.SetProjectChanged(); markers_changed = true; } @@ -313,10 +313,12 @@ int INPUT_HISTORY::RegisterChanges(int mod_type, int start, int end) inp.inheritHotChanges_DeleteSelection(&input_snapshots[real_pos]); break; case MODTYPE_INSERT: - case MODTYPE_PASTEINSERT: case MODTYPE_CLONE: inp.inheritHotChanges_InsertSelection(&input_snapshots[real_pos]); break; + case MODTYPE_PASTEINSERT: + inp.inheritHotChanges_PasteInsert(&input_snapshots[real_pos]); + break; case MODTYPE_CHANGE: case MODTYPE_SET: case MODTYPE_UNSET: diff --git a/src/drivers/win/taseditlib/inputsnapshot.cpp b/src/drivers/win/taseditlib/inputsnapshot.cpp index dc623407..345bd1c9 100644 --- a/src/drivers/win/taseditlib/inputsnapshot.cpp +++ b/src/drivers/win/taseditlib/inputsnapshot.cpp @@ -53,8 +53,7 @@ void INPUT_SNAPSHOT::init(MovieData& md, bool hotchanges) } } // make a copy of markers.markers_array - markers_array = markers.markers_array; - + markers.MakeCopy(markers_array); coherent = true; // save time to description time_t raw_time; @@ -63,20 +62,11 @@ void INPUT_SNAPSHOT::init(MovieData& md, bool hotchanges) strftime(description, 10, "%H:%M:%S", timeinfo); } -// copy all stored markers to Markers -void INPUT_SNAPSHOT::toMarkers() -{ - markers.markers_array = markers_array; -} -// copy some stored markers to Markers manually, from Frame 0 to end frame (including end frame) void INPUT_SNAPSHOT::copyToMarkers(int end) { - if ((int)markers.markers_array.size() <= end) markers.markers_array.resize(end+1); - for (int i = end; i >= 0; i--) - markers.markers_array[i] = markers_array[i]; + markers.RestoreFromCopy(markers_array, end); } - void INPUT_SNAPSHOT::toMovie(MovieData& md, int start, int end) { if (end < 0) end = size-1; @@ -327,17 +317,17 @@ bool INPUT_SNAPSHOT::checkMarkersDiff(INPUT_SNAPSHOT& inp) // return true if any difference in markers_array is found, comparing to markers.markers_array bool INPUT_SNAPSHOT::checkMarkersDiff() { - if (markers_array.size() != markers.markers_array.size()) return true; + if (markers_array.size() != markers.GetMarkersSize()) return true; for (int i = markers_array.size()-1; i >= 0; i--) - if ((markers_array[i] - markers.markers_array[i]) & MARKER_FLAG_BIT) return true; + if ((bool)(markers_array[i] & MARKER_FLAG_BIT) != markers.GetMarker(i)) return true; return false; } // return true only when difference is found before end frame (not including end frame) bool INPUT_SNAPSHOT::checkMarkersDiff(int end) { - if (markers_array.size() != markers.markers_array.size() && ((int)markers_array.size()-1 < end || (int)markers.markers_array.size()-1 < end)) return true; + if (markers_array.size() != markers.GetMarkersSize() && ((int)markers_array.size()-1 < end || (int)markers.GetMarkersSize()-1 < end)) return true; for (int i = end-1; i >= 0; i--) - if ((markers_array[i] - markers.markers_array[i]) & MARKER_FLAG_BIT) return true; + if ((bool)(markers_array[i] & MARKER_FLAG_BIT) != markers.GetMarker(i)) return true; return false; } @@ -527,7 +517,7 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of int this_size = hot_changes.size(), source_size = source_of_hotchanges->hot_changes.size(); SelectionFrames::iterator it(selection.GetStrobedSelection().begin()); SelectionFrames::iterator current_selection_end(selection.GetStrobedSelection().end()); - while (pos < this_size && source_pos < source_size) + while (pos < this_size) { if (it != current_selection_end && frame == *it) { @@ -536,17 +526,16 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of region_len++; // set filled line to the frame memset(&hot_changes[pos], 0xFF, bytes); - pos += bytes; - } else + } else if (source_pos < source_size) { // this frame is not selected frame -= region_len; region_len = 0; // copy hotchanges of this frame memcpy(&hot_changes[pos], &source_of_hotchanges->hot_changes[source_pos], bytes); - pos += bytes; source_pos += bytes; } + pos += bytes; frame++; } FadeHotChanges(); @@ -567,7 +556,6 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of region_len++; // set filled line to the frame memset(&hot_changes[pos], 0xFF, bytes); - pos += bytes; // exit loop when all selection frames are handled if (it == current_selection_end) break; } else @@ -576,6 +564,62 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of frame -= region_len; region_len = 0; // leave zeros in this frame + } + pos += bytes; + frame++; + } + } +} +void INPUT_SNAPSHOT::inheritHotChanges_PasteInsert(INPUT_SNAPSHOT* source_of_hotchanges) +{ + // copy hot changes from source snapshot and insert filled lines for inserted frames (which are represented by inserted_set) + if (source_of_hotchanges && source_of_hotchanges->has_hot_changes) + { + 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.GetInsertedSet().begin()); + SelectionFrames::iterator inserted_set_end(selection.GetInsertedSet().end()); + while (pos < this_size) + { + if (it != inserted_set_end && frame == *it) + { + // this frame was inserted + it++; + // set filled line to the frame + memset(&hot_changes[pos], 0xFF, bytes); + } else if (source_pos < source_size) + { + // copy hotchanges of this frame + memcpy(&hot_changes[pos], &source_of_hotchanges->hot_changes[source_pos], bytes); + source_pos += bytes; + } + pos += bytes; + frame++; + } + FadeHotChanges(); + } else + { + // no old data, just fill selected lines + int bytes = bytes_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; + int frame = 0, pos = 0; + int this_size = hot_changes.size(); + SelectionFrames::iterator it(selection.GetInsertedSet().begin()); + SelectionFrames::iterator inserted_set_end(selection.GetInsertedSet().end()); + while (pos < this_size) + { + if (it != inserted_set_end && frame == *it) + { + // this frame was inserted + it++; + // set filled line to the frame + memset(&hot_changes[pos], 0xFF, bytes); + pos += bytes; + // exit loop when all inserted_set frames are handled + if (it == inserted_set_end) break; + } else + { + // leave zeros in this frame pos += bytes; } frame++; diff --git a/src/drivers/win/taseditlib/inputsnapshot.h b/src/drivers/win/taseditlib/inputsnapshot.h index c9bf00ba..3fdcdccc 100644 --- a/src/drivers/win/taseditlib/inputsnapshot.h +++ b/src/drivers/win/taseditlib/inputsnapshot.h @@ -15,7 +15,7 @@ public: void toMovie(MovieData& md, int start = 0, int end = -1); void toMarkers(); - void copyToMarkers(int end); + void copyToMarkers(int end = -1); void save(EMUFILE *os); bool load(EMUFILE *is); @@ -37,6 +37,7 @@ public: void inheritHotChanges(INPUT_SNAPSHOT* source_of_hotchanges); void inheritHotChanges_DeleteSelection(INPUT_SNAPSHOT* source_of_hotchanges); void inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of_hotchanges); + void inheritHotChanges_PasteInsert(INPUT_SNAPSHOT* source_of_hotchanges); void fillHotChanges(INPUT_SNAPSHOT& inp, int start = 0, int end = -1); void SetMaxHotChange_Bits(int frame, int joypad, uint8 joy_bits); diff --git a/src/drivers/win/taseditlib/markers.cpp b/src/drivers/win/taseditlib/markers.cpp index b263ba34..f43ec35c 100644 --- a/src/drivers/win/taseditlib/markers.cpp +++ b/src/drivers/win/taseditlib/markers.cpp @@ -66,12 +66,66 @@ error: return true; } // ---------------------------------------------------------- +void MARKERS::MakeCopy(std::vector &destination_array) +{ + // copy array + destination_array = markers_array; + // copy notes + + +} +void MARKERS::RestoreFromCopy(std::vector &source_array, int until_frame) +{ + if (until_frame >= 0) + { + // restore array up to and including the frame + if ((int)markers_array.size() <= until_frame) markers_array.resize(until_frame+1); + for (int i = until_frame; i >= 0; i--) + markers_array[i] = source_array[i]; + // restore notes + + } else + { + // restore array + markers_array = source_array; + // restore notes + + } +} + +int MARKERS::GetMarkersSize() +{ + return markers_array.size(); +} + +bool MARKERS::GetMarker(int frame) +{ + if (frame >= 0 && frame < (int)markers_array.size()) + return markers_array[frame] & MARKER_FLAG_BIT; + return false; +} +void MARKERS::SetMarker(int frame) +{ + markers_array[frame] |= MARKER_FLAG_BIT; +} +void MARKERS::ClearMarker(int frame) +{ + markers_array[frame] &= ~MARKER_FLAG_BIT; +} +void MARKERS::EraseMarker(int frame) +{ + // check if there's a marker, delete note if needed + markers_array.erase(markers_array.begin() + frame); +} void MARKERS::ToggleMarker(int frame) { - if (markers_array[frame] & MARKER_FLAG_BIT) - markers_array[frame] &= ~MARKER_FLAG_BIT; - else - markers_array[frame] |= MARKER_FLAG_BIT; + if (frame >= 0 && frame < (int)markers_array.size()) + { + if (markers_array[frame] & MARKER_FLAG_BIT) + markers_array[frame] &= ~MARKER_FLAG_BIT; + else + markers_array[frame] |= MARKER_FLAG_BIT; + } } void MARKERS::insertEmpty(int at, int frames) diff --git a/src/drivers/win/taseditlib/markers.h b/src/drivers/win/taseditlib/markers.h index 7d1e088d..68853f0a 100644 --- a/src/drivers/win/taseditlib/markers.h +++ b/src/drivers/win/taseditlib/markers.h @@ -15,12 +15,21 @@ public: void save(EMUFILE *os); bool load(EMUFILE *is); + void MakeCopy(std::vector &destination_array); + void RestoreFromCopy(std::vector &source_array, int until_frame = -1); + + bool GetMarker(int frame); + int GetMarkersSize(); + + void SetMarker(int frame); + void ClearMarker(int frame); + void EraseMarker(int frame); void ToggleMarker(int frame); + void insertEmpty(int at, int frames); void truncateAt(int frame); +private: std::vector markers_array; -private: - }; diff --git a/src/drivers/win/taseditlib/playback.cpp b/src/drivers/win/taseditlib/playback.cpp index 3096d6e2..785723d0 100644 --- a/src/drivers/win/taseditlib/playback.cpp +++ b/src/drivers/win/taseditlib/playback.cpp @@ -1,5 +1,4 @@ //Implementation file of Playback class - #include "taseditproj.h" #ifdef _S9XLUA_H @@ -7,16 +6,14 @@ extern void ForceExecuteLuaFrameFunctions(); #endif extern HWND hwndTasEdit; -extern void FCEU_printf(char *format, ...); -extern void RedrawListAndBookmarks(); -extern void RedrawRowAndBookmark(int index); +extern bool Tasedit_rewind_now; extern bool turbo; +extern bool TASEdit_turbo_seek; extern MARKERS markers; extern GREENZONE greenzone; extern TASEDIT_LIST tasedit_list; - -extern bool Tasedit_rewind_now; +extern BOOKMARKS bookmarks; PLAYBACK::PLAYBACK() { @@ -35,7 +32,7 @@ void PLAYBACK::init() } void PLAYBACK::reset() { - lastCursor = -1; + lastCursor = currFrameCounter; pause_frame = old_pauseframe = 0; old_show_pauseframe = show_pauseframe = false; old_rewind_button_state = rewind_button_state = false; @@ -53,7 +50,12 @@ void PLAYBACK::update() SeekingStop(); // update flashing pauseframe - if (old_pauseframe != pause_frame && old_pauseframe) RedrawRowAndBookmark(old_pauseframe-1); + if (old_pauseframe != pause_frame && old_pauseframe) + { + // pause_frame was changed, clear old_pauseframe gfx + tasedit_list.RedrawRow(old_pauseframe-1); + bookmarks.RedrawChangedBookmarks(old_pauseframe-1); + } old_pauseframe = pause_frame; old_show_pauseframe = show_pauseframe; if (pause_frame) @@ -63,7 +65,12 @@ void PLAYBACK::update() else show_pauseframe = (int)(clock() / PAUSEFRAME_BLINKING_PERIOD_SEEKING) & 1; } else show_pauseframe = false; - if (old_show_pauseframe != show_pauseframe) RedrawRowAndBookmark(pause_frame-1); + if (old_show_pauseframe != show_pauseframe) + { + // update pauseframe gfx + tasedit_list.RedrawRow(pause_frame-1); + bookmarks.RedrawChangedBookmarks(pause_frame-1); + } // update seeking progressbar old_emu_paused = emu_paused; @@ -83,13 +90,16 @@ void PLAYBACK::update() SetProgressbar(1, 1); } - //update the playback cursor + // update the playback cursor if(currFrameCounter != lastCursor) { tasedit_list.FollowPlayback(); - //update the old and new rows - RedrawRowAndBookmark(lastCursor); - RedrawRowAndBookmark(currFrameCounter); + // update gfx of the old and new rows + tasedit_list.RedrawRow(lastCursor); + bookmarks.RedrawChangedBookmarks(lastCursor); + tasedit_list.RedrawRow(currFrameCounter); + bookmarks.RedrawChangedBookmarks(currFrameCounter); + // enforce redrawing now UpdateWindow(tasedit_list.hwndList); lastCursor = currFrameCounter; } @@ -187,7 +197,8 @@ void PLAYBACK::SeekingStart(int finish_frame) { seeking_start_frame = currFrameCounter; pause_frame = finish_frame; - turbo = true; + if (TASEdit_turbo_seek) + turbo = true; UnpauseEmulation(); } void PLAYBACK::SeekingStop() @@ -201,7 +212,10 @@ void PLAYBACK::SeekingStop() void PLAYBACK::RewindFrame() { if (pause_frame && !emu_paused) return; - if (currFrameCounter > 0) jump(currFrameCounter-1); + if (currFrameCounter > 0) + jump(currFrameCounter-1); + else + tasedit_list.FollowPlayback(); if (!pause_frame) PauseEmulation(); } void PLAYBACK::ForwardFrame() @@ -214,31 +228,25 @@ void PLAYBACK::ForwardFrame() void PLAYBACK::RewindFull() { // jump to previous marker - if (currFrameCounter > 0) - { - int index = currFrameCounter - 1; - for (; index >= 0; index--) - if (markers.markers_array[index] & MARKER_FLAG_BIT) break; - if (index >= 0) - jump(index); - else if (currFrameCounter > 0) - jump(0); - } + int index = currFrameCounter - 1; + for (; index >= 0; index--) + if (markers.GetMarker(index)) break; + if (index >= 0) + jump(index); + else + jump(0); } void PLAYBACK::ForwardFull() { // jump to next marker int last_frame = currMovieData.getNumRecords()-1; - if (currFrameCounter < last_frame) - { - int index = currFrameCounter + 1; - for (; index < last_frame; ++index) - if (markers.markers_array[index] & MARKER_FLAG_BIT) break; - if (index <= last_frame) - jump(index); - else if (currFrameCounter < last_frame) - jump(last_frame); - } + int index = currFrameCounter + 1; + for (; index <= last_frame; ++index) + if (markers.GetMarker(index)) break; + if (index <= last_frame) + jump(index); + else + jump(last_frame); } void PLAYBACK::StartFromZero() diff --git a/src/drivers/win/taseditlib/playback.h b/src/drivers/win/taseditlib/playback.h index 62f878b4..f2ab786b 100644 --- a/src/drivers/win/taseditlib/playback.h +++ b/src/drivers/win/taseditlib/playback.h @@ -38,14 +38,14 @@ public: int GetPauseFrame(); void SetProgressbar(int a, int b); + int pause_frame; + HWND hwndProgressbar, hwndRewind, hwndForward, hwndRewindFull, hwndForwardFull; private: bool JumpToFrame(int index); - int pause_frame; - - int lastCursor; // for currentCursor we use external variable currFrameCounter + int lastCursor; // but for currentCursor we use external variable currFrameCounter bool old_emu_paused, emu_paused; int old_pauseframe; bool old_show_pauseframe, show_pauseframe; diff --git a/src/drivers/win/taseditlib/recorder.cpp b/src/drivers/win/taseditlib/recorder.cpp index 98529acb..b3ea4c05 100644 --- a/src/drivers/win/taseditlib/recorder.cpp +++ b/src/drivers/win/taseditlib/recorder.cpp @@ -14,7 +14,7 @@ extern bool TASEdit_use_1p_rec; extern int TASEdit_superimpose; // resources -char windowCaptions[5][30] = { " (Recording All)", +char recordingCaptions[5][30] = { " (Recording All)", " (Recording 1P)", " (Recording 2P)", " (Recording 3P)", @@ -100,7 +100,7 @@ void RECORDER::RecheckRecordingRadioButtons() } } -void RECORDER::InputChangedRec() +void RECORDER::InputChanged() { bool changes_made = false; // take previous values from current snapshot, new input from current movie diff --git a/src/drivers/win/taseditlib/recorder.h b/src/drivers/win/taseditlib/recorder.h index b9999064..88ba4531 100644 --- a/src/drivers/win/taseditlib/recorder.h +++ b/src/drivers/win/taseditlib/recorder.h @@ -17,7 +17,7 @@ public: void UncheckRecordingRadioButtons(); void RecheckRecordingRadioButtons(); - void InputChangedRec(); + void InputChanged(); int multitrack_recording_joypad; HWND hwndRB_RecOff, hwndRB_RecAll, hwndRB_Rec1P, hwndRB_Rec2P, hwndRB_Rec3P, hwndRB_Rec4P; diff --git a/src/drivers/win/taseditlib/screenshot_display.cpp b/src/drivers/win/taseditlib/screenshot_display.cpp new file mode 100644 index 00000000..b115ddae --- /dev/null +++ b/src/drivers/win/taseditlib/screenshot_display.cpp @@ -0,0 +1,195 @@ +//Implementation file of SCREENSHOT_DISPLAY class + +#include "taseditproj.h" +#include "zlib.h" + +extern HWND hwndTasEdit; +extern int TasEdit_wndx, TasEdit_wndy; +extern bool TASEdit_show_branch_screenshots; + +extern BOOKMARKS bookmarks; +extern TASEDIT_LIST tasedit_list; + +LRESULT CALLBACK ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +// resources +char szClassName[] = "ScrBmp"; + +SCREENSHOT_DISPLAY::SCREENSHOT_DISPLAY() +{ + // create BITMAPINFO + scr_bmi = (LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); // 256 color in palette + scr_bmi->bmiHeader.biSize = sizeof(scr_bmi->bmiHeader); + scr_bmi->bmiHeader.biWidth = SCREENSHOT_WIDTH; + scr_bmi->bmiHeader.biHeight = -SCREENSHOT_HEIGHT; // negative value = top-down bmp + scr_bmi->bmiHeader.biPlanes = 1; + scr_bmi->bmiHeader.biBitCount = 8; + scr_bmi->bmiHeader.biCompression = BI_RGB; + scr_bmi->bmiHeader.biSizeImage = 0; + + // register ScrBmp window class + wincl.hInstance = fceu_hInstance; + wincl.lpszClassName = szClassName; + wincl.lpfnWndProc = ScrBmpWndProc; + wincl.style = CS_DBLCLKS; + wincl.cbSize = sizeof(WNDCLASSEX); + wincl.hIcon = 0; + wincl.hIconSm = 0; + wincl.hCursor = 0; + wincl.lpszMenuName = 0; + wincl.cbClsExtra = 0; + wincl.cbWndExtra = 0; + wincl.hbrBackground = 0; + if(!RegisterClassEx(&wincl)) + FCEU_printf("Error registering SCR_DISPLAY window class\n"); + // create blendfunction + blend.BlendOp = AC_SRC_OVER; + blend.BlendFlags = 0; + blend.AlphaFormat = 0; + blend.SourceConstantAlpha = 255; +} + +void SCREENSHOT_DISPLAY::init() +{ + free(); + // fill scr_bmp palette with current palette colors + extern PALETTEENTRY *color_palette; + for (int i = 0; i < 256; ++i) + { + scr_bmi->bmiColors[i].rgbRed = color_palette[i].peRed; + scr_bmi->bmiColors[i].rgbGreen = color_palette[i].peGreen; + scr_bmi->bmiColors[i].rgbBlue = color_palette[i].peBlue; + } + 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) + 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; +} +void SCREENSHOT_DISPLAY::free() +{ + reset(); + if (scr_bmp) + { + DeleteObject(scr_bmp); + scr_bmp = 0; + } +} +void SCREENSHOT_DISPLAY::reset() +{ + screenshot_currently_shown = ITEM_UNDER_MOUSE_NONE; + next_update_time = scr_bmp_phase = 0; + if (hwndScrBmp) + { + DestroyWindow(hwndScrBmp); + hwndScrBmp = 0; + } +} + +void SCREENSHOT_DISPLAY::update() +{ + // once per 40 milliseconds update screenshot_bitmap alpha + if (clock() > next_update_time) + { + next_update_time = clock() + DISPLAY_UPDATE_TICK; + if (bookmarks.item_under_mouse >= 0 && bookmarks.item_under_mouse < TOTAL_BOOKMARKS && TASEdit_show_branch_screenshots) + { + if (!hwndScrBmp) + { + // create window + hwndScrBmp = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT, szClassName, szClassName, WS_POPUP, TasEdit_wndx + scr_bmp_x, TasEdit_wndy + scr_bmp_y, SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT, hwndTasEdit, NULL, fceu_hInstance, NULL); + RedrawScreenshotBitmap(); + ShowWindow(hwndScrBmp, SW_SHOWNA); + } + // change screenshot_bitmap pic if needed + if (bookmarks.item_under_mouse != screenshot_currently_shown) + { + if (bookmarks.bookmarks_array[bookmarks.item_under_mouse].not_empty) + ChangeScreenshotBitmap(); + } + if (scr_bmp_phase < SCR_BMP_PHASE_MAX) + { + scr_bmp_phase++; + // update alpha + int phase_alpha = scr_bmp_phase; + if (phase_alpha > SCR_BMP_PHASE_ALPHA_MAX) phase_alpha = SCR_BMP_PHASE_ALPHA_MAX; + SetLayeredWindowAttributes(hwndScrBmp, 0, (255 * phase_alpha) / SCR_BMP_PHASE_ALPHA_MAX, LWA_ALPHA); + UpdateLayeredWindow(hwndScrBmp, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA); + } + } else + { + // fade and finally hide screenshot + if (scr_bmp_phase > 0) + scr_bmp_phase--; + if (scr_bmp_phase > 0) + { + if (hwndScrBmp) + { + // update alpha + int phase_alpha = scr_bmp_phase; + if (phase_alpha > SCR_BMP_PHASE_ALPHA_MAX) phase_alpha = SCR_BMP_PHASE_ALPHA_MAX; + SetLayeredWindowAttributes(hwndScrBmp, 0, (255 * phase_alpha) / SCR_BMP_PHASE_ALPHA_MAX, LWA_ALPHA); + UpdateLayeredWindow(hwndScrBmp, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA); + } + } else + { + // destroy screenshot bitmap window + scr_bmp_phase = 0; + if (hwndScrBmp) + { + DestroyWindow(hwndScrBmp); + hwndScrBmp = 0; + } + } + } + } +} + +void SCREENSHOT_DISPLAY::ChangeScreenshotBitmap() +{ + // uncompress + uLongf destlen = SCREENSHOT_SIZE; + int e = uncompress(&scr_ptr[0], &destlen, &bookmarks.bookmarks_array[bookmarks.item_under_mouse].saved_screenshot[0], bookmarks.bookmarks_array[bookmarks.item_under_mouse].saved_screenshot.size()); + if (e != Z_OK && e != Z_BUF_ERROR) + { + // error decompressing + FCEU_printf("Error decompressing screenshot %d\n", bookmarks.item_under_mouse); + // at least fill bitmap with zeros + memset(&scr_ptr[0], 0, SCREENSHOT_SIZE); + } + screenshot_currently_shown = bookmarks.item_under_mouse; + RedrawScreenshotBitmap(); +} +void SCREENSHOT_DISPLAY::RedrawScreenshotBitmap() +{ + HBITMAP temp_bmp = (HBITMAP)SendMessage(scr_bmp_pic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)scr_bmp); + if (temp_bmp && temp_bmp != scr_bmp) + DeleteObject(temp_bmp); +} + +void SCREENSHOT_DISPLAY::ParentWindowMoved() +{ + if (hwndScrBmp) + SetWindowPos(hwndScrBmp, 0, TasEdit_wndx + scr_bmp_x, TasEdit_wndy + scr_bmp_y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); +} +// ---------------------------------------------------------------------------------------- +LRESULT APIENTRY ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + extern SCREENSHOT_DISPLAY screenshot_display; + switch(message) + { + case WM_CREATE: + { + // create static bitmap placeholder + screenshot_display.scr_bmp_pic = CreateWindow(WC_STATIC, NULL, SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 255, 255, hwnd, NULL, NULL, NULL); + return 0; + } + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } +} + + diff --git a/src/drivers/win/taseditlib/screenshot_display.h b/src/drivers/win/taseditlib/screenshot_display.h new file mode 100644 index 00000000..8a61b59f --- /dev/null +++ b/src/drivers/win/taseditlib/screenshot_display.h @@ -0,0 +1,37 @@ +//Specification file for SCREENSHOT_DISPLAY class + +#define SCR_BMP_PHASE_MAX 13 +#define SCR_BMP_PHASE_ALPHA_MAX 10 + +#define DISPLAY_UPDATE_TICK 40 // update at 25FPS + +class SCREENSHOT_DISPLAY +{ +public: + SCREENSHOT_DISPLAY(); + void init(); + void free(); + void reset(); + void update(); + + void ChangeScreenshotBitmap(); + void RedrawScreenshotBitmap(); + + void ParentWindowMoved(); + + int screenshot_currently_shown; + HWND hwndScrBmp, scr_bmp_pic; + +private: + int scr_bmp_x; + int scr_bmp_y; + int scr_bmp_phase; + int next_update_time; + + WNDCLASSEX wincl; + BLENDFUNCTION blend; + LPBITMAPINFO scr_bmi; + HBITMAP scr_bmp; + uint8* scr_ptr; + +}; diff --git a/src/drivers/win/taseditlib/tasedit_list.cpp b/src/drivers/win/taseditlib/tasedit_list.cpp index 43eaf866..2f87a99c 100644 --- a/src/drivers/win/taseditlib/tasedit_list.cpp +++ b/src/drivers/win/taseditlib/tasedit_list.cpp @@ -27,6 +27,7 @@ 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 }; +char list_save_id[LIST_ID_LEN] = "LIST"; TASEDIT_LIST::TASEDIT_LIST() { @@ -49,7 +50,7 @@ TASEDIT_LIST::TASEDIT_LIST() void TASEDIT_LIST::init() { - //free(); + free(); hwndList = GetDlgItem(hwndTasEdit, IDC_LIST1); // prepare the main listview @@ -153,18 +154,16 @@ void TASEDIT_LIST::init() 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() { - + if (himglist) + { + ImageList_Destroy(himglist); + himglist = 0; + } } @@ -178,6 +177,36 @@ void TASEDIT_LIST::update() } + +void TASEDIT_LIST::save(EMUFILE *os) +{ + // write "LIST" string + os->fwrite(list_save_id, LIST_ID_LEN); + // write current top item + int top_item = ListView_GetTopIndex(hwndList); + write32le(top_item, os); + +} +// returns true if couldn't load +bool TASEDIT_LIST::load(EMUFILE *is) +{ + update(); + // read "LIST" string + char save_id[LIST_ID_LEN]; + if ((int)is->fread(save_id, LIST_ID_LEN) < LIST_ID_LEN) goto error; + if (strcmp(list_save_id, save_id)) goto error; // string is not valid + // read current top item and scroll list there + int top_item; + if (!read32le(&top_item, is)) goto error; + ListView_EnsureVisible(hwndList, currMovieData.getNumRecords() - 1, FALSE); + ListView_EnsureVisible(hwndList, top_item, FALSE); + + return false; +error: + // scroll to the beginning + ListView_EnsureVisible(hwndList, 0, FALSE); + return true; +} // ---------------------------------------------------------------------- void TASEDIT_LIST::AddFourscore() { @@ -413,19 +442,19 @@ LONG TASEDIT_LIST::CustomDraw(NMLVCUSTOMDRAW* msg) 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)) + if(TASEdit_show_markers && markers.GetMarker(cell_y)) 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)) + if(TASEdit_show_markers && markers.GetMarker(cell_y)) // 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)) + } else if(TASEdit_show_markers && markers.GetMarker(cell_y)) { // marked frame msg->clrTextBk = MARKED_FRAMENUM_COLOR; diff --git a/src/drivers/win/taseditlib/tasedit_list.h b/src/drivers/win/taseditlib/tasedit_list.h index 90811f36..9d481211 100644 --- a/src/drivers/win/taseditlib/tasedit_list.h +++ b/src/drivers/win/taseditlib/tasedit_list.h @@ -1,4 +1,6 @@ //Specification file for TASEDIT_LIST class +#define LIST_ID_LEN 5 + #define CDDS_SUBITEMPREPAINT (CDDS_SUBITEM | CDDS_ITEMPREPAINT) #define CDDS_SUBITEMPOSTPAINT (CDDS_SUBITEM | CDDS_ITEMPOSTPAINT) #define CDDS_SUBITEMPREERASE (CDDS_SUBITEM | CDDS_ITEMPREERASE) @@ -90,6 +92,9 @@ public: void free(); void update(); + void save(EMUFILE *os); + bool load(EMUFILE *is); + void AddFourscore(); void RemoveFourscore(); diff --git a/src/drivers/win/taseditlib/tasedit_sel.cpp b/src/drivers/win/taseditlib/tasedit_sel.cpp index 93bb1aa2..4c04e038 100644 --- a/src/drivers/win/taseditlib/tasedit_sel.cpp +++ b/src/drivers/win/taseditlib/tasedit_sel.cpp @@ -4,15 +4,33 @@ char selection_save_id[SELECTION_ID_LEN] = "SELECTION"; +extern HWND hwndTasEdit; + extern MARKERS markers; extern TASEDIT_LIST tasedit_list; +// resources +char selectionText[] = "Selection: "; +char selectionEmptyText[] = "Selection: no"; +char numTextRow[] = "1 row, "; +char numTextRows[] = " rows, "; +char numTextColumn[] = "1 column"; +char numTextColumns[] = " columns"; +char clipboardText[] = "Clipboard: "; +char clipboardEmptyText[] = "Clipboard: empty"; + TASEDIT_SELECTION::TASEDIT_SELECTION() { } void TASEDIT_SELECTION::init(int new_size) { + hwndPrevMarker = GetDlgItem(hwndTasEdit, TASEDIT_PREV_MARKER); + hwndNextMarker = GetDlgItem(hwndTasEdit, TASEDIT_NEXT_MARKER); + hwndFindBestMarker = GetDlgItem(hwndTasEdit, TASEDIT_FIND_BEST_MARKER); + hwndFindNextMarker = GetDlgItem(hwndTasEdit, TASEDIT_FIND_NEXT_MARKER); + hwndTextSelection = GetDlgItem(hwndTasEdit, IDC_TEXT_SELECTION); + hwndTextClipboard = GetDlgItem(hwndTasEdit, IDC_TEXT_CLIPBOARD); // init vars if (new_size > 0) history_size = new_size + 1; @@ -23,16 +41,24 @@ void TASEDIT_SELECTION::init(int new_size) history_cursor_pos = -1; // create initial selection AddNewSelectionToHistory(); - track_selection_changes = true; + reset(); + RedrawTextClipboard(); } void TASEDIT_SELECTION::free() { // clear history selections_history.resize(0); history_total_items = 0; + temp_selection.clear(); clipboard_selection.clear(); } +void TASEDIT_SELECTION::reset() +{ + old_prev_marker_button_state = prev_marker_button_state = false; + old_next_marker_button_state = next_marker_button_state = false; + must_redraw_text = true; +} void TASEDIT_SELECTION::update() { @@ -49,9 +75,138 @@ void TASEDIT_SELECTION::update() if (!CurrentSelection().size()) break; } } + // update << and >> buttons + old_prev_marker_button_state = prev_marker_button_state; + prev_marker_button_state = ((Button_GetState(hwndPrevMarker) & BST_PUSHED) != 0); + if (prev_marker_button_state) + { + if (!old_prev_marker_button_state) + { + button_hold_time = clock(); + JumpPrevMarker(); + } else if (button_hold_time + HOLD_REPEAT_DELAY < clock()) + { + JumpPrevMarker(); + } + } + old_next_marker_button_state = next_marker_button_state; + next_marker_button_state = (Button_GetState(hwndNextMarker) & BST_PUSHED) != 0; + if (next_marker_button_state) + { + if (!old_next_marker_button_state) + { + button_hold_time = clock(); + JumpNextMarker(); + } else if (button_hold_time + HOLD_REPEAT_DELAY < clock()) + { + JumpNextMarker(); + } + } + // redraw selection info text of needed + if (must_redraw_text) + { + if (CurrentSelection().size()) + { + char new_text[100]; + strcpy(new_text, selectionText); + char num[11]; + // rows + if (CurrentSelection().size() > 1) + { + _itoa(CurrentSelection().size(), num, 10); + strcat(new_text, num); + strcat(new_text, numTextRows); + } else + { + strcat(new_text, numTextRow); + } + // columns + int columns; // in future the number of columns will depend on selected columns + if (currMovieData.fourscore) columns = 32; else columns = 16; + if (columns > 1) + { + _itoa(columns, num, 10); + strcat(new_text, num); + strcat(new_text, numTextColumns); + } else + { + strcat(new_text, numTextColumn); + } + SetWindowText(hwndTextSelection, new_text); + } else + SetWindowText(hwndTextSelection, selectionEmptyText); + must_redraw_text = false; + } } +void TASEDIT_SELECTION::RedrawTextClipboard() +{ + if (clipboard_selection.size()) + { + char new_text[100]; + strcpy(new_text, clipboardText); + char num[11]; + // rows + if (clipboard_selection.size() > 1) + { + _itoa(clipboard_selection.size(), num, 10); + strcat(new_text, num); + strcat(new_text, numTextRows); + } else + { + strcat(new_text, numTextRow); + } + // columns + int columns; // in future the number of columns will depend on selected columns + if (currMovieData.fourscore) columns = 32; else columns = 16; + if (columns > 1) + { + _itoa(columns, num, 10); + strcat(new_text, num); + strcat(new_text, numTextColumns); + } else + { + strcat(new_text, numTextColumn); + } + SetWindowText(hwndTextClipboard, new_text); + } else + SetWindowText(hwndTextClipboard, clipboardEmptyText); +} + +void TASEDIT_SELECTION::JumpPrevMarker() +{ + // jump to previous marker + int index = GetCurrentSelectionBeginning(); + if (index < 0) index = currFrameCounter; // if nothing is selected, consider playback cursor as current selection + for (index--; index >= 0; index--) + if (markers.GetMarker(index)) break; + if (index >= 0) + JumpToFrame(index); + else + JumpToFrame(0); +} +void TASEDIT_SELECTION::JumpNextMarker() +{ + // jump to next marker + int index = GetCurrentSelectionBeginning(); + if (index < 0) index = currFrameCounter; // if nothing is selected, consider playback cursor as current selection + + int last_frame = currMovieData.getNumRecords()-1; + for (++index; index <= last_frame; ++index) + if (markers.GetMarker(index)) break; + if (index <= last_frame) + JumpToFrame(index); + else + JumpToFrame(last_frame); +} +void TASEDIT_SELECTION::JumpToFrame(int frame) +{ + ClearSelection(); + SetRowSelection(frame); + tasedit_list.FollowSelection(); +} +// ---------------------------------------------------------- void TASEDIT_SELECTION::save(EMUFILE *os) { // write "SELECTION" string @@ -114,6 +269,7 @@ bool TASEDIT_SELECTION::load(EMUFILE *is) if (loadSelection(clipboard_selection, is)) goto error; // all ok EnforceSelectionToList(); + reset(); return false; error: return true; @@ -162,6 +318,8 @@ void TASEDIT_SELECTION::ItemRangeChanged(NMLVODSTATECHANGE* info) else for(int i = info->iFrom; i <= info->iTo; ++i) CurrentSelection().erase(i); + + must_redraw_text = true; } void TASEDIT_SELECTION::ItemChanged(NMLISTVIEW* info) { @@ -193,6 +351,8 @@ void TASEDIT_SELECTION::ItemChanged(NMLISTVIEW* info) else if(OFF) CurrentSelection().erase(item); } + + must_redraw_text = true; } // ---------------------------------------------------------- void TASEDIT_SELECTION::AddNewSelectionToHistory() @@ -242,6 +402,7 @@ void TASEDIT_SELECTION::MemorizeClipboardSelection() { // copy currently strobed selection data to clipboard_selection clipboard_selection = temp_selection; + RedrawTextClipboard(); } void TASEDIT_SELECTION::ReselectClipboard() { @@ -277,7 +438,6 @@ void TASEDIT_SELECTION::EnforceSelectionToList() void TASEDIT_SELECTION::SelectAll() { ListView_SetItemState(tasedit_list.hwndList, -1, LVIS_SELECTED, LVIS_SELECTED); - //RedrawList(); } void TASEDIT_SELECTION::SetRowSelection(int index) { @@ -304,10 +464,10 @@ void TASEDIT_SELECTION::SelectMidMarkers() // find markers // searching up starting from center-0 for (upper_marker = center; upper_marker >= 0; upper_marker--) - if (markers.markers_array[upper_marker] & MARKER_FLAG_BIT) break; + if (markers.GetMarker(upper_marker)) break; // searching down starting from center+1 for (lower_marker = center+1; lower_marker < movie_size; ++lower_marker) - if (markers.markers_array[lower_marker] & MARKER_FLAG_BIT) break; + if (markers.GetMarker(lower_marker)) 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(tasedit_list.hwndList, -1, 0, LVIS_SELECTED); @@ -388,6 +548,11 @@ SelectionFrames& TASEDIT_SELECTION::GetStrobedSelection() { return temp_selection; } + +SelectionFrames& TASEDIT_SELECTION::GetInsertedSet() +{ + return inserted_set; +} // this getter is only for inside-class use SelectionFrames& TASEDIT_SELECTION::CurrentSelection() { diff --git a/src/drivers/win/taseditlib/tasedit_sel.h b/src/drivers/win/taseditlib/tasedit_sel.h index 4ace8763..bf37606f 100644 --- a/src/drivers/win/taseditlib/tasedit_sel.h +++ b/src/drivers/win/taseditlib/tasedit_sel.h @@ -8,8 +8,11 @@ public: TASEDIT_SELECTION(); void init(int new_size = 0); void free(); + void reset(); void update(); + void RedrawTextClipboard(); + void save(EMUFILE *os); bool load(EMUFILE *is); void saveSelection(SelectionFrames& selection, EMUFILE *os); @@ -38,6 +41,10 @@ public: void SetRegionSelection(int start, int end); void SelectMidMarkers(); + void JumpPrevMarker(); + void JumpNextMarker(); + void JumpToFrame(int frame); + // getters int GetCurrentSelectionSize(); int GetCurrentSelectionBeginning(); @@ -45,14 +52,23 @@ public: SelectionFrames* MakeStrobe(); SelectionFrames& GetStrobedSelection(); + SelectionFrames& GetInsertedSet(); + private: SelectionFrames& CurrentSelection(); bool track_selection_changes; + bool must_redraw_text; + + bool old_prev_marker_button_state, prev_marker_button_state; + bool old_next_marker_button_state, next_marker_button_state; + int button_hold_time; std::vector selections_history; SelectionFrames clipboard_selection; + SelectionFrames inserted_set; + int history_cursor_pos; int history_start_pos; int history_total_items; @@ -60,4 +76,7 @@ private: SelectionFrames temp_selection; + HWND hwndPrevMarker, hwndNextMarker, hwndFindBestMarker, hwndFindNextMarker; + HWND hwndTextSelection, hwndTextClipboard; + }; diff --git a/src/drivers/win/taseditlib/taseditproj.cpp b/src/drivers/win/taseditlib/taseditproj.cpp index 274a5e73..08bc52a5 100644 --- a/src/drivers/win/taseditlib/taseditproj.cpp +++ b/src/drivers/win/taseditlib/taseditproj.cpp @@ -1,11 +1,12 @@ //Implementation file of TASEdit Project class - #include "taseditproj.h" extern MARKERS markers; extern BOOKMARKS bookmarks; +extern SCREENSHOT_DISPLAY screenshot_display; extern GREENZONE greenzone; extern PLAYBACK playback; +extern RECORDER recorder; extern INPUT_HISTORY history; extern TASEDIT_LIST tasedit_list; extern TASEDIT_SELECTION selection; @@ -59,6 +60,7 @@ bool TASEDIT_PROJECT::saveProject() greenzone.save(ofs); history.save(ofs); selection.save(ofs); + tasedit_list.save(ofs); delete ofs; @@ -81,7 +83,6 @@ bool TASEDIT_PROJECT::LoadProject(std::string PFN) bool error; LoadFM2(currMovieData, &ifs, ifs.size(), false); LoadSubtitles(currMovieData); - tasedit_list.update(); // try to load markers error = markers.load(&ifs); if (error) @@ -125,14 +126,23 @@ bool TASEDIT_PROJECT::LoadProject(std::string PFN) { FCEU_printf("Error loading selection\n"); selection.init(); + } else + { + // update and try to load list + error = tasedit_list.load(&ifs); + } + if (error) + { + FCEU_printf("Error loading list\n"); } + playback.reset(); + recorder.reset(); + screenshot_display.reset(); reset(); - playback.updateProgressbar(); return true; } // ----------------------------------------------------------------- -//All the get/set functions... std::string TASEDIT_PROJECT::GetProjectName() { return projectName; diff --git a/src/drivers/win/taseditlib/taseditproj.h b/src/drivers/win/taseditlib/taseditproj.h index 336da570..6a1ca266 100644 --- a/src/drivers/win/taseditlib/taseditproj.h +++ b/src/drivers/win/taseditlib/taseditproj.h @@ -14,6 +14,7 @@ typedef std::set SelectionFrames; #include "bookmarks.h" #include "tasedit_list.h" #include "tasedit_sel.h" +#include "screenshot_display.h" #define AUTOSAVE_PERIOD_SCALE 60000 // = 1 minute in milliseconds diff --git a/src/movie.cpp b/src/movie.cpp index a6f874ae..ed9c9aa2 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -984,7 +984,7 @@ static int _currCommand = 0; //either dumps the current joystick state or loads one state from the movie void FCEUMOV_AddInputState() { - #ifdef _WIN32 +#ifdef _WIN32 if(movieMode == MOVIEMODE_TASEDIT) { // if movie length is less than currFrame, pad it with empty frames @@ -992,7 +992,7 @@ void FCEUMOV_AddInputState() currMovieData.insertEmpty(-1, 1 + currFrameCounter - (int)currMovieData.records.size()); MovieRecord* mr = &currMovieData.records[currFrameCounter]; - if(movie_readonly || turbo || pauseframe > currFrameCounter) + if(movie_readonly || turbo || playback.pause_frame > currFrameCounter) { // do not record buttons if(mr->command_reset()) @@ -1008,10 +1008,11 @@ void FCEUMOV_AddInputState() // record buttons joyports[0].log(mr); joyports[1].log(mr); - recorder.InputChangedRec(); + recorder.InputChanged(); } + _currCommand = 0; } else - #endif +#endif if(movieMode == MOVIEMODE_PLAY) { //stop when we run out of frames diff --git a/vc/vc10_fceux.vcxproj b/vc/vc10_fceux.vcxproj index 903c13c8..c143362e 100644 --- a/vc/vc10_fceux.vcxproj +++ b/vc/vc10_fceux.vcxproj @@ -429,6 +429,7 @@ + @@ -749,6 +750,7 @@ + diff --git a/vc/vc10_fceux.vcxproj.filters b/vc/vc10_fceux.vcxproj.filters index 626fb3a9..17424f28 100644 --- a/vc/vc10_fceux.vcxproj.filters +++ b/vc/vc10_fceux.vcxproj.filters @@ -937,6 +937,7 @@ drivers\win\taseditlib + @@ -1408,6 +1409,7 @@ drivers\win\taseditlib +