* Tasedit: gradual greenzone cleaning

This commit is contained in:
ansstuff 2011-10-20 22:31:30 +00:00
parent f81fa03c44
commit 383baa85c4
5 changed files with 187 additions and 74 deletions

View File

@ -174,17 +174,24 @@ LONG CustomDraw(NMLVCUSTOMDRAW* msg)
{
// marked frame
msg->clrTextBk = MARKED_FRAMENUM_COLOR;
} else if(cell_y < greenzone.greenZoneCount && !greenzone.savestates[cell_y].empty())
} else if(cell_y < greenzone.greenZoneCount)
{
if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
if (!greenzone.savestates[cell_y].empty())
{
// lag frame
msg->clrTextBk = LAG_FRAMENUM_COLOR;
} else
if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
msg->clrTextBk = LAG_FRAMENUM_COLOR;
else
msg->clrTextBk = GREENZONE_FRAMENUM_COLOR;
} else if ((!greenzone.savestates[cell_y & EVERY16TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0xF) + 1 && !greenzone.savestates[(cell_y | 0xF) + 1].empty())
|| (!greenzone.savestates[cell_y & EVERY8TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x7) + 1 && !greenzone.savestates[(cell_y | 0x7) + 1].empty())
|| (!greenzone.savestates[cell_y & EVERY4TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x3) + 1 && !greenzone.savestates[(cell_y | 0x3) + 1].empty())
|| (!greenzone.savestates[cell_y & EVERY2ND].empty() && !greenzone.savestates[(cell_y | 0x1) + 1].empty()))
{
// green zone frame
msg->clrTextBk = GREENZONE_FRAMENUM_COLOR;
}
if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
msg->clrTextBk = PALE_LAG_FRAMENUM_COLOR;
else
msg->clrTextBk = PALE_GREENZONE_FRAMENUM_COLOR;
} else msg->clrTextBk = NORMAL_FRAMENUM_COLOR;
} else msg->clrTextBk = NORMAL_FRAMENUM_COLOR;
} else if((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 0 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 2)
{
@ -197,17 +204,24 @@ LONG CustomDraw(NMLVCUSTOMDRAW* msg)
{
// current frame
msg->clrTextBk = CUR_INPUT_COLOR1;
} else if(cell_y < greenzone.greenZoneCount && !greenzone.savestates[cell_y].empty())
} else if(cell_y < greenzone.greenZoneCount)
{
if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
if (!greenzone.savestates[cell_y].empty())
{
// lag frame
msg->clrTextBk = LAG_INPUT_COLOR1;
} else
if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
msg->clrTextBk = LAG_INPUT_COLOR1;
else
msg->clrTextBk = GREENZONE_INPUT_COLOR1;
} else if ((!greenzone.savestates[cell_y & EVERY16TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0xF) + 1 && !greenzone.savestates[(cell_y | 0xF) + 1].empty())
|| (!greenzone.savestates[cell_y & EVERY8TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x7) + 1 && !greenzone.savestates[(cell_y | 0x7) + 1].empty())
|| (!greenzone.savestates[cell_y & EVERY4TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x3) + 1 && !greenzone.savestates[(cell_y | 0x3) + 1].empty())
|| (!greenzone.savestates[cell_y & EVERY2ND].empty() && !greenzone.savestates[(cell_y | 0x1) + 1].empty()))
{
// green zone frame
msg->clrTextBk = GREENZONE_INPUT_COLOR1;
}
if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
msg->clrTextBk = PALE_LAG_INPUT_COLOR1;
else
msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR1;
} else msg->clrTextBk = NORMAL_INPUT_COLOR1;
} else msg->clrTextBk = NORMAL_INPUT_COLOR1;
} else if((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 1 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 3)
{
@ -220,17 +234,24 @@ LONG CustomDraw(NMLVCUSTOMDRAW* msg)
{
// current frame
msg->clrTextBk = CUR_INPUT_COLOR2;
} else if(cell_y < greenzone.greenZoneCount && !greenzone.savestates[cell_y].empty())
} else if(cell_y < greenzone.greenZoneCount)
{
if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
if (!greenzone.savestates[cell_y].empty())
{
// lag frame
msg->clrTextBk = LAG_INPUT_COLOR2;
} else
if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
msg->clrTextBk = LAG_INPUT_COLOR2;
else
msg->clrTextBk = GREENZONE_INPUT_COLOR2;
} else if ((!greenzone.savestates[cell_y & EVERY16TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0xF) + 1 && !greenzone.savestates[(cell_y | 0xF) + 1].empty())
|| (!greenzone.savestates[cell_y & EVERY8TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x7) + 1 && !greenzone.savestates[(cell_y | 0x7) + 1].empty())
|| (!greenzone.savestates[cell_y & EVERY4TH].empty() && (int)greenzone.savestates.size() > (cell_y | 0x3) + 1 && !greenzone.savestates[(cell_y | 0x3) + 1].empty())
|| (!greenzone.savestates[cell_y & EVERY2ND].empty() && !greenzone.savestates[(cell_y | 0x1) + 1].empty()))
{
// green zone frame
msg->clrTextBk = GREENZONE_INPUT_COLOR2;
}
if (TASEdit_show_lag_frames && greenzone.lag_history[cell_y])
msg->clrTextBk = PALE_LAG_INPUT_COLOR2;
else
msg->clrTextBk = PALE_GREENZONE_INPUT_COLOR2;
} else msg->clrTextBk = NORMAL_INPUT_COLOR2;
} else msg->clrTextBk = NORMAL_INPUT_COLOR2;
}
}
@ -434,6 +455,7 @@ void SingleClick(LPNMITEMACTIVATE info)
project.changed = true;
// deselect this row, so that new marker will be seen immediately
ListView_SetItemState(hwndList, row_index, 0, LVIS_SELECTED);
ListView_SetItemState(hwndList, -1, LVIS_FOCUSED, LVIS_FOCUSED);
// also no need to redraw row
}
}
@ -637,7 +659,7 @@ void ColumnSet(int column)
void ClearSelection()
{
ListView_SetItemState(hwndList,-1,0, LVIS_SELECTED);
ListView_SetItemState(hwndList, -1, 0, LVIS_FOCUSED|LVIS_SELECTED);
}
void ClearRowSelection(int index)
{
@ -676,7 +698,8 @@ void SelectMidMarkers()
return;
}
ClearSelection();
//ClearSelection(); - need to clear without clearing focused, because otherwise there's strange bug when quickly pressing Ctrl+A right after clicking on already selected row
ListView_SetItemState(hwndList, -1, 0, LVIS_SELECTED);
// selecting circle:
if (upper_border > upper_marker+1 || lower_border < lower_marker-1 || lower_border > lower_marker)
{
@ -1458,6 +1481,8 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
FollowPlayback();
else if (selectionFrames.size())
FollowSelection();
else if (playback.pauseframe)
FollowPauseframe();
break;
case ID_VIEW_SHOW_LAG_FRAMES:
//switch "Highlight lag frames" flag
@ -1499,8 +1524,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
if (new_capacity < TASEdit_greenzone_capacity)
{
TASEdit_greenzone_capacity = new_capacity;
greenzone.ClearGreenzoneTail();
RedrawList();
greenzone.GreenzoneCleaning();
} else TASEdit_greenzone_capacity = new_capacity;
}
break;
@ -1685,6 +1709,26 @@ void FollowSelection()
ListView_EnsureVisible(hwndList, index, false);
}
}
void FollowPauseframe()
{
int jump_frame = playback.pauseframe;
if (jump_frame >= 0)
{
// center list at jump_frame
int list_items = listItems;
if (currMovieData.fourscore) list_items--;
int lower_border = (list_items - 1) / 2;
int upper_border = (list_items - 1) - lower_border;
int index = jump_frame + lower_border;
if (index >= currMovieData.getNumRecords())
index = currMovieData.getNumRecords()-1;
ListView_EnsureVisible(hwndList, index, false);
index = jump_frame - upper_border;
if (index < 0)
index = 0;
ListView_EnsureVisible(hwndList, index, false);
}
}
void EnterTasEdit()
{

View File

@ -4,9 +4,9 @@
#define NUM_JOYPAD_BUTTONS 8
#define PROGRESSBAR_WIDTH 200
#define GREENZONE_CAPACITY_DEFAULT 100000
#define GREENZONE_CAPACITY_DEFAULT 10000
#define GREENZONE_CAPACITY_MIN 1
#define GREENZONE_CAPACITY_MAX 200000 // maybe even more
#define GREENZONE_CAPACITY_MAX 50000
#define UNDO_LEVELS_MIN 1
#define UNDO_LEVELS_MAX 999
@ -57,23 +57,42 @@
#define DIGITS_IN_FRAMENUM 7
// listview colors
#define NORMAL_FRAMENUM_COLOR 0xFFFFFF
#define NORMAL_INPUT_COLOR1 0xF0F0F0
#define NORMAL_INPUT_COLOR2 0xDEDEDE
#define GREENZONE_FRAMENUM_COLOR 0xDDFFDD
#define GREENZONE_INPUT_COLOR1 0xC8F7C4
#define GREENZONE_INPUT_COLOR2 0xAEE2AE
#define PALE_GREENZONE_FRAMENUM_COLOR 0xE4FFE4
#define PALE_GREENZONE_INPUT_COLOR1 0xD5F9D4
#define PALE_GREENZONE_INPUT_COLOR2 0xBAE6BA
#define LAG_FRAMENUM_COLOR 0xDBDAFF
#define LAG_INPUT_COLOR1 0xCECBEF
#define LAG_INPUT_COLOR2 0xBEBAE4
#define PALE_LAG_FRAMENUM_COLOR 0xE1E1FF
#define PALE_LAG_INPUT_COLOR1 0xD6D3F1
#define PALE_LAG_INPUT_COLOR2 0xC7C4E8
#define CUR_FRAMENUM_COLOR 0xFCF1CE
#define CUR_INPUT_COLOR1 0xF7E9B2
#define CUR_INPUT_COLOR2 0xE4D8A8
#define UNDOHINT_FRAMENUM_COLOR 0xF9DDE6
#define MARKED_UNDOHINT_FRAMENUM_COLOR 0xE1E7EC
#define UNDOHINT_INPUT_COLOR1 0xF6CCDD
#define UNDOHINT_INPUT_COLOR2 0xE5B7CC
#define MARKED_FRAMENUM_COLOR 0xC0FCFF
#define CUR_MARKED_FRAMENUM_COLOR 0xDEF7F4
#define CUR_FRAMENUM_COLOR 0xFCF1CE
#define GREENZONE_FRAMENUM_COLOR 0xDDFFDD
#define LAG_FRAMENUM_COLOR 0xDBDAFF
#define NORMAL_INPUT_COLOR1 0xF0F0F0
#define UNDOHINT_INPUT_COLOR1 0xF6CCDD
#define CUR_INPUT_COLOR1 0xF7E9B2
#define GREENZONE_INPUT_COLOR1 0xC3FFC3
#define LAG_INPUT_COLOR1 0xCCC8EE
#define NORMAL_INPUT_COLOR2 0xDEDEDE
#define UNDOHINT_INPUT_COLOR2 0xE5B7CC
#define CUR_INPUT_COLOR2 0xE4D8A8
#define GREENZONE_INPUT_COLOR2 0xAEE2AE
#define LAG_INPUT_COLOR2 0xB8B3E2
#define MARKED_UNDOHINT_FRAMENUM_COLOR 0xE1E7EC
// greenzone cleaning masks
#define EVERY16TH 0xFFFFFFF0
#define EVERY8TH 0xFFFFFFF8
#define EVERY4TH 0xFFFFFFFC
#define EVERY2ND 0xFFFFFFFE
// -----------------------------
void EnterTasEdit();
void InitDialog();
@ -85,6 +104,7 @@ bool CheckItemVisible(int frame);
void FollowPlayback();
void FollowUndo();
void FollowSelection();
void FollowPauseframe();
void ClearSelection();
void ClearRowSelection(int index);
void AddFourscore();

View File

@ -26,6 +26,7 @@ void GREENZONE::init()
{
clearGreenzone();
reset();
next_cleaning_time = clock() + TIME_BETWEEN_CLEANINGS;
}
void GREENZONE::reset()
{
@ -34,7 +35,8 @@ void GREENZONE::reset()
}
void GREENZONE::update()
{
if (clock() > next_cleaning_time)
GreenzoneCleaning();
}
@ -63,10 +65,6 @@ void GREENZONE::TryDumpIncremental(bool lagFlag)
else
lag_history[currFrameCounter-1] = 0;
}
ClearGreenzoneTail();
}
bool GREENZONE::loadTasSavestate(int frame)
@ -90,18 +88,57 @@ void GREENZONE::storeTasSavestate(int frame)
ms.trim();
}
void GREENZONE::ClearGreenzoneTail()
void GREENZONE::GreenzoneCleaning()
{
int tail_frame = greenZoneCount-1 - TASEdit_greenzone_capacity;
if (tail_frame >= currFrameCounter) tail_frame = currFrameCounter - 1;
for (;tail_frame >= 0; tail_frame--)
int i = currFrameCounter - TASEdit_greenzone_capacity;
if (i < 0) goto none_changed;
int limit;
// 2x of 1/2
limit = i - 2 * TASEdit_greenzone_capacity;
if (limit < -1) limit = -1;
for (; i > limit; i--)
{
if (savestates[tail_frame].empty()) break;
ClearSavestate(tail_frame);
RedrawRow(tail_frame);
if ((i & 0x1) && !savestates[i].empty())
ClearSavestate(i);
}
if (i < 0) goto finish;
// 4x of 1/4
limit = i - 4 * TASEdit_greenzone_capacity;
if (limit < -1) limit = -1;
for (; i > limit; i--)
{
if ((i & 0x3) && !savestates[i].empty())
ClearSavestate(i);
}
if (i < 0) goto finish;
// 8x of 1/8
limit = i - 8 * TASEdit_greenzone_capacity;
if (limit < -1) limit = -1;
for (; i > limit; i--)
{
if ((i & 0x7) && !savestates[i].empty())
ClearSavestate(i);
}
if (i < 0) goto finish;
// 16x of 1/16
limit = i - 16 * TASEdit_greenzone_capacity;
if (limit < -1) limit = -1;
for (; i > limit; i--)
{
if ((i & 0xF) && !savestates[i].empty())
ClearSavestate(i);
}
// clear all remaining
for (; i >= 0; i--)
{
if (!savestates[i].empty())
ClearSavestate(i);
}
finish:
RedrawList();
none_changed:
// shedule next cleaning
next_cleaning_time = clock() + TIME_BETWEEN_CLEANINGS;
}
void GREENZONE::ClearSavestate(int index)
@ -110,7 +147,6 @@ void GREENZONE::ClearSavestate(int index)
savestates[index].swap(tmp);
}
void GREENZONE::clearGreenzone()
{
int size = savestates.size();
@ -144,6 +180,7 @@ void GREENZONE::save(EMUFILE *os)
// write playback position
write32le(currFrameCounter, os);
// write savestates
GreenzoneCleaning();
for (frame = 0; frame < greenZoneCount; ++frame)
{
// update TASEditor progressbar from time to time
@ -179,7 +216,6 @@ bool GREENZONE::load(EMUFILE *is)
{
greenZoneCount = size;
savestates.resize(greenZoneCount);
int greenzone_tail_frame = greenZoneCount-1 - TASEdit_greenzone_capacity;
// read and uncompress lag history
lag_history.resize(greenZoneCount);
int comprlen;
@ -194,11 +230,16 @@ bool GREENZONE::load(EMUFILE *is)
if (read32le((uint32 *)&frame, is))
{
currFrameCounter = frame;
int greenzone_tail_frame = currFrameCounter - TASEdit_greenzone_capacity;
int greenzone_tail_frame2 = greenzone_tail_frame - 2 * TASEdit_greenzone_capacity;
int greenzone_tail_frame4 = greenzone_tail_frame - 4 * TASEdit_greenzone_capacity;
int greenzone_tail_frame8 = greenzone_tail_frame - 8 * TASEdit_greenzone_capacity;
int greenzone_tail_frame16 = greenzone_tail_frame - 16 * TASEdit_greenzone_capacity;
// read savestates
while(1)
{
if (!read32le((uint32 *)&frame, is)) break;
if (frame == -1) break;
if (frame < 0) break; // -1 = eof
// update TASEditor progressbar from time to time
if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
{
@ -210,16 +251,20 @@ bool GREENZONE::load(EMUFILE *is)
// read savestate
if (!read32le((uint32 *)&size, is)) break;
if (size < 0) break;
if (frame > greenzone_tail_frame || frame == currFrameCounter)
{
// load savestate
savestates[frame].resize(size);
if ((int)is->fread(savestates[frame].data(),size) < size) break;
prev_frame = frame; // successfully read one greenzone frame info
} else
if (frame <= greenzone_tail_frame16
|| (frame <= greenzone_tail_frame8 && (frame & 0xF))
|| (frame <= greenzone_tail_frame4 && (frame & 0x7))
|| (frame <= greenzone_tail_frame2 && (frame & 0x3))
|| (frame <= greenzone_tail_frame && (frame & 0x1)))
{
// skip loading this savestate
if (is->fseek(size,SEEK_CUR) != 0) break;
if (is->fseek(size, SEEK_CUR) != 0) break;
} else
{
// load this savestate
savestates[frame].resize(size);
if ((int)is->fread(savestates[frame].data(), size) < size) break;
prev_frame = frame; // successfully read one greenzone frame info
}
}
if (prev_frame+1 == greenZoneCount)

View File

@ -1,6 +1,7 @@
//Specification file for Greenzone class
//#define LAG_FLAG_BIT 1
#define TIME_BETWEEN_CLEANINGS 10000 // in milliseconds
#define GREENZONE_ID_LEN 10
@ -20,7 +21,9 @@ public:
bool loadTasSavestate(int frame);
void storeTasSavestate(int frame);
void ClearGreenzoneTail();
void GreenzoneCleaning();
void ClearGreenzoneTail1();
void ClearSavestate(int index);
void InvalidateGreenZone(int after);
@ -33,6 +36,6 @@ public:
std::vector<uint8> lag_history;
private:
int next_cleaning_time;
};

View File

@ -171,6 +171,7 @@ void PLAYBACK::ToggleEmulationPause()
void PLAYBACK::PauseEmulation()
{
FCEUI_SetEmulationPaused(1);
RedrawList(); // to show some "pale" greenzone
// make some additional stuff
}
void PLAYBACK::UnpauseEmulation()
@ -192,12 +193,12 @@ void PLAYBACK::SeekingStop()
turbo = false;
PauseEmulation();
SetProgressbar(1, 1);
RedrawList(); // to show some "pale" greenzone
}
void PLAYBACK::RewindFrame()
{
if (currFrameCounter > 0) jump(currFrameCounter-1);
turbo = false;
FollowPlayback();
}
void PLAYBACK::ForwardFrame()
@ -260,7 +261,7 @@ void PLAYBACK::restorePosition()
bool PLAYBACK::JumpToFrame(int index)
{
// Returns true if a jump to the frame is made, false if started seeking or if nothing's done
// Returns true if a jump to the frame is made, false if started seeking outside greenzone or if nothing's done
if (index<0) return false;
if (index >= greenzone.greenZoneCount)
@ -293,7 +294,7 @@ bool PLAYBACK::JumpToFrame(int index)
// continue from the frame
if (index != currFrameCounter)
SeekingStart(index+1);
return false;
return true;
}
int PLAYBACK::GetPauseFrame()