* Tasedit: more refactoring

* Tasedit: "<<" and ">>" buttons now jump from one Marker to another
* Tasedit: clever FollowSelection
This commit is contained in:
ansstuff 2011-10-15 20:20:22 +00:00
parent 07dde626de
commit 0e48de6f98
15 changed files with 320 additions and 138 deletions

View File

@ -62,7 +62,7 @@ HWND hwndHistoryList;
WNDPROC hwndHistoryList_oldWndProc; WNDPROC hwndHistoryList_oldWndProc;
HWND hwndBookmarksList, hwndBookmarks; HWND hwndBookmarksList, hwndBookmarks;
WNDPROC hwndBookmarksList_oldWndProc; WNDPROC hwndBookmarksList_oldWndProc;
HWND hwndProgressbar, hwndRewind, hwndForward; HWND hwndProgressbar, hwndRewind, hwndForward, hwndRewindFull, hwndForwardFull;
HWND hwndRB_RecOff, hwndRB_RecAll, hwndRB_Rec1P, hwndRB_Rec2P, hwndRB_Rec3P, hwndRB_Rec4P; HWND hwndRB_RecOff, hwndRB_RecAll, hwndRB_Rec1P, hwndRB_Rec2P, hwndRB_Rec3P, hwndRB_Rec4P;
@ -78,7 +78,7 @@ TASEDIT_PROJECT project;
INPUT_HISTORY history; INPUT_HISTORY history;
PLAYBACK playback; PLAYBACK playback;
GREENZONE greenzone; GREENZONE greenzone;
MARKERS markers;
void GetDispInfo(NMLVDISPINFO* nmlvDispInfo) void GetDispInfo(NMLVDISPINFO* nmlvDispInfo)
{ {
@ -162,18 +162,18 @@ LONG CustomDraw(NMLVCUSTOMDRAW* msg)
} else if (cell_y == currFrameCounter || cell_y == playback.GetPauseFrame()) } else if (cell_y == currFrameCounter || cell_y == playback.GetPauseFrame())
{ {
// current frame // current frame
if(TASEdit_show_markers && currMovieData.frames_flags[cell_y] & MARKER_FLAG_BIT) if(TASEdit_show_markers && (markers.markers_array[cell_y] & MARKER_FLAG_BIT))
// this frame is also marked // this frame is also marked
msg->clrTextBk = CUR_MARKED_FRAMENUM_COLOR; msg->clrTextBk = CUR_MARKED_FRAMENUM_COLOR;
else else
msg->clrTextBk = CUR_FRAMENUM_COLOR; msg->clrTextBk = CUR_FRAMENUM_COLOR;
} else if(TASEdit_show_markers && currMovieData.frames_flags[cell_y] & MARKER_FLAG_BIT) } else if(TASEdit_show_markers && (markers.markers_array[cell_y] & MARKER_FLAG_BIT))
{ {
// marked frame // marked frame
msg->clrTextBk = MARKED_FRAMENUM_COLOR; msg->clrTextBk = MARKED_FRAMENUM_COLOR;
} else if(cell_y < greenzone.greenZoneCount && !greenzone.savestates[cell_y].empty()) } else if(cell_y < greenzone.greenZoneCount && !greenzone.savestates[cell_y].empty())
{ {
if (TASEdit_show_lag_frames && (currMovieData.frames_flags[cell_y] & LAG_FLAG_BIT)) if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
{ {
// lag frame // lag frame
msg->clrTextBk = LAG_FRAMENUM_COLOR; msg->clrTextBk = LAG_FRAMENUM_COLOR;
@ -196,7 +196,7 @@ LONG CustomDraw(NMLVCUSTOMDRAW* msg)
msg->clrTextBk = CUR_INPUT_COLOR1; msg->clrTextBk = CUR_INPUT_COLOR1;
} else if(cell_y < greenzone.greenZoneCount && !greenzone.savestates[cell_y].empty()) } else if(cell_y < greenzone.greenZoneCount && !greenzone.savestates[cell_y].empty())
{ {
if (TASEdit_show_lag_frames && (currMovieData.frames_flags[cell_y] & LAG_FLAG_BIT)) if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
{ {
// lag frame // lag frame
msg->clrTextBk = LAG_INPUT_COLOR1; msg->clrTextBk = LAG_INPUT_COLOR1;
@ -219,7 +219,7 @@ LONG CustomDraw(NMLVCUSTOMDRAW* msg)
msg->clrTextBk = CUR_INPUT_COLOR2; msg->clrTextBk = CUR_INPUT_COLOR2;
} else if(cell_y < greenzone.greenZoneCount && !greenzone.savestates[cell_y].empty()) } else if(cell_y < greenzone.greenZoneCount && !greenzone.savestates[cell_y].empty())
{ {
if (TASEdit_show_lag_frames && (currMovieData.frames_flags[cell_y] & LAG_FLAG_BIT)) if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
{ {
// lag frame // lag frame
msg->clrTextBk = LAG_INPUT_COLOR2; msg->clrTextBk = LAG_INPUT_COLOR2;
@ -288,6 +288,8 @@ void UpdateList()
} }
} }
} }
// also update number of items in markers array
markers.update();
} }
void RedrawWindowCaption() void RedrawWindowCaption()
@ -426,13 +428,10 @@ void SingleClick(LPNMITEMACTIVATE info)
if (info->uKeyFlags & LVKF_ALT) if (info->uKeyFlags & LVKF_ALT)
{ {
// reverse MARKER_FLAG_BIT in pointed frame // reverse MARKER_FLAG_BIT in pointed frame
if (currMovieData.frames_flags[row_index] & MARKER_FLAG_BIT) markers.ToggleMarker(row_index);
currMovieData.frames_flags[row_index] &= ~MARKER_FLAG_BIT;
else
currMovieData.frames_flags[row_index] |= MARKER_FLAG_BIT;
MarkersChanged(); MarkersChanged();
ListView_SetItemState(hwndList,row_index,0,LVIS_SELECTED); // deselect this row, so that new marker will be seen immediately
//RedrawList(); ListView_SetItemState(hwndList, row_index, 0, LVIS_SELECTED);
} }
} }
else if(column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R) else if(column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R)
@ -464,7 +463,6 @@ void CloneFrames()
int frames = selectionFrames.size(); int frames = selectionFrames.size();
currMovieData.records.reserve(currMovieData.getNumRecords() + frames); currMovieData.records.reserve(currMovieData.getNumRecords() + frames);
currMovieData.frames_flags.reserve(currMovieData.getNumRecords() + frames);
//insert frames before each selection, but consecutive selection lines are accounted as single region //insert frames before each selection, but consecutive selection lines are accounted as single region
frames = 1; frames = 1;
@ -476,7 +474,9 @@ void CloneFrames()
if (next_it == selectionFrames.rend() || (int)*next_it < ((int)*it - 1)) if (next_it == selectionFrames.rend() || (int)*next_it < ((int)*it - 1))
{ {
// end of current region // end of current region
currMovieData.cloneRegion(*it,frames); currMovieData.cloneRegion(*it, frames);
if (TASEdit_bind_markers)
markers.insertEmpty(*it, frames);
frames = 1; frames = 1;
} else frames++; } else frames++;
} }
@ -488,11 +488,8 @@ void InsertFrames()
{ {
int frames = selectionFrames.size(); int frames = selectionFrames.size();
//this is going to be slow.
//to keep this from being even slower than it would otherwise be, go ahead and reserve records //to keep this from being even slower than it would otherwise be, go ahead and reserve records
currMovieData.records.reserve(currMovieData.getNumRecords() + frames); currMovieData.records.reserve(currMovieData.getNumRecords() + frames);
currMovieData.frames_flags.reserve(currMovieData.getNumRecords() + frames);
//insert frames before each selection, but consecutive selection lines are accounted as single region //insert frames before each selection, but consecutive selection lines are accounted as single region
frames = 1; frames = 1;
@ -505,6 +502,8 @@ void InsertFrames()
{ {
// end of current region // end of current region
currMovieData.insertEmpty(*it,frames); currMovieData.insertEmpty(*it,frames);
if (TASEdit_bind_markers)
markers.insertEmpty(*it,frames);
frames = 1; frames = 1;
} else frames++; } else frames++;
} }
@ -521,7 +520,7 @@ void DeleteFrames()
{ {
currMovieData.records.erase(currMovieData.records.begin() + *it); currMovieData.records.erase(currMovieData.records.begin() + *it);
if (TASEdit_bind_markers) if (TASEdit_bind_markers)
currMovieData.frames_flags.erase(currMovieData.frames_flags.begin() + *it); markers.markers_array.erase(markers.markers_array.begin() + *it);
} }
// check if user deleted all frames // check if user deleted all frames
if (!currMovieData.getNumRecords()) if (!currMovieData.getNumRecords())
@ -529,7 +528,14 @@ void DeleteFrames()
// reduce list // reduce list
UpdateList(); UpdateList();
greenzone.InvalidateGreenZone(history.RegisterInputChanges(MODTYPE_DELETE, start_index)); int result = history.RegisterInputChanges(MODTYPE_DELETE, start_index);
if (result >= 0)
{
greenzone.InvalidateGreenZone(result);
} else if (greenzone.greenZoneCount >= currMovieData.getNumRecords())
{
greenzone.InvalidateGreenZone(currMovieData.getNumRecords()-1);
} else RedrawList();
} }
void ClearFrames(bool cut) void ClearFrames(bool cut)
@ -557,7 +563,14 @@ void Truncate()
{ {
currMovieData.truncateAt(frame+1); currMovieData.truncateAt(frame+1);
UpdateList(); UpdateList();
greenzone.InvalidateGreenZone(history.RegisterInputChanges(MODTYPE_TRUNCATE, frame+1)); int result = history.RegisterInputChanges(MODTYPE_TRUNCATE, frame+1);
if (result >= 0)
{
greenzone.InvalidateGreenZone(result);
} else if (greenzone.greenZoneCount >= currMovieData.getNumRecords())
{
greenzone.InvalidateGreenZone(currMovieData.getNumRecords()-1);
} else RedrawList();
} }
} }
@ -571,7 +584,7 @@ void ColumnSet(int column)
bool unset_found = false; bool unset_found = false;
for(TSelectionFrames::iterator it(selectionFrames.begin()); it != selectionFrames.end(); it++) for(TSelectionFrames::iterator it(selectionFrames.begin()); it != selectionFrames.end(); it++)
{ {
if(!(currMovieData.frames_flags[*it] & MARKER_FLAG_BIT)) if(!(markers.markers_array[*it] & MARKER_FLAG_BIT))
{ {
unset_found = true; unset_found = true;
break; break;
@ -581,12 +594,12 @@ void ColumnSet(int column)
{ {
// set all // set all
for(TSelectionFrames::iterator it(selectionFrames.begin()); it != selectionFrames.end(); it++) for(TSelectionFrames::iterator it(selectionFrames.begin()); it != selectionFrames.end(); it++)
currMovieData.frames_flags[*it] |= MARKER_FLAG_BIT; markers.markers_array[*it] |= MARKER_FLAG_BIT;
} else } else
{ {
// unset all // unset all
for(TSelectionFrames::iterator it(selectionFrames.begin()); it != selectionFrames.end(); it++) for(TSelectionFrames::iterator it(selectionFrames.begin()); it != selectionFrames.end(); it++)
currMovieData.frames_flags[*it] &= ~MARKER_FLAG_BIT; markers.markers_array[*it] &= ~MARKER_FLAG_BIT;
} }
MarkersChanged(); MarkersChanged();
ClearSelection(); ClearSelection();
@ -647,10 +660,10 @@ void SelectMidMarkers()
// find markers // find markers
// searching up starting from center-0 // searching up starting from center-0
for (upper_marker = center; upper_marker >= 0; upper_marker--) for (upper_marker = center; upper_marker >= 0; upper_marker--)
if (currMovieData.frames_flags[upper_marker] & MARKER_FLAG_BIT) break; if (markers.markers_array[upper_marker] & MARKER_FLAG_BIT) break;
// searching down starting from center+1 // searching down starting from center+1
for (lower_marker = center+1; lower_marker < movie_size; ++lower_marker) for (lower_marker = center+1; lower_marker < movie_size; ++lower_marker)
if (currMovieData.frames_flags[lower_marker] & MARKER_FLAG_BIT) break; if (markers.markers_array[lower_marker] & MARKER_FLAG_BIT) break;
if (upper_marker == -1 && lower_marker == movie_size) if (upper_marker == -1 && lower_marker == movie_size)
{ {
@ -1230,6 +1243,8 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
SendMessage(hwndProgressbar, PBM_SETRANGE, 0, MAKELPARAM(0, PROGRESSBAR_WIDTH)); SendMessage(hwndProgressbar, PBM_SETRANGE, 0, MAKELPARAM(0, PROGRESSBAR_WIDTH));
hwndRewind = GetDlgItem(hwndDlg, TASEDIT_REWIND); hwndRewind = GetDlgItem(hwndDlg, TASEDIT_REWIND);
hwndForward = GetDlgItem(hwndDlg, TASEDIT_FORWARD); hwndForward = GetDlgItem(hwndDlg, TASEDIT_FORWARD);
hwndRewindFull = GetDlgItem(hwndDlg, TASEDIT_REWIND_FULL);
hwndForwardFull = GetDlgItem(hwndDlg, TASEDIT_FORWARD_FULL);
hwndRB_RecOff = GetDlgItem(hwndDlg, IDC_RADIO1); hwndRB_RecOff = GetDlgItem(hwndDlg, IDC_RADIO1);
hwndRB_RecAll = GetDlgItem(hwndDlg, IDC_RADIO2); hwndRB_RecAll = GetDlgItem(hwndDlg, IDC_RADIO2);
hwndRB_Rec1P = GetDlgItem(hwndDlg, IDC_RADIO3); hwndRB_Rec1P = GetDlgItem(hwndDlg, IDC_RADIO3);
@ -1399,12 +1414,16 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
{ {
// insert at selection // insert at selection
int index = *selectionFrames.begin(); int index = *selectionFrames.begin();
currMovieData.insertEmpty(index,frames); currMovieData.insertEmpty(index, frames);
if (TASEdit_bind_markers)
markers.insertEmpty(index, frames);
greenzone.InvalidateGreenZone(history.RegisterInputChanges(MODTYPE_INSERT, index)); greenzone.InvalidateGreenZone(history.RegisterInputChanges(MODTYPE_INSERT, index));
} else } else
{ {
// insert at playback cursor // insert at playback cursor
currMovieData.insertEmpty(currFrameCounter,frames); currMovieData.insertEmpty(currFrameCounter, frames);
if (TASEdit_bind_markers)
markers.insertEmpty(currFrameCounter, frames);
greenzone.InvalidateGreenZone(history.RegisterInputChanges(MODTYPE_INSERT, currFrameCounter)); greenzone.InvalidateGreenZone(history.RegisterInputChanges(MODTYPE_INSERT, currFrameCounter));
} }
} }
@ -1421,15 +1440,9 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
case ID_CONTEXT_SELECTED_CLEARFRAMES: case ID_CONTEXT_SELECTED_CLEARFRAMES:
if (selectionFrames.size()) ClearFrames(); if (selectionFrames.size()) ClearFrames();
break; break;
case TASEDIT_REWIND_FULL:
playback.RewindFull();
break;
case TASEDIT_PLAYSTOP: case TASEDIT_PLAYSTOP:
playback.ToggleEmulationPause(); playback.ToggleEmulationPause();
break; break;
case TASEDIT_FORWARD_FULL:
playback.ForwardFull();
break;
case ACCEL_CTRL_F: case ACCEL_CTRL_F:
case CHECK_FOLLOW_CURSOR: case CHECK_FOLLOW_CURSOR:
//switch "Follow playback" flag //switch "Follow playback" flag
@ -1439,7 +1452,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
if (TASEdit_follow_playback) if (TASEdit_follow_playback)
FollowPlayback(); FollowPlayback();
else if (selectionFrames.size()) else if (selectionFrames.size())
ListView_EnsureVisible(hwndList,(int)*selectionFrames.begin(),FALSE); FollowSelection();
break; break;
case ID_VIEW_SHOW_LAG_FRAMES: case ID_VIEW_SHOW_LAG_FRAMES:
//switch "Highlight lag frames" flag //switch "Highlight lag frames" flag
@ -1619,6 +1632,43 @@ void FollowUndo()
} }
} }
} }
void FollowSelection()
{
int list_items = listItems;
if (currMovieData.fourscore) list_items--;
int selection_start = *selectionFrames.begin();
int selection_end = *selectionFrames.rbegin();
int selection_items = 1 + selection_end - selection_start;
if (selection_items <= list_items)
{
// selected region can fit in screen
int lower_border = (list_items - selection_items) / 2;
int upper_border = (list_items - selection_items) - lower_border;
int index = selection_end + lower_border;
if (index >= currMovieData.getNumRecords())
index = currMovieData.getNumRecords()-1;
ListView_EnsureVisible(hwndList, index, false);
index = selection_start - upper_border;
if (index < 0)
index = 0;
ListView_EnsureVisible(hwndList, index, false);
} else
{
// selected region is too big to fit in screen
// just center at selection_start
int lower_border = (list_items - 1) / 2;
int upper_border = (list_items - 1) - lower_border;
int index = selection_start + lower_border;
if (index >= currMovieData.getNumRecords())
index = currMovieData.getNumRecords()-1;
ListView_EnsureVisible(hwndList, index, false);
index = selection_start - upper_border;
if (index < 0)
index = 0;
ListView_EnsureVisible(hwndList, index, false);
}
}
void EnterTasEdit() void EnterTasEdit()
{ {
@ -1661,7 +1711,6 @@ void EnterTasEdit()
SetWindowPos(hwndTasEdit,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER); SetWindowPos(hwndTasEdit,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
playback.init(); playback.init();
greenzone.init();
// either start new movie or use current movie // either start new movie or use current movie
if (movieMode == MOVIEMODE_INACTIVE) if (movieMode == MOVIEMODE_INACTIVE)
{ {
@ -1731,10 +1780,12 @@ void EnterTasEdit()
ListView_InsertColumn(hwndHistoryList, 0, &lvc); ListView_InsertColumn(hwndHistoryList, 0, &lvc);
// init variables // init variables
greenzone.init();
greenzone.TryDumpIncremental(lagFlag != 0);
markers.init();
project.init(); project.init();
history.init(TasEdit_undo_levels); history.init(TasEdit_undo_levels);
SetFocus(hwndHistoryList); SetFocus(hwndHistoryList);
greenzone.TryDumpIncremental(lagFlag != 0);
FCEU_DispMessage("Tasedit engaged",0); FCEU_DispMessage("Tasedit engaged",0);
} }
} }
@ -1757,6 +1808,7 @@ bool ExitTasEdit()
KeyboardClearBackgroundAccessBit(KEYBACKACCESS_TASEDIT); KeyboardClearBackgroundAccessBit(KEYBACKACCESS_TASEDIT);
JoystickClearBackgroundAccessBit(JOYBACKACCESS_TASEDIT); JoystickClearBackgroundAccessBit(JOYBACKACCESS_TASEDIT);
// release memory // release memory
markers.free();
greenzone.clearGreenzone(); greenzone.clearGreenzone();
history.free(); history.free();

View File

@ -83,6 +83,7 @@ void InputChangedRec();
bool CheckItemVisible(int frame); bool CheckItemVisible(int frame);
void FollowPlayback(); void FollowPlayback();
void FollowUndo(); void FollowUndo();
void FollowSelection();
void ClearSelection(); void ClearSelection();
void ClearRowSelection(int index); void ClearRowSelection(int index);
void AddFourscore(); void AddFourscore();

View File

@ -10,7 +10,6 @@
extern TASEDIT_PROJECT project; extern TASEDIT_PROJECT project;
extern PLAYBACK playback; extern PLAYBACK playback;
extern int TASEdit_greenzone_capacity; extern int TASEdit_greenzone_capacity;
extern bool TASEdit_bind_markers;
extern bool TASEdit_restore_position; extern bool TASEdit_restore_position;
extern void FCEU_printf(char *format, ...); extern void FCEU_printf(char *format, ...);
@ -24,11 +23,11 @@ void GREENZONE::init()
{ {
clearGreenzone(); clearGreenzone();
currMovieData.frames_flags.resize(currMovieData.records.size());
reset(); reset();
} }
void GREENZONE::reset() void GREENZONE::reset()
{ {
lag_history.resize(currMovieData.getNumRecords());
} }
void GREENZONE::update() void GREENZONE::update()
@ -40,16 +39,16 @@ void GREENZONE::update()
void GREENZONE::TryDumpIncremental(bool lagFlag) void GREENZONE::TryDumpIncremental(bool lagFlag)
{ {
// if movie length is less than currFrame, pad it with empty frames // if movie length is less than currFrame, pad it with empty frames
if((int)currMovieData.records.size() <= currFrameCounter) if(currMovieData.getNumRecords() <= currFrameCounter)
currMovieData.insertEmpty(-1, 1 + currFrameCounter - (int)currMovieData.records.size()); currMovieData.insertEmpty(-1, 1 + currFrameCounter - currMovieData.getNumRecords());
// update greenzone upper limit // update greenzone upper limit
if (greenZoneCount <= currFrameCounter) if (greenZoneCount <= currFrameCounter)
greenZoneCount = currFrameCounter+1; greenZoneCount = currFrameCounter+1;
if ((int)savestates.size() < greenZoneCount) if ((int)savestates.size() < greenZoneCount)
savestates.resize(greenZoneCount); savestates.resize(greenZoneCount);
if ((int)currMovieData.frames_flags.size() < greenZoneCount) if ((int)lag_history.size() < greenZoneCount)
currMovieData.frames_flags.resize(greenZoneCount); lag_history.resize(greenZoneCount);
// if frame changed - log savestate // if frame changed - log savestate
storeTasSavestate(currFrameCounter); storeTasSavestate(currFrameCounter);
@ -58,9 +57,9 @@ void GREENZONE::TryDumpIncremental(bool lagFlag)
{ {
// lagFlag indicates that lag was in previous frame // lagFlag indicates that lag was in previous frame
if (lagFlag) if (lagFlag)
currMovieData.frames_flags[currFrameCounter-1] |= LAG_FLAG_BIT; lag_history[currFrameCounter-1] = 1;
else else
currMovieData.frames_flags[currFrameCounter-1] &= ~LAG_FLAG_BIT; lag_history[currFrameCounter-1] = 0;
} }
@ -70,7 +69,7 @@ void GREENZONE::TryDumpIncremental(bool lagFlag)
bool GREENZONE::loadTasSavestate(int frame) bool GREENZONE::loadTasSavestate(int frame)
{ {
if (frame < 0 || frame >= (int)currMovieData.records.size()) if (frame < 0 || frame >= currMovieData.getNumRecords())
return false; return false;
if ((int)savestates.size() <= frame || savestates[frame].empty()) if ((int)savestates.size() <= frame || savestates[frame].empty())
return false; return false;
@ -119,15 +118,14 @@ void GREENZONE::clearGreenzone()
} }
savestates.resize(0); savestates.resize(0);
greenZoneCount = 0; greenZoneCount = 0;
currMovieData.frames_flags.resize(0); lag_history.resize(0);
// reset lua_colorings // reset lua_colorings
// reset monitorings // reset monitorings
} }
int GREENZONE::dumpGreenzone(EMUFILE *os) void GREENZONE::save(EMUFILE *os)
{ {
int start = os->ftell();
int frame, size; int frame, size;
int last_tick = 0; int last_tick = 0;
// write size // write size
@ -144,8 +142,8 @@ int GREENZONE::dumpGreenzone(EMUFILE *os)
} }
if (savestates[frame].empty()) continue; if (savestates[frame].empty()) continue;
write32le(frame, os); write32le(frame, os);
// write frames_flags // write lag history
os->fwrite(&currMovieData.frames_flags[frame], 1); write8le(lag_history[frame], os);
// write lua_colorings // write lua_colorings
// write monitorings // write monitorings
// write savestate // write savestate
@ -156,19 +154,15 @@ int GREENZONE::dumpGreenzone(EMUFILE *os)
} }
// write -1 as eof for greenzone // write -1 as eof for greenzone
write32le(-1, os); write32le(-1, os);
int end = os->ftell();
return end-start;
} }
bool GREENZONE::load(EMUFILE *is)
bool GREENZONE::loadGreenzone(EMUFILE *is)
{ {
clearGreenzone(); clearGreenzone();
currMovieData.frames_flags.resize(currMovieData.records.size()); lag_history.resize(currMovieData.getNumRecords());
int frame = 0, prev_frame = 0, size = 0; int frame = 0, prev_frame = 0, size = 0;
int last_tick = 0; int last_tick = 0;
// read size // read size
if (read32le((uint32 *)&size, is) && size >= 0 && size <= (int)currMovieData.records.size()) if (read32le((uint32 *)&size, is) && size >= 0 && size <= currMovieData.getNumRecords())
{ {
greenZoneCount = size; greenZoneCount = size;
savestates.resize(greenZoneCount); savestates.resize(greenZoneCount);
@ -187,8 +181,8 @@ bool GREENZONE::loadGreenzone(EMUFILE *is)
playback.SetProgressbar(frame, greenZoneCount); playback.SetProgressbar(frame, greenZoneCount);
last_tick = frame / PROGRESSBAR_UPDATE_RATE; last_tick = frame / PROGRESSBAR_UPDATE_RATE;
} }
// read frames_flags // read lag history
if ((int)is->fread(&currMovieData.frames_flags[frame],1) != 1) break; if (!read8le(&lag_history[frame], is)) break;
// read lua_colorings // read lua_colorings
// read monitorings // read monitorings
// read savestate // read savestate
@ -223,19 +217,21 @@ error:
void GREENZONE::InvalidateGreenZone(int after) void GREENZONE::InvalidateGreenZone(int after)
{ {
if (after < 0) return; if (after >= 0)
project.changed = true;
if (greenZoneCount > after+1)
{ {
greenZoneCount = after+1; project.changed = true;
currMovieData.rerecordCount++; if (greenZoneCount > after+1)
// either set playback cursor to the end of greenzone or run seeking to restore playback position
if (currFrameCounter >= greenZoneCount)
{ {
if (TASEdit_restore_position) greenZoneCount = after+1;
playback.restorePosition(); currMovieData.rerecordCount++;
else // either set playback cursor to the end of greenzone or run seeking to restore playback position
playback.jump(greenZoneCount-1); if (currFrameCounter >= greenZoneCount)
{
if (TASEdit_restore_position)
playback.restorePosition();
else
playback.jump(greenZoneCount-1);
}
} }
} }
// redraw list even if greenzone didn't change // redraw list even if greenzone didn't change

View File

@ -1,5 +1,6 @@
//Specification file for Greenzone class //Specification file for Greenzone class
//#define LAG_FLAG_BIT 1
class GREENZONE class GREENZONE
{ {
@ -9,11 +10,11 @@ public:
void reset(); void reset();
void update(); void update();
void TryDumpIncremental(bool lagFlag = true); void save(EMUFILE *os);
bool load(EMUFILE *is);
void clearGreenzone(); void clearGreenzone();
int dumpGreenzone(EMUFILE *os); void TryDumpIncremental(bool lagFlag = true);
bool loadGreenzone(EMUFILE *is);
bool loadTasSavestate(int frame); bool loadTasSavestate(int frame);
void storeTasSavestate(int frame); void storeTasSavestate(int frame);
@ -27,6 +28,7 @@ public:
// data // data
int greenZoneCount; int greenZoneCount;
std::vector<std::vector<uint8>> savestates; std::vector<std::vector<uint8>> savestates;
std::vector<uint8> lag_history;
private: private:

View File

@ -57,7 +57,6 @@ void INPUT_SNAPSHOT::toMovie(MovieData& md, int start)
{ {
// write input data to movie data // write input data to movie data
md.records.resize(size); md.records.resize(size);
md.frames_flags.resize(size);
switch(input_type) switch(input_type)
{ {
case FOURSCORE: case FOURSCORE:

View File

@ -0,0 +1,70 @@
//Implementation file of Markers class
#include "movie.h"
#include "../common.h"
#include "taseditproj.h"
//#include "../tasedit.h"
MARKERS::MARKERS()
{
}
void MARKERS::init()
{
free();
update();
}
void MARKERS::free()
{
markers_array.resize(0);
}
void MARKERS::update()
{
if (markers_array.size() < currMovieData.getNumRecords())
markers_array.resize(currMovieData.getNumRecords());
}
void MARKERS::save(EMUFILE *os)
{
// write size
int size = markers_array.size();
write32le(size, os);
// write array
os->fwrite(markers_array.data(), size);
}
bool MARKERS::load(EMUFILE *is)
{
markers_array.resize(currMovieData.getNumRecords());
int size;
if (read32le((uint32 *)&size, is) && size == currMovieData.getNumRecords())
{
// read array
if ((int)is->fread(markers_array.data(), size) == size) return true;
}
error:
FCEU_printf("Error loading markers\n");
return false;
}
// ----------------------------------------------------------
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;
}
void MARKERS::insertEmpty(int at, int frames)
{
if(at == -1)
{
markers_array.resize(markers_array.size() + frames);
} else
{
markers_array.insert(markers_array.begin() + at, frames, 0);
}
}

View File

@ -0,0 +1,23 @@
//Specification file for Markers class
#define MARKER_FLAG_BIT 1
class MARKERS
{
public:
MARKERS();
void init();
void free();
void update();
void save(EMUFILE *os);
bool load(EMUFILE *is);
void ToggleMarker(int frame);
void insertEmpty(int at, int frames);
std::vector<uint8> markers_array;
private:
};

View File

@ -9,9 +9,10 @@
extern void ForceExecuteLuaFrameFunctions(); extern void ForceExecuteLuaFrameFunctions();
#endif #endif
extern HWND hwndProgressbar, hwndList, hwndRewind, hwndForward; extern HWND hwndProgressbar, hwndList, hwndRewind, hwndForward, hwndRewindFull, hwndForwardFull;
extern void FCEU_printf(char *format, ...); extern void FCEU_printf(char *format, ...);
extern bool turbo; extern bool turbo;
extern MARKERS markers;
extern GREENZONE greenzone; extern GREENZONE greenzone;
extern bool Tasedit_rewind_now; extern bool Tasedit_rewind_now;
@ -32,6 +33,8 @@ void PLAYBACK::reset()
old_show_pauseframe = show_pauseframe = false; old_show_pauseframe = show_pauseframe = false;
old_rewind_button_state = rewind_button_state = false; old_rewind_button_state = rewind_button_state = false;
old_forward_button_state = forward_button_state = false; old_forward_button_state = forward_button_state = false;
old_rewind_full_button_state = rewind_full_button_state = false;
old_forward_full_button_state = forward_full_button_state = false;
old_emu_paused = emu_paused = true; old_emu_paused = emu_paused = true;
SeekingStop(); SeekingStop();
} }
@ -42,23 +45,6 @@ void PLAYBACK::update()
if(pauseframe && pauseframe <= currFrameCounter + 1) if(pauseframe && pauseframe <= currFrameCounter + 1)
SeekingStop(); SeekingStop();
// update seeking progressbar
old_emu_paused = emu_paused;
emu_paused = (FCEUI_EmulationPaused() != 0);
if (pauseframe && !emu_paused)
{
SetProgressbar(currFrameCounter - seeking_start_frame, pauseframe-seeking_start_frame);
} else if (old_emu_paused != emu_paused)
{
// emulator got paused/unpaused externally
if (old_emu_paused && !emu_paused)
// externally unpaused - progressbar should be empty
SetProgressbar(0, 1);
else
// externally paused - progressbar should be full
SetProgressbar(1, 1);
}
// update flashing pauseframe // update flashing pauseframe
if (old_pauseframe != pauseframe && old_pauseframe) RedrawRow(old_pauseframe-1); if (old_pauseframe != pauseframe && old_pauseframe) RedrawRow(old_pauseframe-1);
old_pauseframe = pauseframe; old_pauseframe = pauseframe;
@ -72,6 +58,24 @@ void PLAYBACK::update()
} else show_pauseframe = false; } else show_pauseframe = false;
if (old_show_pauseframe != show_pauseframe) RedrawRow(pauseframe-1); if (old_show_pauseframe != show_pauseframe) RedrawRow(pauseframe-1);
// update seeking progressbar
old_emu_paused = emu_paused;
emu_paused = (FCEUI_EmulationPaused() != 0);
if (pauseframe)
{
if (old_show_pauseframe != show_pauseframe)
SetProgressbar(currFrameCounter - seeking_start_frame, pauseframe-seeking_start_frame);
} else if (old_emu_paused != emu_paused)
{
// emulator got paused/unpaused externally
if (old_emu_paused && !emu_paused)
// externally unpaused - progressbar should be empty
SetProgressbar(0, 1);
else
// externally paused - progressbar should be full
SetProgressbar(1, 1);
}
//update the playback cursor //update the playback cursor
if(currFrameCounter != lastCursor) if(currFrameCounter != lastCursor)
{ {
@ -113,6 +117,34 @@ void PLAYBACK::update()
} }
} }
} }
// update << and >> buttons
old_rewind_full_button_state = rewind_full_button_state;
rewind_full_button_state = ((Button_GetState(hwndRewindFull) & BST_PUSHED) != 0);
if (rewind_full_button_state && !rewind_button_state && !forward_button_state)
{
if (!old_rewind_full_button_state)
{
button_hold_time = clock();
RewindFull();
} else if (button_hold_time + HOLD_REPEAT_DELAY < clock())
{
RewindFull();
}
}
old_forward_full_button_state = forward_full_button_state;
forward_full_button_state = (Button_GetState(hwndForwardFull) & BST_PUSHED) != 0;
if (forward_full_button_state && !rewind_button_state && !forward_button_state && !rewind_full_button_state)
{
if (!old_forward_full_button_state)
{
button_hold_time = clock();
ForwardFull();
} else if (button_hold_time + HOLD_REPEAT_DELAY < clock())
{
ForwardFull();
}
}
} }
void PLAYBACK::updateProgressbar() void PLAYBACK::updateProgressbar()
@ -176,14 +208,33 @@ void PLAYBACK::ForwardFrame()
} }
void PLAYBACK::RewindFull() void PLAYBACK::RewindFull()
{ {
// rewind to the beginning of greenzone // jump to previous marker
jump(greenzone.FindBeginningOfGreenZone()); 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);
}
FollowPlayback(); FollowPlayback();
} }
void PLAYBACK::ForwardFull() void PLAYBACK::ForwardFull()
{ {
// move to the end of greenzone // jump to next marker
jump(greenzone.greenZoneCount-1); 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);
}
FollowPlayback(); FollowPlayback();
} }

