* 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);
int result = history.RegisterImport(md, name);
if (result >= 0)
{
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);
}
} else
{
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)
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);
if (first_change >= 0)
@ -453,6 +451,13 @@ void BOOKMARKS::deploy(int slot)
// didn't change anything in current movie
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)
if (greenzone.SavestateIsEmpty(keyframe))
greenzone.WriteSavestate(keyframe, bookmarks_array[slot].savestate);
@ -664,7 +669,7 @@ LONG BOOKMARKS::CustomDraw(NMLVCUSTOMDRAW* msg)
{
if (!greenzone.SavestateIsEmpty(frame))
{
if (greenzone.laglog.GetLagInfoAtFrame(frame))
if (greenzone.laglog.GetLagInfoAtFrame(frame) == LAGGED_YES)
msg->clrTextBk = LAG_FRAMENUM_COLOR;
else
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 & EVERY2ND) && !greenzone.SavestateIsEmpty((frame & EVERY2ND) + 2)))
{
if (greenzone.laglog.GetLagInfoAtFrame(frame))
if (greenzone.laglog.GetLagInfoAtFrame(frame) == LAGGED_YES)
msg->clrTextBk = PALE_LAG_FRAMENUM_COLOR;
else
msg->clrTextBk = PALE_GREENZONE_FRAMENUM_COLOR;
@ -695,7 +700,7 @@ LONG BOOKMARKS::CustomDraw(NMLVCUSTOMDRAW* msg)
{
if (!greenzone.SavestateIsEmpty(frame))
{
if (greenzone.laglog.GetLagInfoAtFrame(frame))
if (greenzone.laglog.GetLagInfoAtFrame(frame) == LAGGED_YES)
msg->clrTextBk = LAG_INPUT_COLOR1;
else
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 & EVERY2ND) && !greenzone.SavestateIsEmpty((frame & EVERY2ND) + 2)))
{
if (greenzone.laglog.GetLagInfoAtFrame(frame))
if (greenzone.laglog.GetLagInfoAtFrame(frame) == LAGGED_YES)
msg->clrTextBk = PALE_LAG_INPUT_COLOR1;
else
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)
{
// 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;
value = (autofire_patterns[current_pattern][pattern_offset] != 0);
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++)
{
// 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;
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++)
{
// 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;
currMovieData.records[*it].setBitValue(joy, button, autofire_patterns[current_pattern][pattern_offset] != 0);
pattern_offset++;

View File

@ -90,26 +90,22 @@ void GREENZONE::CollectCurrentState()
// lagFlag indicates that lag was in previous frame
int old_lagFlag = laglog.GetLagInfoAtFrame(currFrameCounter - 1);
// 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
AdjustUp();
} else if (!old_lagFlag && lagFlag)
} else if ((old_lagFlag == LAGGED_NO) && lagFlag)
{
// there's new lag on previous frame - shift Input down
AdjustDown();
} else
{
// old_lagFlag == lagFlag
laglog.SetLagInfo(currFrameCounter - 1, (lagFlag != 0));
}
} else
{
if (lagFlag)
if (lagFlag && (old_lagFlag != LAGGED_YES))
laglog.SetLagInfo(currFrameCounter - 1, true);
else
else if (old_lagFlag != LAGGED_NO)
laglog.SetLagInfo(currFrameCounter - 1, false);
}
}
@ -407,7 +403,7 @@ void GREENZONE::AdjustUp()
int first_input_chanes = history.RegisterAdjustLag(at, -1);
// 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
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
Invalidate(at);

View File

