* Taseditor: fixed lag adjustments when dealing with previously unknown lag state

* Taseditor: crossing gaps in Icons by Alt + wheel
This commit is contained in:
ansstuff 2012-11-05 19:42:08 +00:00
parent 93e4b17993
commit c9bf79a8eb
11 changed files with 343 additions and 228 deletions

View File

@ -626,9 +626,13 @@ void Import()
strcat(name, ext); strcat(name, ext);
int result = history.RegisterImport(md, name); int result = history.RegisterImport(md, name);
if (result >= 0) if (result >= 0)
{
greenzone.InvalidateAndCheck(result); greenzone.InvalidateAndCheck(result);
else greenzone.laglog.InvalidateFrom(result);
} else
{
MessageBox(taseditor_window.hwndTasEditor, "Imported movie has the same Input.\nNo changes were made.", "TAS Editor", MB_OK); MessageBox(taseditor_window.hwndTasEditor, "Imported movie has the same Input.\nNo changes were made.", "TAS Editor", MB_OK);
}
} else } else
{ {
FCEUD_PrintError("Error loading movie data!"); FCEUD_PrintError("Error loading movie data!");

View File

@ -433,8 +433,6 @@ void BOOKMARKS::deploy(int slot)
// add empty frame at the end (at keyframe) // add empty frame at the end (at keyframe)
currMovieData.insertEmpty(-1, 1); currMovieData.insertEmpty(-1, 1);
} }
// revert Greenzone's LagLog to the Bookmarked state
greenzone.laglog = bookmarks_array[slot].snapshot.laglog;
int first_change = history.RegisterBranching(slot, markers_changed); int first_change = history.RegisterBranching(slot, markers_changed);
if (first_change >= 0) if (first_change >= 0)
@ -453,6 +451,13 @@ void BOOKMARKS::deploy(int slot)
// didn't change anything in current movie // didn't change anything in current movie
bookmarks_array[slot].jumped(); bookmarks_array[slot].jumped();
} }
// if Greenzone's LagLog size is less than Bookmarked LagLog size then replace it
if (greenzone.laglog.GetSize() < bookmarks_array[slot].snapshot.laglog.GetSize())
greenzone.laglog = bookmarks_array[slot].snapshot.laglog;
// but then also invalidate it after the point of difference
greenzone.laglog.InvalidateFrom(first_change);
// jump to the target (bookmarked frame) // jump to the target (bookmarked frame)
if (greenzone.SavestateIsEmpty(keyframe)) if (greenzone.SavestateIsEmpty(keyframe))
greenzone.WriteSavestate(keyframe, bookmarks_array[slot].savestate); greenzone.WriteSavestate(keyframe, bookmarks_array[slot].savestate);
@ -664,7 +669,7 @@ LONG BOOKMARKS::CustomDraw(NMLVCUSTOMDRAW* msg)
{ {
if (!greenzone.SavestateIsEmpty(frame)) if (!greenzone.SavestateIsEmpty(frame))
{ {
if (greenzone.laglog.GetLagInfoAtFrame(frame)) if (greenzone.laglog.GetLagInfoAtFrame(frame) == LAGGED_YES)
msg->clrTextBk = LAG_FRAMENUM_COLOR; msg->clrTextBk = LAG_FRAMENUM_COLOR;
else else
msg->clrTextBk = GREENZONE_FRAMENUM_COLOR; msg->clrTextBk = GREENZONE_FRAMENUM_COLOR;
@ -673,7 +678,7 @@ LONG BOOKMARKS::CustomDraw(NMLVCUSTOMDRAW* msg)
|| (!greenzone.SavestateIsEmpty(frame & EVERY4TH) && !greenzone.SavestateIsEmpty((frame & EVERY4TH) + 4)) || (!greenzone.SavestateIsEmpty(frame & EVERY4TH) && !greenzone.SavestateIsEmpty((frame & EVERY4TH) + 4))
|| (!greenzone.SavestateIsEmpty(frame & EVERY2ND) && !greenzone.SavestateIsEmpty((frame & EVERY2ND) + 2))) || (!greenzone.SavestateIsEmpty(frame & EVERY2ND) && !greenzone.SavestateIsEmpty((frame & EVERY2ND) + 2)))
{ {
if (greenzone.laglog.GetLagInfoAtFrame(frame)) if (greenzone.laglog.GetLagInfoAtFrame(frame) == LAGGED_YES)
msg->clrTextBk = PALE_LAG_FRAMENUM_COLOR; msg->clrTextBk = PALE_LAG_FRAMENUM_COLOR;
else else
msg->clrTextBk = PALE_GREENZONE_FRAMENUM_COLOR; msg->clrTextBk = PALE_GREENZONE_FRAMENUM_COLOR;
@ -695,7 +700,7 @@ LONG BOOKMARKS::CustomDraw(NMLVCUSTOMDRAW* msg)
{ {
if (!greenzone.SavestateIsEmpty(frame)) if (!greenzone.SavestateIsEmpty(frame))
{ {
if (greenzone.laglog.GetLagInfoAtFrame(frame)) if (greenzone.laglog.GetLagInfoAtFrame(frame) == LAGGED_YES)
msg->clrTextBk = LAG_INPUT_COLOR1; msg->clrTextBk = LAG_INPUT_COLOR1;
else else
msg->clrTextBk = GREENZONE_INPUT_COLOR1; msg->clrTextBk = GREENZONE_INPUT_COLOR1;
@ -704,7 +709,7 @@ LONG BOOKMARKS::CustomDraw(NMLVCUSTOMDRAW* msg)
|| (!greenzone.SavestateIsEmpty(frame & EVERY4TH) && !greenzone.SavestateIsEmpty((frame & EVERY4TH) + 4)) || (!greenzone.SavestateIsEmpty(frame & EVERY4TH) && !greenzone.SavestateIsEmpty((frame & EVERY4TH) + 4))
|| (!greenzone.SavestateIsEmpty(frame & EVERY2ND) && !greenzone.SavestateIsEmpty((frame & EVERY2ND) + 2))) || (!greenzone.SavestateIsEmpty(frame & EVERY2ND) && !greenzone.SavestateIsEmpty((frame & EVERY2ND) + 2)))
{ {
if (greenzone.laglog.GetLagInfoAtFrame(frame)) if (greenzone.laglog.GetLagInfoAtFrame(frame) == LAGGED_YES)
msg->clrTextBk = PALE_LAG_INPUT_COLOR1; msg->clrTextBk = PALE_LAG_INPUT_COLOR1;
else else
msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR1; msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR1;

View File

@ -204,7 +204,7 @@ void EDITOR::InputSetPattern(int start, int end, int joy, int button, int consec
for (int i = start; i <= end; ++i) for (int i = start; i <= end; ++i)
{ {
// skip lag frames // skip lag frames
if (taseditor_config.pattern_skips_lag && greenzone.laglog.GetLagInfoAtFrame(i)) if (taseditor_config.pattern_skips_lag && greenzone.laglog.GetLagInfoAtFrame(i) == LAGGED_YES)
continue; continue;
value = (autofire_patterns[current_pattern][pattern_offset] != 0); value = (autofire_patterns[current_pattern][pattern_offset] != 0);
if (currMovieData.records[i].checkBit(joy, button) != value) if (currMovieData.records[i].checkBit(joy, button) != value)
@ -285,7 +285,7 @@ bool EDITOR::FrameColumnSetPattern()
for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++)
{ {
// skip lag frames // skip lag frames
if (taseditor_config.pattern_skips_lag && greenzone.laglog.GetLagInfoAtFrame(*it)) if (taseditor_config.pattern_skips_lag && greenzone.laglog.GetLagInfoAtFrame(*it) == LAGGED_YES)
continue; continue;
if (autofire_patterns[current_pattern][pattern_offset]) if (autofire_patterns[current_pattern][pattern_offset])
{ {
@ -370,7 +370,7 @@ bool EDITOR::InputColumnSetPattern(int joy, int button)
for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++) for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++)
{ {
// skip lag frames // skip lag frames
if (taseditor_config.pattern_skips_lag && greenzone.laglog.GetLagInfoAtFrame(*it)) if (taseditor_config.pattern_skips_lag && greenzone.laglog.GetLagInfoAtFrame(*it) == LAGGED_YES)
continue; continue;
currMovieData.records[*it].setBitValue(joy, button, autofire_patterns[current_pattern][pattern_offset] != 0); currMovieData.records[*it].setBitValue(joy, button, autofire_patterns[current_pattern][pattern_offset] != 0);
pattern_offset++; pattern_offset++;

View File

@ -90,26 +90,22 @@ void GREENZONE::CollectCurrentState()
// lagFlag indicates that lag was in previous frame // lagFlag indicates that lag was in previous frame
int old_lagFlag = laglog.GetLagInfoAtFrame(currFrameCounter - 1); int old_lagFlag = laglog.GetLagInfoAtFrame(currFrameCounter - 1);
// Auto-adjust Input according to lag // Auto-adjust Input according to lag
if (taseditor_config.adjust_input_due_to_lag) if (taseditor_config.adjust_input_due_to_lag && old_lagFlag != LAGGED_DONTKNOW)
{ {
if (old_lagFlag && !lagFlag) if ((old_lagFlag == LAGGED_YES) && !lagFlag)
{ {
// there's no more lag on previous frame - shift Input up // there's no more lag on previous frame - shift Input up
AdjustUp(); AdjustUp();
} else if (!old_lagFlag && lagFlag) } else if ((old_lagFlag == LAGGED_NO) && lagFlag)
{ {
// there's new lag on previous frame - shift Input down // there's new lag on previous frame - shift Input down
AdjustDown(); AdjustDown();
} else
{
// old_lagFlag == lagFlag
laglog.SetLagInfo(currFrameCounter - 1, (lagFlag != 0));
} }
} else } else
{ {
if (lagFlag) if (lagFlag && (old_lagFlag != LAGGED_YES))
laglog.SetLagInfo(currFrameCounter - 1, true); laglog.SetLagInfo(currFrameCounter - 1, true);
else else if (old_lagFlag != LAGGED_NO)
laglog.SetLagInfo(currFrameCounter - 1, false); laglog.SetLagInfo(currFrameCounter - 1, false);
} }
} }
@ -407,7 +403,7 @@ void GREENZONE::AdjustUp()
int first_input_chanes = history.RegisterAdjustLag(at, -1); int first_input_chanes = history.RegisterAdjustLag(at, -1);
// if Input in the frame above currFrameCounter has changed then invalidate Greenzone (rewind 1 frame back) // if Input in the frame above currFrameCounter has changed then invalidate Greenzone (rewind 1 frame back)
// also if the frame above currFrameCounter is lag frame then rewind 1 frame (invalidate Greenzone), because maybe this frame also needs lag removal // also if the frame above currFrameCounter is lag frame then rewind 1 frame (invalidate Greenzone), because maybe this frame also needs lag removal
if ((first_input_chanes >= 0 && first_input_chanes < currFrameCounter) || (laglog.GetLagInfoAtFrame(at))) if ((first_input_chanes >= 0 && first_input_chanes < currFrameCounter) || (laglog.GetLagInfoAtFrame(at) != LAGGED_NO))
{ {
// custom invalidation procedure, not retriggering LostPosition/PauseFrame // custom invalidation procedure, not retriggering LostPosition/PauseFrame
Invalidate(at); Invalidate(at);

View File

@ -381,18 +381,8 @@ int HISTORY::JumpInTime(int new_pos)
if (first_change >= 0) if (first_change >= 0)
{ {
snapshots[real_pos].inputlog.toMovie(currMovieData, first_change); snapshots[real_pos].inputlog.toMovie(currMovieData, first_change);
// but Greenzone should be invalidated after the frame of Lag changes if this frame is less than the frame of Input changes if (markers_changed)
for (int i = 0; i < first_change; ++i) markers_manager.update();
{
// if old info != new info
if (greenzone.laglog.GetLagInfoAtFrame(i) != snapshots[real_pos].laglog.GetLagInfoAtFrame(i))
{
// Greenzone should be invalidated from the frame
first_change = i;
break;
}
}
greenzone.laglog = snapshots[real_pos].laglog;
selection.must_find_current_marker = playback.must_find_current_marker = true; selection.must_find_current_marker = playback.must_find_current_marker = true;
project.SetProjectChanged(); project.SetProjectChanged();
// Piano Roll Redraw will be called by Greenzone invalidation // Piano Roll Redraw will be called by Greenzone invalidation
@ -407,6 +397,17 @@ int HISTORY::JumpInTime(int new_pos)
// when using Hot Changes, Piano Roll should be always redrawn, because old changes become less hot // when using Hot Changes, Piano Roll should be always redrawn, because old changes become less hot
piano_roll.RedrawList(); piano_roll.RedrawList();
} }
// but Greenzone should be invalidated after the frame of Lag changes if this frame is less than the frame of Input changes
int first_lag_changes = greenzone.laglog.findFirstChange(snapshots[real_pos].laglog, first_change);
if (first_lag_changes >= 0 && first_change > first_lag_changes)
first_change = first_lag_changes;
// if old Greenzone's LagLog size is less than new LagLog size then replace it
if (greenzone.laglog.GetSize() < snapshots[real_pos].laglog.GetSize())
greenzone.laglog = snapshots[real_pos].laglog;
// but then also invalidate it after the point of difference
greenzone.laglog.InvalidateFrom(first_change);
piano_roll.UpdateItemCount(); piano_roll.UpdateItemCount();
piano_roll.FollowUndo(); piano_roll.FollowUndo();
return first_change; return first_change;
@ -764,17 +765,6 @@ int HISTORY::RegisterBranching(int slot, bool markers_changed)
snap.inputlog.copyHotChanges(&bookmarks.bookmarks_array[slot].snapshot.inputlog); snap.inputlog.copyHotChanges(&bookmarks.bookmarks_array[slot].snapshot.inputlog);
AddItemToHistory(snap, branches.GetCurrentBranch()); AddItemToHistory(snap, branches.GetCurrentBranch());
project.SetProjectChanged(); project.SetProjectChanged();
// but Greenzone should be invalidated after the frame of Lag changes if this frame is less than the frame of Input changes
for (int i = 0; i < first_changes; ++i)
{
// if old info != new info
if (snapshots[real_pos].laglog.GetLagInfoAtFrame(i) != greenzone.laglog.GetLagInfoAtFrame(i))
{
// Greenzone should be invalidated from the frame
first_changes = i;
break;
}
}
} else if (markers_changed) } else if (markers_changed)
{ {
// fill description: modification type + time of the Branch // fill description: modification type + time of the Branch
@ -790,6 +780,10 @@ int HISTORY::RegisterBranching(int slot, bool markers_changed)
AddItemToHistory(snap, branches.GetCurrentBranch()); AddItemToHistory(snap, branches.GetCurrentBranch());
project.SetProjectChanged(); project.SetProjectChanged();
} }
// but Greenzone should be invalidated after the frame of Lag changes if this frame is less than the frame of Input changes
int first_lag_changes = greenzone.laglog.findFirstChange(bookmarks.bookmarks_array[slot].snapshot.laglog, first_changes);
if (first_lag_changes >= 0 && first_changes > first_lag_changes)
return first_lag_changes;
return first_changes; return first_changes;
} }
void HISTORY::RegisterRecording(int frame_of_change) void HISTORY::RegisterRecording(int frame_of_change)

View File

@ -35,7 +35,7 @@ void LAGLOG::compress_data()
if (len) if (len)
{ {
uLongf comprlen = (len>>9)+12 + len; uLongf comprlen = (len>>9)+12 + len;
lag_log_compressed.resize(comprlen); lag_log_compressed.resize(comprlen, LAGGED_DONTKNOW);
compress(&lag_log_compressed[0], &comprlen, (uint8*)&lag_log[0], len); compress(&lag_log_compressed[0], &comprlen, (uint8*)&lag_log[0], len);
lag_log_compressed.resize(comprlen); lag_log_compressed.resize(comprlen);
} else } else
@ -75,7 +75,7 @@ bool LAGLOG::load(EMUFILE *is)
if (read32le(&size, is)) if (read32le(&size, is))
{ {
already_compressed = true; already_compressed = true;
lag_log.resize(size); lag_log.resize(size, LAGGED_DONTKNOW);
if (size) if (size)
{ {
// read and uncompress array // read and uncompress array
@ -113,15 +113,24 @@ bool LAGLOG::skipLoad(EMUFILE *is)
return true; return true;
} }
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
void LAGLOG::InvalidateFrom(int frame)
{
if (frame >= 0 && frame < (int)lag_log.size())
{
lag_log.resize(frame);
already_compressed = false;
}
}
void LAGLOG::SetLagInfo(int frame, bool lagFlag) void LAGLOG::SetLagInfo(int frame, bool lagFlag)
{ {
if ((int)lag_log.size() <= frame) if ((int)lag_log.size() <= frame)
lag_log.resize(frame + 1); lag_log.resize(frame + 1, LAGGED_DONTKNOW);
if (lagFlag) if (lagFlag)
lag_log[frame] = 1; lag_log[frame] = LAGGED_YES;
else else
lag_log[frame] = 0; lag_log[frame] = LAGGED_NO;
already_compressed = false; already_compressed = false;
} }
@ -129,15 +138,25 @@ void LAGLOG::EraseFrame(int frame)
{ {
if (frame < (int)lag_log.size()) if (frame < (int)lag_log.size())
lag_log.erase(lag_log.begin() + frame); lag_log.erase(lag_log.begin() + frame);
already_compressed = false;
} }
void LAGLOG::InsertFrame(int frame, bool lagFlag, int frames) void LAGLOG::InsertFrame(int frame, bool lagFlag, int frames)
{ {
if (frame < (int)lag_log.size()) if (frame < (int)lag_log.size())
{
// insert // insert
lag_log.insert(lag_log.begin() + frame, frames, (lagFlag) ? 1 : 0); lag_log.insert(lag_log.begin() + frame, frames, (lagFlag) ? LAGGED_YES : LAGGED_NO);
else } else
{
// append // append
lag_log.resize(frame + 1, (lagFlag) ? 1 : 0); lag_log.resize(frame + 1, LAGGED_DONTKNOW);
if (lagFlag)
lag_log[frame] = LAGGED_YES;
else
lag_log[frame] = LAGGED_NO;
}
already_compressed = false;
} }
// getters // getters
@ -145,11 +164,33 @@ int LAGLOG::GetSize()
{ {
return lag_log.size(); return lag_log.size();
} }
bool LAGLOG::GetLagInfoAtFrame(int frame) int LAGLOG::GetLagInfoAtFrame(int frame)
{ {
if (frame < (int)lag_log.size()) if (frame < (int)lag_log.size())
return (lag_log[frame] != 0); return lag_log[frame];
else else
return false; return LAGGED_DONTKNOW;
} }
int LAGLOG::findFirstChange(LAGLOG& their_log, int end)
{
// search for differences to the specified end (or to the end of this or their LagLog, whichever is less)
if (end < 0 || end >= (int)lag_log.size()) end = lag_log.size() - 1;
int their_log_end = their_log.GetSize() - 1;
if (end > their_log_end)
end = their_log_end;
uint8 my_lag_info, their_lag_info;
for (int i = 0; i <= end; ++i)
{
// if old info != new info and both infos are known
my_lag_info = lag_log[i];
their_lag_info = their_log.GetLagInfoAtFrame(i);
if ((my_lag_info == LAGGED_YES && their_lag_info == LAGGED_NO) || (my_lag_info == LAGGED_NO && their_lag_info == LAGGED_YES))
return i;
}
// no difference was found
return -1;
}

View File

@ -1,5 +1,9 @@
// Specification file for LagLog class // Specification file for LagLog class
#define LAGGED_NO 0
#define LAGGED_YES 1
#define LAGGED_DONTKNOW 2
class LAGLOG class LAGLOG
{ {
public: public:
@ -14,12 +18,16 @@ public:
bool load(EMUFILE *is); bool load(EMUFILE *is);
bool skipLoad(EMUFILE *is); bool skipLoad(EMUFILE *is);
void InvalidateFrom(int frame);
void SetLagInfo(int frame, bool lagFlag); void SetLagInfo(int frame, bool lagFlag);
void EraseFrame(int frame); void EraseFrame(int frame);
void InsertFrame(int frame, bool lagFlag, int frames = 1); void InsertFrame(int frame, bool lagFlag, int frames = 1);
int GetSize(); int GetSize();
bool GetLagInfoAtFrame(int frame); int GetLagInfoAtFrame(int frame);
int findFirstChange(LAGLOG& their_log, int end);
private: private:
// saved data // saved data

View File

@ -1298,204 +1298,219 @@ void PIANO_ROLL::GetDispInfo(NMLVDISPINFO* nmlvDispInfo)
LONG PIANO_ROLL::CustomDraw(NMLVCUSTOMDRAW* msg) LONG PIANO_ROLL::CustomDraw(NMLVCUSTOMDRAW* msg)
{ {
int cell_x, cell_y;
switch(msg->nmcd.dwDrawStage) switch(msg->nmcd.dwDrawStage)
{ {
case CDDS_PREPAINT: case CDDS_PREPAINT:
return CDRF_NOTIFYITEMDRAW; return CDRF_NOTIFYITEMDRAW;
case CDDS_ITEMPREPAINT: case CDDS_ITEMPREPAINT:
return CDRF_NOTIFYSUBITEMDRAW; return CDRF_NOTIFYSUBITEMDRAW;
case CDDS_SUBITEMPREPAINT: case CDDS_SUBITEMPREPAINT:
cell_x = msg->iSubItem;
cell_y = msg->nmcd.dwItemSpec;
if (cell_x > COLUMN_ICONS)
{ {
// text color int cell_x = msg->iSubItem;
if (taseditor_config.enable_hot_changes && cell_x >= COLUMN_JOYPAD1_A && cell_x <= COLUMN_JOYPAD4_R) int cell_y = msg->nmcd.dwItemSpec;
msg->clrText = hot_changes_colors[history.GetCurrentSnapshot().inputlog.GetHotChangeInfo(cell_y, cell_x - COLUMN_JOYPAD1_A)]; if (cell_x > COLUMN_ICONS)
else
msg->clrText = NORMAL_TEXT_COLOR;
// bg color and text font
if (cell_x == COLUMN_FRAMENUM || cell_x == COLUMN_FRAMENUM2)
{ {
// font int frame_lag = greenzone.laglog.GetLagInfoAtFrame(cell_y);
if (markers_manager.GetMarker(cell_y)) // text color
SelectObject(msg->nmcd.hdc, hMainListSelectFont); if (taseditor_config.enable_hot_changes && cell_x >= COLUMN_JOYPAD1_A && cell_x <= COLUMN_JOYPAD4_R)
msg->clrText = hot_changes_colors[history.GetCurrentSnapshot().inputlog.GetHotChangeInfo(cell_y, cell_x - COLUMN_JOYPAD1_A)];
else else
SelectObject(msg->nmcd.hdc, hMainListFont); msg->clrText = NORMAL_TEXT_COLOR;
// bg // bg color and text font
// frame number if (cell_x == COLUMN_FRAMENUM || cell_x == COLUMN_FRAMENUM2)
if (cell_y == history.GetUndoHint())
{ {
// undo hint here // font
if (markers_manager.GetMarker(cell_y) && (drag_mode != DRAG_MODE_MARKER || marker_drag_framenum != cell_y)) if (markers_manager.GetMarker(cell_y))
SelectObject(msg->nmcd.hdc, hMainListSelectFont);
else
SelectObject(msg->nmcd.hdc, hMainListFont);
// bg
// frame number
if (cell_y == history.GetUndoHint())
{ {
msg->clrTextBk = (taseditor_config.bind_markers) ? BINDMARKED_UNDOHINT_FRAMENUM_COLOR : MARKED_UNDOHINT_FRAMENUM_COLOR; // undo hint here
if (markers_manager.GetMarker(cell_y) && (drag_mode != DRAG_MODE_MARKER || marker_drag_framenum != cell_y))
{
msg->clrTextBk = (taseditor_config.bind_markers) ? BINDMARKED_UNDOHINT_FRAMENUM_COLOR : MARKED_UNDOHINT_FRAMENUM_COLOR;
} else
{
msg->clrTextBk = UNDOHINT_FRAMENUM_COLOR;
}
} else if (cell_y == currFrameCounter || cell_y == (playback.GetFlashingPauseFrame() - 1))
{
// this is current frame
if (markers_manager.GetMarker(cell_y) && (drag_mode != DRAG_MODE_MARKER || marker_drag_framenum != cell_y))
{
msg->clrTextBk = (taseditor_config.bind_markers) ? CUR_BINDMARKED_FRAMENUM_COLOR : CUR_MARKED_FRAMENUM_COLOR;
} else
{
msg->clrTextBk = CUR_FRAMENUM_COLOR;
}
} else if (markers_manager.GetMarker(cell_y) && (drag_mode != DRAG_MODE_MARKER || marker_drag_framenum != cell_y))
{
// this is marked frame
msg->clrTextBk = (taseditor_config.bind_markers) ? BINDMARKED_FRAMENUM_COLOR : MARKED_FRAMENUM_COLOR;
} else if (cell_y < greenzone.GetSize())
{
if (!greenzone.SavestateIsEmpty(cell_y))
{
// the frame is normal Greenzone frame
if (frame_lag == LAGGED_YES)
msg->clrTextBk = LAG_FRAMENUM_COLOR;
else
msg->clrTextBk = GREENZONE_FRAMENUM_COLOR;
} else if ((!greenzone.SavestateIsEmpty(cell_y & EVERY16TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY16TH) + 16))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY8TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY8TH) + 8))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY4TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY4TH) + 4))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY2ND) && !greenzone.SavestateIsEmpty((cell_y & EVERY2ND) + 2)))
{
// the frame is in a gap (in Greenzone tail)
if (frame_lag == LAGGED_YES)
msg->clrTextBk = PALE_LAG_FRAMENUM_COLOR;
else
msg->clrTextBk = PALE_GREENZONE_FRAMENUM_COLOR;
} else
{
// the frame is above Greenzone tail
if (frame_lag == LAGGED_YES)
msg->clrTextBk = VERY_PALE_LAG_FRAMENUM_COLOR;
else if (frame_lag == LAGGED_NO)
msg->clrTextBk = VERY_PALE_GREENZONE_FRAMENUM_COLOR;
else
msg->clrTextBk = NORMAL_FRAMENUM_COLOR;
}
} else } else
{ {
msg->clrTextBk = UNDOHINT_FRAMENUM_COLOR; // the frame is below Greenzone head
} if (frame_lag == LAGGED_YES)
} else if (cell_y == currFrameCounter || cell_y == (playback.GetFlashingPauseFrame() - 1))
{
// this is current frame
if (markers_manager.GetMarker(cell_y) && (drag_mode != DRAG_MODE_MARKER || marker_drag_framenum != cell_y))
{
msg->clrTextBk = (taseditor_config.bind_markers) ? CUR_BINDMARKED_FRAMENUM_COLOR : CUR_MARKED_FRAMENUM_COLOR;
} else
{
msg->clrTextBk = CUR_FRAMENUM_COLOR;
}
} else if (markers_manager.GetMarker(cell_y) && (drag_mode != DRAG_MODE_MARKER || marker_drag_framenum != cell_y))
{
// this is marked frame
msg->clrTextBk = (taseditor_config.bind_markers) ? BINDMARKED_FRAMENUM_COLOR : MARKED_FRAMENUM_COLOR;
} else if (cell_y < greenzone.GetSize())
{
if (!greenzone.SavestateIsEmpty(cell_y))
{
// the frame is normal Greenzone frame
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
msg->clrTextBk = LAG_FRAMENUM_COLOR;
else
msg->clrTextBk = GREENZONE_FRAMENUM_COLOR;
} else if ((!greenzone.SavestateIsEmpty(cell_y & EVERY16TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY16TH) + 16))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY8TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY8TH) + 8))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY4TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY4TH) + 4))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY2ND) && !greenzone.SavestateIsEmpty((cell_y & EVERY2ND) + 2)))
{
// the frame is in a gap (in Greenzone tail)
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
msg->clrTextBk = PALE_LAG_FRAMENUM_COLOR;
else
msg->clrTextBk = PALE_GREENZONE_FRAMENUM_COLOR;
} else
{
// the frame is above Greenzone tail
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
msg->clrTextBk = VERY_PALE_LAG_FRAMENUM_COLOR; msg->clrTextBk = VERY_PALE_LAG_FRAMENUM_COLOR;
else else if (frame_lag == LAGGED_NO)
msg->clrTextBk = VERY_PALE_GREENZONE_FRAMENUM_COLOR; msg->clrTextBk = VERY_PALE_GREENZONE_FRAMENUM_COLOR;
else
msg->clrTextBk = NORMAL_FRAMENUM_COLOR;
} }
} else } else if ((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 0 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 2)
{ {
// the frame is below Greenzone head // pad 1 or 3
if (greenzone.laglog.GetLagInfoAtFrame(cell_y)) // font: empty cells have "SelectFont" (so that "-" is wide), non-empty have normal font
msg->clrTextBk = VERY_PALE_LAG_FRAMENUM_COLOR; int joy = (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
int bit = (cell_x - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
if ((int)currMovieData.records.size() <= cell_y ||
((currMovieData.records[cell_y].joysticks[joy]) & (1<<bit)) )
SelectObject(msg->nmcd.hdc, hMainListFont);
else else
msg->clrTextBk = VERY_PALE_GREENZONE_FRAMENUM_COLOR; SelectObject(msg->nmcd.hdc, hMainListSelectFont);
} // bg
} else if ((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 0 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 2) if (cell_y == history.GetUndoHint())
{
// pad 1 or 3
// font: empty cells have "SelectFont" (so that "-" is wide), non-empty have normal font
int joy = (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
int bit = (cell_x - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
if ((int)currMovieData.records.size() <= cell_y ||
((currMovieData.records[cell_y].joysticks[joy]) & (1<<bit)) )
SelectObject(msg->nmcd.hdc, hMainListFont);
else
SelectObject(msg->nmcd.hdc, hMainListSelectFont);
// bg
if (cell_y == history.GetUndoHint())
{
// undo hint here
msg->clrTextBk = UNDOHINT_INPUT_COLOR1;
} else if (cell_y == currFrameCounter || cell_y == (playback.GetFlashingPauseFrame() - 1))
{
// this is current frame
msg->clrTextBk = CUR_INPUT_COLOR1;
} else if (cell_y < greenzone.GetSize())
{
if (!greenzone.SavestateIsEmpty(cell_y))
{ {
// the frame is normal Greenzone frame // undo hint here
if (greenzone.laglog.GetLagInfoAtFrame(cell_y)) msg->clrTextBk = UNDOHINT_INPUT_COLOR1;
msg->clrTextBk = LAG_INPUT_COLOR1; } else if (cell_y == currFrameCounter || cell_y == (playback.GetFlashingPauseFrame() - 1))
else
msg->clrTextBk = GREENZONE_INPUT_COLOR1;
} else if ((!greenzone.SavestateIsEmpty(cell_y & EVERY16TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY16TH) + 16))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY8TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY8TH) + 8))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY4TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY4TH) + 4))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY2ND) && !greenzone.SavestateIsEmpty((cell_y & EVERY2ND) + 2)))
{ {
// the frame is in a gap (in Greenzone tail) // this is current frame
if (greenzone.laglog.GetLagInfoAtFrame(cell_y)) msg->clrTextBk = CUR_INPUT_COLOR1;
msg->clrTextBk = PALE_LAG_INPUT_COLOR1; } else if (cell_y < greenzone.GetSize())
else {
msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR1; if (!greenzone.SavestateIsEmpty(cell_y))
{
// the frame is normal Greenzone frame
if (frame_lag == LAGGED_YES)
msg->clrTextBk = LAG_INPUT_COLOR1;
else
msg->clrTextBk = GREENZONE_INPUT_COLOR1;
} else if ((!greenzone.SavestateIsEmpty(cell_y & EVERY16TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY16TH) + 16))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY8TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY8TH) + 8))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY4TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY4TH) + 4))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY2ND) && !greenzone.SavestateIsEmpty((cell_y & EVERY2ND) + 2)))
{
// the frame is in a gap (in Greenzone tail)
if (frame_lag == LAGGED_YES)
msg->clrTextBk = PALE_LAG_INPUT_COLOR1;
else
msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR1;
} else
{
// the frame is above Greenzone tail
if (frame_lag == LAGGED_YES)
msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR1;
else if (frame_lag == LAGGED_NO)
msg->clrTextBk = VERY_PALE_GREENZONE_INPUT_COLOR1;
else
msg->clrTextBk = NORMAL_INPUT_COLOR1;
}
} else } else
{ {
// the frame is above Greenzone tail // the frame is below Greenzone head
if (greenzone.laglog.GetLagInfoAtFrame(cell_y)) if (frame_lag == LAGGED_YES)
msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR1; msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR1;
else else if (frame_lag == LAGGED_NO)
msg->clrTextBk = VERY_PALE_GREENZONE_INPUT_COLOR1; msg->clrTextBk = VERY_PALE_GREENZONE_INPUT_COLOR1;
else
msg->clrTextBk = NORMAL_INPUT_COLOR1;
} }
} else } else if ((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 1 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 3)
{ {
// the frame is below Greenzone head // pad 2 or 4
if (greenzone.laglog.GetLagInfoAtFrame(cell_y)) // font: empty cells have "SelectFont", non-empty have normal font
msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR1; int joy = (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
int bit = (cell_x - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
if ((int)currMovieData.records.size() <= cell_y ||
((currMovieData.records[cell_y].joysticks[joy]) & (1<<bit)) )
SelectObject(msg->nmcd.hdc, hMainListFont);
else else
msg->clrTextBk = VERY_PALE_GREENZONE_INPUT_COLOR1; SelectObject(msg->nmcd.hdc, hMainListSelectFont);
} // bg
} else if ((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 1 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 3) if (cell_y == history.GetUndoHint())
{
// pad 2 or 4
// font: empty cells have "SelectFont", non-empty have normal font
int joy = (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
int bit = (cell_x - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
if ((int)currMovieData.records.size() <= cell_y ||
((currMovieData.records[cell_y].joysticks[joy]) & (1<<bit)) )
SelectObject(msg->nmcd.hdc, hMainListFont);
else
SelectObject(msg->nmcd.hdc, hMainListSelectFont);
// bg
if (cell_y == history.GetUndoHint())
{
// undo hint here
msg->clrTextBk = UNDOHINT_INPUT_COLOR2;
} else if (cell_y == currFrameCounter || cell_y == (playback.GetFlashingPauseFrame() - 1))
{
// this is current frame
msg->clrTextBk = CUR_INPUT_COLOR2;
} else if (cell_y < greenzone.GetSize())
{
if (!greenzone.SavestateIsEmpty(cell_y))
{ {
// the frame is normal Greenzone frame // undo hint here
if (greenzone.laglog.GetLagInfoAtFrame(cell_y)) msg->clrTextBk = UNDOHINT_INPUT_COLOR2;
msg->clrTextBk = LAG_INPUT_COLOR2; } else if (cell_y == currFrameCounter || cell_y == (playback.GetFlashingPauseFrame() - 1))
else
msg->clrTextBk = GREENZONE_INPUT_COLOR2;
} else if ((!greenzone.SavestateIsEmpty(cell_y & EVERY16TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY16TH) + 16))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY8TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY8TH) + 8))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY4TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY4TH) + 4))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY2ND) && !greenzone.SavestateIsEmpty((cell_y & EVERY2ND) + 2)))
{ {
// the frame is in a gap (in Greenzone tail) // this is current frame
if (greenzone.laglog.GetLagInfoAtFrame(cell_y)) msg->clrTextBk = CUR_INPUT_COLOR2;
msg->clrTextBk = PALE_LAG_INPUT_COLOR2; } else if (cell_y < greenzone.GetSize())
else {
msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR2; if (!greenzone.SavestateIsEmpty(cell_y))
{
// the frame is normal Greenzone frame
if (frame_lag == LAGGED_YES)
msg->clrTextBk = LAG_INPUT_COLOR2;
else
msg->clrTextBk = GREENZONE_INPUT_COLOR2;
} else if ((!greenzone.SavestateIsEmpty(cell_y & EVERY16TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY16TH) + 16))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY8TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY8TH) + 8))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY4TH) && !greenzone.SavestateIsEmpty((cell_y & EVERY4TH) + 4))
|| (!greenzone.SavestateIsEmpty(cell_y & EVERY2ND) && !greenzone.SavestateIsEmpty((cell_y & EVERY2ND) + 2)))
{
// the frame is in a gap (in Greenzone tail)
if (frame_lag == LAGGED_YES)
msg->clrTextBk = PALE_LAG_INPUT_COLOR2;
else
msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR2;
} else
{
// the frame is above Greenzone tail
if (frame_lag == LAGGED_YES)
msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR2;
else if (frame_lag == LAGGED_NO)
msg->clrTextBk = VERY_PALE_GREENZONE_INPUT_COLOR2;
else
msg->clrTextBk = NORMAL_INPUT_COLOR2;
}
} else } else
{ {
// the frame is above Greenzone tail // the frame is below Greenzone head
if (greenzone.laglog.GetLagInfoAtFrame(cell_y)) if (frame_lag == LAGGED_YES)
msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR2; msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR2;
else else if (frame_lag == LAGGED_NO)
msg->clrTextBk = VERY_PALE_GREENZONE_INPUT_COLOR2; msg->clrTextBk = VERY_PALE_GREENZONE_INPUT_COLOR2;
else
msg->clrTextBk = NORMAL_INPUT_COLOR2;
} }
} else
{
// the frame is below Greenzone head
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR2;
else
msg->clrTextBk = VERY_PALE_GREENZONE_INPUT_COLOR2;
} }
} }
} }
return CDRF_DODEFAULT;
default: default:
return CDRF_DODEFAULT; return CDRF_DODEFAULT;
} }
@ -1556,6 +1571,17 @@ void PIANO_ROLL::RightClick(LVHITTESTINFO& info)
} }
} }
bool PIANO_ROLL::CheckIfTheresAnyIconAtFrame(int frame)
{
if (frame == currFrameCounter)
return true;
if (frame == playback.GetLostPosition())
return true;
if (bookmarks.FindBookmarkAtFrame(frame) >= 0)
return true;
return false;
}
void PIANO_ROLL::CrossGaps(int zDelta) void PIANO_ROLL::CrossGaps(int zDelta)
{ {
POINT p; POINT p;
@ -1573,9 +1599,49 @@ void PIANO_ROLL::CrossGaps(int zDelta)
ListView_SubItemHitTest(hwndList, &info); ListView_SubItemHitTest(hwndList, &info);
int row_index = info.iItem; int row_index = info.iItem;
int column_index = info.iSubItem; int column_index = info.iSubItem;
if (row_index >= 0 && column_index >= COLUMN_FRAMENUM && column_index <= COLUMN_FRAMENUM2) if (row_index >= 0 && column_index >= COLUMN_ICONS && column_index <= COLUMN_FRAMENUM2)
{ {
if (column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2) if (column_index == COLUMN_ICONS)
{
// cross gaps in Icons
if (zDelta < 0)
{
// search down
int last_frame = currMovieData.getNumRecords() - 1;
if (row_index < last_frame)
{
int frame = row_index + 1;
bool result_of_closest_frame = CheckIfTheresAnyIconAtFrame(frame);
while ((++frame) <= last_frame)
{
if (CheckIfTheresAnyIconAtFrame(frame) != result_of_closest_frame)
{
// found different result, so we crossed the gap
ListView_Scroll(hwndList, 0, list_row_height * (frame - row_index));
break;
}
}
}
} else
{
// search up
int first_frame = 0;
if (row_index > first_frame)
{
int frame = row_index - 1;
bool result_of_closest_frame = CheckIfTheresAnyIconAtFrame(frame);
while ((--frame) >= first_frame)
{
if (CheckIfTheresAnyIconAtFrame(frame) != result_of_closest_frame)
{
// found different result, so we crossed the gap
ListView_Scroll(hwndList, 0, list_row_height * (frame - row_index));
break;
}
}
}
}
} else if (column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2)
{ {
// cross gaps in Markers // cross gaps in Markers
if (zDelta < 0) if (zDelta < 0)

View File

@ -103,7 +103,7 @@ enum DRAG_MODES
#define NORMAL_BACKGROUND_COLOR 0xFFFFFF #define NORMAL_BACKGROUND_COLOR 0xFFFFFF
#define NORMAL_FRAMENUM_COLOR 0xFFFFFF #define NORMAL_FRAMENUM_COLOR 0xFFFFFF
#define NORMAL_INPUT_COLOR1 0xEDEDED #define NORMAL_INPUT_COLOR1 0xE9E9E9
#define NORMAL_INPUT_COLOR2 0xE2E2E2 #define NORMAL_INPUT_COLOR2 0xE2E2E2
#define GREENZONE_FRAMENUM_COLOR 0xDDFFDD #define GREENZONE_FRAMENUM_COLOR 0xDDFFDD
@ -130,9 +130,9 @@ enum DRAG_MODES
#define VERY_PALE_LAG_INPUT_COLOR1 0xE5E5F7 #define VERY_PALE_LAG_INPUT_COLOR1 0xE5E5F7
#define VERY_PALE_LAG_INPUT_COLOR2 0xE0E0F1 #define VERY_PALE_LAG_INPUT_COLOR2 0xE0E0F1
#define CUR_FRAMENUM_COLOR 0xFCF1CE #define CUR_FRAMENUM_COLOR 0xFCEDCF
#define CUR_INPUT_COLOR1 0xF8EBB6 #define CUR_INPUT_COLOR1 0xF7E7B5
#define CUR_INPUT_COLOR2 0xE6DDA5 #define CUR_INPUT_COLOR2 0xE5DBA5
#define UNDOHINT_FRAMENUM_COLOR 0xF9DDE6 #define UNDOHINT_FRAMENUM_COLOR 0xF9DDE6
#define UNDOHINT_INPUT_COLOR1 0xF7D2E1 #define UNDOHINT_INPUT_COLOR1 0xF7D2E1
@ -190,6 +190,7 @@ public:
void RightClick(LVHITTESTINFO& info); void RightClick(LVHITTESTINFO& info);
bool CheckIfTheresAnyIconAtFrame(int frame);
void CrossGaps(int zDelta); void CrossGaps(int zDelta);
int header_item_under_mouse; int header_item_under_mouse;

View File

@ -512,7 +512,7 @@ void SELECTION::SetRegionSelectionPattern(int start, int end)
for (int i = start; i <= end; ++i) for (int i = start; i <= end; ++i)
{ {
// skip lag frames // skip lag frames
if (taseditor_config.pattern_skips_lag && greenzone.laglog.GetLagInfoAtFrame(i)) if (taseditor_config.pattern_skips_lag && greenzone.laglog.GetLagInfoAtFrame(i) == LAGGED_YES)
continue; continue;
if (editor.autofire_patterns[current_pattern][pattern_offset]) if (editor.autofire_patterns[current_pattern][pattern_offset])
{ {

View File

@ -51,7 +51,7 @@ TASEDITOR_CONFIG::TASEDITOR_CONFIG()
view_branches_tree = false; view_branches_tree = false;
branch_scr_hud = true; branch_scr_hud = true;
restore_position = false; restore_position = false;
adjust_input_due_to_lag = false; adjust_input_due_to_lag = true;
greenzone_capacity = GREENZONE_CAPACITY_DEFAULT; greenzone_capacity = GREENZONE_CAPACITY_DEFAULT;
undo_levels = UNDO_LEVELS_DEFAULT; undo_levels = UNDO_LEVELS_DEFAULT;
autosave_period = AUTOSAVE_PERIOD_DEFAULT; autosave_period = AUTOSAVE_PERIOD_DEFAULT;