From 383baa85c4f2f69df16bbc6a5a5548a06c872f8c Mon Sep 17 00:00:00 2001 From: ansstuff Date: Thu, 20 Oct 2011 22:31:30 +0000 Subject: [PATCH] * Tasedit: gradual greenzone cleaning --- src/drivers/win/tasedit.cpp | 100 ++++++++++++++++------- src/drivers/win/tasedit.h | 52 ++++++++---- src/drivers/win/taseditlib/greenzone.cpp | 95 +++++++++++++++------ src/drivers/win/taseditlib/greenzone.h | 7 +- src/drivers/win/taseditlib/playback.cpp | 7 +- 5 files changed, 187 insertions(+), 74 deletions(-) diff --git a/src/drivers/win/tasedit.cpp b/src/drivers/win/tasedit.cpp index ae2cd6c1..4a774a7a 100644 --- a/src/drivers/win/tasedit.cpp +++ b/src/drivers/win/tasedit.cpp @@ -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() { diff --git a/src/drivers/win/tasedit.h b/src/drivers/win/tasedit.h index 7bb72f9b..7c749a0f 100644 --- a/src/drivers/win/tasedit.h +++ b/src/drivers/win/tasedit.h @@ -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(); diff --git a/src/drivers/win/taseditlib/greenzone.cpp b/src/drivers/win/taseditlib/greenzone.cpp index e98eb3e6..181943d4 100644 --- a/src/drivers/win/taseditlib/greenzone.cpp +++ b/src/drivers/win/taseditlib/greenzone.cpp @@ -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) diff --git a/src/drivers/win/taseditlib/greenzone.h b/src/drivers/win/taseditlib/greenzone.h index 2af209f0..095e6808 100644 --- a/src/drivers/win/taseditlib/greenzone.h +++ b/src/drivers/win/taseditlib/greenzone.h @@ -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 lag_history; private: - + int next_cleaning_time; }; diff --git a/src/drivers/win/taseditlib/playback.cpp b/src/drivers/win/taseditlib/playback.cpp index 6ba4cab6..142ed54f 100644 --- a/src/drivers/win/taseditlib/playback.cpp +++ b/src/drivers/win/taseditlib/playback.cpp @@ -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()