@ -381,18 +381,8 @@ int HISTORY::JumpInTime(int new_pos)
if (first_change >= 0)
{
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
for (int i = 0; i < first_change; ++i)
{
// 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;
if (markers_changed)
markers_manager.update();
selection.must_find_current_marker = playback.must_find_current_marker = true;
project.SetProjectChanged();
// 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
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.FollowUndo();
return first_change;
@ -764,17 +765,6 @@ int HISTORY::RegisterBranching(int slot, bool markers_changed)
snap.inputlog.copyHotChanges(&bookmarks.bookmarks_array[slot].snapshot.inputlog);
AddItemToHistory(snap, branches.GetCurrentBranch());
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)
{
// fill description: modification type + time of the Branch
@ -790,6 +780,10 @@ int HISTORY::RegisterBranching(int slot, bool markers_changed)
AddItemToHistory(snap, branches.GetCurrentBranch());
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;
}
void HISTORY::RegisterRecording(int frame_of_change)

View File

@ -35,7 +35,7 @@ void LAGLOG::compress_data()
if (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);
lag_log_compressed.resize(comprlen);
} else
@ -75,7 +75,7 @@ bool LAGLOG::load(EMUFILE *is)
if (read32le(&size, is))
{
already_compressed = true;
lag_log.resize(size);
lag_log.resize(size, LAGGED_DONTKNOW);
if (size)
{
// read and uncompress array
@ -113,15 +113,24 @@ bool LAGLOG::skipLoad(EMUFILE *is)
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)
{
if ((int)lag_log.size() <= frame)
lag_log.resize(frame + 1);
lag_log.resize(frame + 1, LAGGED_DONTKNOW);
if (lagFlag)
lag_log[frame] = 1;
lag_log[frame] = LAGGED_YES;
else
lag_log[frame] = 0;
lag_log[frame] = LAGGED_NO;
already_compressed = false;
}
@ -129,15 +138,25 @@ void LAGLOG::EraseFrame(int frame)
{
if (frame < (int)lag_log.size())
lag_log.erase(lag_log.begin() + frame);
already_compressed = false;
}
void LAGLOG::InsertFrame(int frame, bool lagFlag, int frames)
{
if (frame < (int)lag_log.size())
{
// insert
lag_log.insert(lag_log.begin() + frame, frames, (lagFlag) ? 1 : 0);
else
lag_log.insert(lag_log.begin() + frame, frames, (lagFlag) ? LAGGED_YES : LAGGED_NO);
} else
{
// 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
@ -145,11 +164,33 @@ int LAGLOG::GetSize()
{
return lag_log.size();
}
bool LAGLOG::GetLagInfoAtFrame(int frame)
int LAGLOG::GetLagInfoAtFrame(int frame)
{
if (frame < (int)lag_log.size())
return (lag_log[frame] != 0);
return lag_log[frame];
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
#define LAGGED_NO 0
#define LAGGED_YES 1
#define LAGGED_DONTKNOW 2
class LAGLOG
{
public:
@ -14,12 +18,16 @@ public:
bool load(EMUFILE *is);
bool skipLoad(EMUFILE *is);
void InvalidateFrom(int frame);
void SetLagInfo(int frame, bool lagFlag);
void EraseFrame(int frame);
void InsertFrame(int frame, bool lagFlag, int frames = 1);
int GetSize();
bool GetLagInfoAtFrame(int frame);
int GetLagInfoAtFrame(int frame);
int findFirstChange(LAGLOG& their_log, int end);
private:
// saved data

View File

@ -1298,204 +1298,219 @@ void PIANO_ROLL::GetDispInfo(NMLVDISPINFO* nmlvDispInfo)
LONG PIANO_ROLL::CustomDraw(NMLVCUSTOMDRAW* msg)
{
int cell_x, cell_y;
switch(msg->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
return CDRF_NOTIFYITEMDRAW;
case CDDS_ITEMPREPAINT:
return CDRF_NOTIFYSUBITEMDRAW;
case CDDS_SUBITEMPREPAINT:
cell_x = msg->iSubItem;
cell_y = msg->nmcd.dwItemSpec;
if (cell_x > COLUMN_ICONS)
case CDDS_PREPAINT:
return CDRF_NOTIFYITEMDRAW;
case CDDS_ITEMPREPAINT:
return CDRF_NOTIFYSUBITEMDRAW;
case CDDS_SUBITEMPREPAINT:
{
// text color
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
msg->clrText = NORMAL_TEXT_COLOR;
// bg color and text font
if (cell_x == COLUMN_FRAMENUM || cell_x == COLUMN_FRAMENUM2)
int cell_x = msg->iSubItem;
int cell_y = msg->nmcd.dwItemSpec;
if (cell_x > COLUMN_ICONS)
{
// font
if (markers_manager.GetMarker(cell_y))
SelectObject(msg->nmcd.hdc, hMainListSelectFont);
int frame_lag = greenzone.laglog.GetLagInfoAtFrame(cell_y);
// text color
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
SelectObject(msg->nmcd.hdc, hMainListFont);
// bg
// frame number
if (cell_y == history.GetUndoHint())
msg->clrText = NORMAL_TEXT_COLOR;
// bg color and text font
if (cell_x == COLUMN_FRAMENUM || cell_x == COLUMN_FRAMENUM2)
{
// undo hint here
if (markers_manager.GetMarker(cell_y) && (drag_mode != DRAG_MODE_MARKER || marker_drag_framenum != cell_y))
// font
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
{
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 (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))
// the frame is below Greenzone head
if (frame_lag == LAGGED_YES)
msg->clrTextBk = VERY_PALE_LAG_FRAMENUM_COLOR;
else
else if (frame_lag == LAGGED_NO)
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
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
msg->clrTextBk = VERY_PALE_LAG_FRAMENUM_COLOR;
// 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
msg->clrTextBk = VERY_PALE_GREENZONE_FRAMENUM_COLOR;
}
} else if ((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 0 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 2)
{
// 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))
SelectObject(msg->nmcd.hdc, hMainListSelectFont);
// bg
if (cell_y == history.GetUndoHint())
{
// the frame is normal Greenzone frame
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
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)))
// undo hint here
msg->clrTextBk = UNDOHINT_INPUT_COLOR1;
} else if (cell_y == currFrameCounter || cell_y == (playback.GetFlashingPauseFrame() - 1))
{
// the frame is in a gap (in Greenzone tail)
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
msg->clrTextBk = PALE_LAG_INPUT_COLOR1;
else
msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR1;
// 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
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
{
// the frame is above Greenzone tail
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
// the frame is below Greenzone head
if (frame_lag == LAGGED_YES)
msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR1;
else
else if (frame_lag == LAGGED_NO)
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
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR1;
// 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
msg->clrTextBk = VERY_PALE_GREENZONE_INPUT_COLOR1;
}
} else if ((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 1 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 3)
{
// 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))
SelectObject(msg->nmcd.hdc, hMainListSelectFont);
// bg
if (cell_y == history.GetUndoHint())
{
// the frame is normal Greenzone frame
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
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)))
// undo hint here
msg->clrTextBk = UNDOHINT_INPUT_COLOR2;
} else if (cell_y == currFrameCounter || cell_y == (playback.GetFlashingPauseFrame() - 1))
{
// the frame is in a gap (in Greenzone tail)
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
msg->clrTextBk = PALE_LAG_INPUT_COLOR2;
else
msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR2;
// 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
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
{
// the frame is above Greenzone tail
if (greenzone.laglog.GetLagInfoAtFrame(cell_y))
// the frame is below Greenzone head
if (frame_lag == LAGGED_YES)
msg->clrTextBk = VERY_PALE_LAG_INPUT_COLOR2;
else
else if (frame_lag == LAGGED_NO)
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:
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)
{
POINT p;
@ -1573,9 +1599,49 @@ void PIANO_ROLL::CrossGaps(int zDelta)
ListView_SubItemHitTest(hwndList, &info);
int row_index = info.iItem;
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
if (zDelta < 0)

View File

@ -103,7 +103,7 @@ enum DRAG_MODES
#define NORMAL_BACKGROUND_COLOR 0xFFFFFF
#define NORMAL_FRAMENUM_COLOR 0xFFFFFF
#define NORMAL_INPUT_COLOR1 0xEDEDED
#define NORMAL_INPUT_COLOR1 0xE9E9E9
#define NORMAL_INPUT_COLOR2 0xE2E2E2
#define GREENZONE_FRAMENUM_COLOR 0xDDFFDD
@ -130,9 +130,9 @@ enum DRAG_MODES
#define VERY_PALE_LAG_INPUT_COLOR1 0xE5E5F7
#define VERY_PALE_LAG_INPUT_COLOR2 0xE0E0F1
#define CUR_FRAMENUM_COLOR 0xFCF1CE
#define CUR_INPUT_COLOR1 0xF8EBB6
#define CUR_INPUT_COLOR2 0xE6DDA5
#define CUR_FRAMENUM_COLOR 0xFCEDCF
#define CUR_INPUT_COLOR1 0xF7E7B5
#define CUR_INPUT_COLOR2 0xE5DBA5
#define UNDOHINT_FRAMENUM_COLOR 0xF9DDE6
#define UNDOHINT_INPUT_COLOR1 0xF7D2E1
@ -190,6 +190,7 @@ public:
void RightClick(LVHITTESTINFO& info);
bool CheckIfTheresAnyIconAtFrame(int frame);
void CrossGaps(int zDelta);
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)
{
// 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;
if (editor.autofire_patterns[current_pattern][pattern_offset])
{

View File

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