View File

@ -47,6 +47,8 @@ private:
bool old_show_pauseframe, show_pauseframe; bool old_show_pauseframe, show_pauseframe;
bool old_rewind_button_state, rewind_button_state; bool old_rewind_button_state, rewind_button_state;
bool old_forward_button_state, forward_button_state; bool old_forward_button_state, forward_button_state;
bool old_rewind_full_button_state, rewind_full_button_state;
bool old_forward_full_button_state, forward_full_button_state;
int button_hold_time; int button_hold_time;
int seeking_start_frame; int seeking_start_frame;

View File

@ -3,9 +3,10 @@
#include "../main.h" #include "../main.h"
#include "taseditproj.h" #include "taseditproj.h"
extern INPUT_HISTORY history; extern MARKERS markers;
extern PLAYBACK playback;
extern GREENZONE greenzone; extern GREENZONE greenzone;
extern PLAYBACK playback;
extern INPUT_HISTORY history;
extern void FCEU_printf(char *format, ...); extern void FCEU_printf(char *format, ...);
@ -42,11 +43,10 @@ bool TASEDIT_PROJECT::saveProject()
if (PFN.empty()) return false; if (PFN.empty()) return false;
const char* filename = PFN.c_str(); const char* filename = PFN.c_str();
EMUFILE_FILE* ofs = FCEUD_UTF8_fstream(filename,"wb"); EMUFILE_FILE* ofs = FCEUD_UTF8_fstream(filename,"wb");
//ofs << GetProjectName() << std::endl;
//ofs << GetFM2Name() << std::endl;
currMovieData.dump(ofs, true); currMovieData.dump(ofs, true);
greenzone.dumpGreenzone(ofs); markers.save(ofs);
greenzone.save(ofs);
history.save(ofs); history.save(ofs);
delete ofs; delete ofs;
@ -65,22 +65,25 @@ bool TASEDIT_PROJECT::LoadProject(std::string PFN)
EMUFILE_FILE ifs(filename, "rb"); EMUFILE_FILE ifs(filename, "rb");
FCEU_printf("Loading project %s\n", filename); FCEU_printf("Loading TASEdit project %s\n", filename);
LoadFM2(currMovieData, &ifs, ifs.size(), false); LoadFM2(currMovieData, &ifs, ifs.size(), false);
LoadSubtitles(currMovieData); LoadSubtitles(currMovieData);
// try to load markers
// try to load greenzone if (markers.load(&ifs))
if (!greenzone.loadGreenzone(&ifs))
{ {
// there was some error while loading greenzone - reset playback to frame 0 // try to load greenzone
poweron(true); if (greenzone.load(&ifs))
currFrameCounter = 0; {
// try to load history // there was some error while loading greenzone - reset playback to frame 0
history.load(&ifs); poweron(true);
currFrameCounter = 0;
// try to load history
history.load(&ifs);
}
} }
reset(); reset();
playback.updateProgressbar();
return true; return true;
} }
// ----------------------------------------------------------------- // -----------------------------------------------------------------

View File

@ -5,6 +5,7 @@
#include "inputhistory.h" #include "inputhistory.h"
#include "playback.h" #include "playback.h"
#include "greenzone.h" #include "greenzone.h"
#include "markers.h"
class TASEDIT_PROJECT class TASEDIT_PROJECT
{ {

View File

@ -109,7 +109,6 @@ void MovieData::clearRecordRange(int start, int len)
for(int i=0;i<len;i++) for(int i=0;i<len;i++)
{ {
records[i+start].clear(); records[i+start].clear();
frames_flags[i+start] = 0;
} }
} }
@ -118,20 +117,11 @@ void MovieData::insertEmpty(int at, int frames)
if(at == -1) if(at == -1)
{ {
int currcount = records.size(); int currcount = records.size();
records.resize(currcount+frames); records.resize(currcount + frames);
#ifdef WIN32 clearRecordRange(currcount, frames);
if (TASEdit_bind_markers) } else
#endif
frames_flags.resize(currcount+frames);
clearRecordRange(currcount,frames);
}
else
{ {
records.insert(records.begin()+at,frames,MovieRecord()); records.insert(records.begin() + at, frames, MovieRecord());
#ifdef WIN32
if (TASEdit_bind_markers)
#endif
frames_flags.insert(frames_flags.begin()+at,frames,0);
clearRecordRange(at,frames); clearRecordRange(at,frames);
} }
} }
@ -140,14 +130,10 @@ void MovieData::cloneRegion(int at, int frames)
{ {
if(at == -1) return; if(at == -1) return;
records.insert(records.begin()+at,frames,MovieRecord()); 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++) for(int i = 0; i < frames; i++)
records[i+at].Clone(records[i+at+frames]); records[i+at].Clone(records[i + at + frames]);
} }
MovieRecord::MovieRecord() MovieRecord::MovieRecord()
@ -601,7 +587,6 @@ static void LoadFM2_binarychunk(MovieData& movieData, EMUFILE* fp, int size)
numRecords=movieData.loadFrameCount; numRecords=movieData.loadFrameCount;
movieData.records.resize(numRecords); movieData.records.resize(numRecords);
movieData.frames_flags.resize(numRecords);
for(int i=0;i<numRecords;i++) for(int i=0;i<numRecords;i++)
{ {
movieData.records[i].parseBinary(&movieData,fp); movieData.records[i].parseBinary(&movieData,fp);
@ -673,7 +658,6 @@ bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader)
if (stopAfterHeader) return true; if (stopAfterHeader) return true;
int currcount = movieData.records.size(); int currcount = movieData.records.size();
movieData.records.resize(currcount+1); movieData.records.resize(currcount+1);
movieData.frames_flags.resize(currcount+1);
int preparse = fp->ftell(); int preparse = fp->ftell();
movieData.records[currcount].parse(&movieData, fp); movieData.records[currcount].parse(&movieData, fp);
int postparse = fp->ftell(); int postparse = fp->ftell();

View File

@ -1,9 +1,6 @@
#ifndef __MOVIE_H_ #ifndef __MOVIE_H_
#define __MOVIE_H_ #define __MOVIE_H_
#define LAG_FLAG_BIT 1
#define MARKER_FLAG_BIT 2
#define PROGRESSBAR_UPDATE_RATE 2000 // in frames of greenzone #define PROGRESSBAR_UPDATE_RATE 2000 // in frames of greenzone
#include <vector> #include <vector>
@ -178,7 +175,6 @@ public:
std::string romFilename; std::string romFilename;
std::vector<uint8> savestate; std::vector<uint8> savestate;
std::vector<MovieRecord> records; std::vector<MovieRecord> records;
std::vector<uint8> frames_flags;
std::vector<std::wstring> comments; std::vector<std::wstring> comments;
std::vector<std::string> subtitles; std::vector<std::string> subtitles;
//this is the RERECORD COUNT. please rename variable. //this is the RERECORD COUNT. please rename variable.

View File

@ -421,6 +421,7 @@
<ClCompile Include="..\src\drivers\win\taseditlib\greenzone.cpp" /> <ClCompile Include="..\src\drivers\win\taseditlib\greenzone.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\inputhistory.cpp" /> <ClCompile Include="..\src\drivers\win\taseditlib\inputhistory.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\inputsnapshot.cpp" /> <ClCompile Include="..\src\drivers\win\taseditlib\inputsnapshot.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\markers.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\playback.cpp" /> <ClCompile Include="..\src\drivers\win\taseditlib\playback.cpp" />
<ClCompile Include="..\src\drivers\win\texthook.cpp" /> <ClCompile Include="..\src\drivers\win\texthook.cpp" />
<ClCompile Include="..\src\drivers\win\throttle.cpp" /> <ClCompile Include="..\src\drivers\win\throttle.cpp" />

View File

@ -911,6 +911,7 @@
<ClCompile Include="..\src\drivers\win\taseditlib\inputsnapshot.cpp" /> <ClCompile Include="..\src\drivers\win\taseditlib\inputsnapshot.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\playback.cpp" /> <ClCompile Include="..\src\drivers\win\taseditlib\playback.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\greenzone.cpp" /> <ClCompile Include="..\src\drivers\win\taseditlib\greenzone.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\markers.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\src\cart.h"> <ClInclude Include="..\src\cart.h">