diff --git a/src/drivers/win/config.cpp b/src/drivers/win/config.cpp index c9a9e59c..fd2c0fcb 100644 --- a/src/drivers/win/config.cpp +++ b/src/drivers/win/config.cpp @@ -353,6 +353,7 @@ static CFGSTRUCT fceuconfig[] = { AC(taseditor_config.findnote_matchcase), AC(taseditor_config.findnote_search_up), AC(taseditor_config.draw_input), + AC(taseditor_config.enable_greenzoning), AC(taseditor_config.silent_autosave), AC(taseditor_config.autopause_at_finish), AC(taseditor_config.tooltips), diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index bcb464ba..bb38e949 100644 --- a/src/drivers/win/res.rc +++ b/src/drivers/win/res.rc @@ -276,6 +276,7 @@ BEGIN MENUITEM "Set max Undo levels", ID_CONFIG_SETMAXUNDOLEVELS,MFT_STRING,MFS_ENABLED MENUITEM "Set Autosave period", ID_CONFIG_SETAUTOSAVEPERIOD,MFT_STRING,MFS_ENABLED MENUITEM MFT_SEPARATOR + MENUITEM "Enable Greenzoning", ID_CONFIG_ENABLEGREENZONING,MFT_STRING,MFS_ENABLED MENUITEM "Silent Autosave", ID_CONFIG_SILENTAUTOSAVE,MFT_STRING,MFS_ENABLED MENUITEM "Autofire Pattern skips Lag", ID_CONFIG_PATTERNSKIPSLAG,MFT_STRING,MFS_ENABLED MENUITEM "Auto-adjust Input according to Lag", ID_CONFIG_ADJUSTLAG,MFT_STRING,MFS_ENABLED @@ -386,6 +387,8 @@ BEGIN MENUITEM "Deselect", ID_SELECTED_DESELECT MENUITEM "Select between Markers\tCtrl+A", ID_SELECTED_SELECTMIDMARKERS MENUITEM SEPARATOR + MENUITEM "Ungreenzone", ID_SELECTED_UNGREENZONE + MENUITEM SEPARATOR MENUITEM "Clear\tDel", ID_CONTEXT_SELECTED_CLEARFRAMES MENUITEM "Delete\tCtrl+Del", ID_CONTEXT_SELECTED_DELETEFRAMES MENUITEM "Clone\tCtrl+Ins", ID_SELECTED_CLONE diff --git a/src/drivers/win/resource.h b/src/drivers/win/resource.h index 089b4dad..71a84443 100644 --- a/src/drivers/win/resource.h +++ b/src/drivers/win/resource.h @@ -1141,6 +1141,9 @@ #define ID_CONFIG_PATTERNSKIPSLAG 40568 #define CLEAR_LOG 40569 #define CLOSE_LOG 40570 +#define ID_SELECTED_UNGREENZONE 40571 +#define ID_SELECTED_F 40572 +#define ID_CONFIG_ENABLEGREENZONING 40573 #define IDC_DEBUGGER_ICONTRAY 55535 #define MW_ValueLabel2 65423 #define MW_ValueLabel1 65426 @@ -1151,7 +1154,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 289 -#define _APS_NEXT_COMMAND_VALUE 40571 +#define _APS_NEXT_COMMAND_VALUE 40574 #define _APS_NEXT_CONTROL_VALUE 1282 #define _APS_NEXT_SYMED_VALUE 101 #endif diff --git a/src/drivers/win/taseditor.cpp b/src/drivers/win/taseditor.cpp index 9c1bbf0b..dcd72b9a 100644 --- a/src/drivers/win/taseditor.cpp +++ b/src/drivers/win/taseditor.cpp @@ -116,7 +116,7 @@ bool EnterTasEditor() history.init(); taseditor_lua.init(); // either start new movie or use current movie - if (FCEUMOV_Mode(MOVIEMODE_INACTIVE) || currMovieData.savestate.size() != 0) + if (!FCEUMOV_Mode(MOVIEMODE_RECORD|MOVIEMODE_PLAY) || currMovieData.savestate.size() != 0) { if (currMovieData.savestate.size() != 0) FCEUD_PrintError("This version of TAS Editor doesn't work with movies starting from savestate."); @@ -131,6 +131,9 @@ bool EnterTasEditor() FCEUI_StopMovie(); movieMode = MOVIEMODE_TASEDITOR; } + // if movie length is less or equal to currFrame, pad it with empty frames + if (((int)currMovieData.records.size() - 1) < currFrameCounter) + currMovieData.insertEmpty(-1, currFrameCounter - ((int)currMovieData.records.size() - 1)); // ensure that movie has correct set of ports/fourscore SetInputType(currMovieData, GetInputType(currMovieData)); // force the input configuration stored in the movie to apply to FCEUX config diff --git a/src/drivers/win/taseditor/bookmarks.cpp b/src/drivers/win/taseditor/bookmarks.cpp index a429b439..53481758 100644 --- a/src/drivers/win/taseditor/bookmarks.cpp +++ b/src/drivers/win/taseditor/bookmarks.cpp @@ -451,7 +451,7 @@ void BOOKMARKS::deploy(int slot) // jump to the target (bookmarked frame) if (greenzone.SavestateIsEmpty(keyframe)) greenzone.WriteSavestate(keyframe, bookmarks_array[slot].savestate); - playback.jump(keyframe); + playback.jump(keyframe, true); // switch current branch to this branch int old_current_branch = branches.GetCurrentBranch(); branches.HandleBookmarkDeploy(slot); diff --git a/src/drivers/win/taseditor/greenzone.cpp b/src/drivers/win/taseditor/greenzone.cpp index c24eaab9..d42e780c 100644 --- a/src/drivers/win/taseditor/greenzone.cpp +++ b/src/drivers/win/taseditor/greenzone.cpp @@ -59,30 +59,20 @@ void GREENZONE::reset() } void GREENZONE::update() { - // keep collecting savestates, this function must be called at the end of every frame - CollectCurrentState(); + // keep collecting savestates, this code must be executed at the end of every frame + if (taseditor_config.enable_greenzoning) + { + CollectCurrentState(); + } else + { + // just update Greenzone upper limit + if (greenZoneCount <= currFrameCounter) + greenZoneCount = currFrameCounter + 1; + } // run cleaning from time to time if (clock() > next_cleaning_time) RunGreenzoneCleaning(); -} - -void GREENZONE::CollectCurrentState() -{ - // update Greenzone upper limit if needed - if (greenZoneCount <= currFrameCounter) - greenZoneCount = currFrameCounter + 1; - - if ((int)savestates.size() < greenZoneCount) - savestates.resize(greenZoneCount); - - // if frame is not saved - log savestate - if (!savestates[currFrameCounter].size()) - { - EMUFILE_MEMORY ms(&savestates[currFrameCounter]); - FCEUSS_SaveMS(&ms, Z_DEFAULT_COMPRESSION); - ms.trim(); - } // also log lag frames if (currFrameCounter > 0) @@ -111,21 +101,33 @@ void GREENZONE::CollectCurrentState() } } -bool GREENZONE::loadTasSavestate(int frame) +void GREENZONE::CollectCurrentState() { - if (frame < 0 || frame >= currMovieData.getNumRecords()) - return false; - if ((int)savestates.size() <= frame || !savestates[frame].size()) - return false; + if ((int)savestates.size() <= currFrameCounter) + savestates.resize(currFrameCounter + 1); + // if frame is not saved - log savestate + if (!savestates[currFrameCounter].size()) + { + EMUFILE_MEMORY ms(&savestates[currFrameCounter]); + FCEUSS_SaveMS(&ms, Z_DEFAULT_COMPRESSION); + ms.trim(); + } + if (greenZoneCount <= currFrameCounter) + greenZoneCount = currFrameCounter + 1; +} +bool GREENZONE::LoadSavestate(unsigned int frame) +{ + if (frame >= savestates.size() || !savestates[frame].size()) + return false; EMUFILE_MEMORY ms(&savestates[frame]); return FCEUSS_LoadFP(&ms, SSLOADPARAM_NOBACKUP); } void GREENZONE::RunGreenzoneCleaning() { - int i = currFrameCounter - taseditor_config.greenzone_capacity; bool changed = false; + int i = currFrameCounter - taseditor_config.greenzone_capacity; if (i <= 0) goto finish; // zeroth frame should not be cleaned int limit; // 2x of 1/2 @@ -133,11 +135,8 @@ void GREENZONE::RunGreenzoneCleaning() if (limit < 0) limit = 0; for (; i > limit; i--) { - if ((i & 0x1) && savestates[i].size()) - { - ClearSavestateAndFreeMemory(i); - changed = true; - } + if (i & 0x1) + changed = changed | ClearSavestateAndFreeMemory(i); } if (i < 0) goto finish; // 4x of 1/4 @@ -145,11 +144,8 @@ void GREENZONE::RunGreenzoneCleaning() if (limit < 0) limit = 0; for (; i > limit; i--) { - if ((i & 0x3) && savestates[i].size()) - { - ClearSavestateAndFreeMemory(i); - changed = true; - } + if (i & 0x3) + changed = changed | ClearSavestateAndFreeMemory(i); } if (i < 0) goto finish; // 8x of 1/8 @@ -157,11 +153,8 @@ void GREENZONE::RunGreenzoneCleaning() if (limit < 0) limit = 0; for (; i > limit; i--) { - if ((i & 0x7) && savestates[i].size()) - { - ClearSavestateAndFreeMemory(i); - changed = true; - } + if (i & 0x7) + changed = changed | ClearSavestateAndFreeMemory(i); } if (i < 0) goto finish; // 16x of 1/16 @@ -169,20 +162,13 @@ void GREENZONE::RunGreenzoneCleaning() if (limit < 0) limit = 0; for (; i > limit; i--) { - if ((i & 0xF) && savestates[i].size()) - { - ClearSavestateAndFreeMemory(i); - changed = true; - } + if (i & 0xF) + changed = changed | ClearSavestateAndFreeMemory(i); } // clear all remaining for (; i > 0; i--) { - if (savestates[i].size()) - { - ClearSavestateAndFreeMemory(i); - changed = true; - } + changed = changed | ClearSavestateAndFreeMemory(i); } finish: if (changed) @@ -194,14 +180,48 @@ finish: next_cleaning_time = clock() + TIME_BETWEEN_CLEANINGS; } -void GREENZONE::ClearSavestate(int index) +// returns true if actually cleared savestate data +bool GREENZONE::ClearSavestate(unsigned int index) { - savestates[index].resize(0); + if (index < savestates.size() && savestates[index].size()) + { + savestates[index].resize(0); + return true; + } else + { + return false; + } } -void GREENZONE::ClearSavestateAndFreeMemory(int index) +bool GREENZONE::ClearSavestateAndFreeMemory(unsigned int index) { - savestates[index].swap(std::vector()); + if (index < savestates.size() && savestates[index].size()) + { + savestates[index].swap(std::vector()); + return true; + } else + { + return false; + } +} + +void GREENZONE::UnGreenzoneSelectedFrames() +{ + SelectionFrames* current_selection = selection.MakeStrobe(); + if (current_selection->size() == 0) return; + bool changed = false; + int size = savestates.size(); + int start_index = *current_selection->begin(); + int end_index = *current_selection->rbegin(); + SelectionFrames::reverse_iterator current_selection_rend = current_selection->rend(); + // degreenzone frames, going backwards + for (SelectionFrames::reverse_iterator it(current_selection->rbegin()); it != current_selection_rend; it++) + changed = changed | ClearSavestateAndFreeMemory(*it); + if (changed) + { + piano_roll.RedrawList(); + bookmarks.RedrawBookmarksList(); + } } void GREENZONE::save(EMUFILE *os, bool really_save) @@ -216,10 +236,12 @@ void GREENZONE::save(EMUFILE *os, bool really_save) write32le(greenZoneCount, os); // write Playback cursor position write32le(currFrameCounter, os); + CollectCurrentState(); // write savestates int frame, size; int last_tick = 0; RunGreenzoneCleaning(); + if (greenZoneCount > (int)savestates.size()) greenZoneCount = savestates.size(); for (frame = 0; frame < greenZoneCount; ++frame) { // update TASEditor progressbar from time to time @@ -248,6 +270,7 @@ void GREENZONE::save(EMUFILE *os, bool really_save) if (currFrameCounter > 0) { // write ONE savestate for currFrameCounter + CollectCurrentState(); int size = savestates[currFrameCounter].size(); write32le(size, os); os->fwrite(&savestates[currFrameCounter][0], size); @@ -291,7 +314,7 @@ bool GREENZONE::load(EMUFILE *is, unsigned int offset) savestates[frame].resize(size); if (is->fread(&savestates[frame][0], size) == size) { - if (loadTasSavestate(currFrameCounter)) + if (LoadSavestate(currFrameCounter)) { FCEU_printf("No Greenzone in the file\n"); return false; @@ -359,12 +382,12 @@ bool GREENZONE::load(EMUFILE *is, unsigned int offset) if (prev_frame+1 == greenZoneCount) { // everything went fine - load savestate at cursor position - if (loadTasSavestate(currFrameCounter)) + if (LoadSavestate(currFrameCounter)) return false; } // uh, okay, but maybe we managed to read at least something useful from the file // first see if original position of currFrameCounter was read successfully - if (loadTasSavestate(currFrameCounter)) + if (LoadSavestate(currFrameCounter)) { greenZoneCount = prev_frame+1; // cut greenZoneCount to last good frame FCEU_printf("Greenzone loaded partially\n"); @@ -373,7 +396,7 @@ bool GREENZONE::load(EMUFILE *is, unsigned int offset) // then at least jump to some frame that was read successfully for (; prev_frame >= 0; prev_frame--) { - if (loadTasSavestate(prev_frame)) + if (LoadSavestate(prev_frame)) { currFrameCounter = prev_frame; greenZoneCount = prev_frame+1; // cut greenZoneCount to this good frame @@ -425,7 +448,7 @@ void GREENZONE::AdjustUp() Invalidate(first_input_changes); bool emu_was_paused = (FCEUI_EmulationPaused() != 0); int saved_pause_frame = playback.GetPauseFrame(); - playback.jump(first_input_changes); + playback.EnsurePlaybackIsInsideGreenzone(); if (saved_pause_frame >= 0) playback.SeekingStart(saved_pause_frame); if (emu_was_paused) @@ -462,7 +485,7 @@ void GREENZONE::AdjustDown() Invalidate(first_input_chanes); bool emu_was_paused = (FCEUI_EmulationPaused() != 0); int saved_pause_frame = playback.GetPauseFrame(); - playback.jump(first_input_chanes); + playback.EnsurePlaybackIsInsideGreenzone(); if (saved_pause_frame >= 0) playback.SeekingStart(saved_pause_frame); if (emu_was_paused) @@ -483,17 +506,14 @@ void GREENZONE::InvalidateAndCheck(int after) { if (after >= currMovieData.getNumRecords()) after = currMovieData.getNumRecords() - 1; + // clear all savestates that became irrelevant + for (int i = savestates.size() - 1; i > after; i--) + ClearSavestate(i); if (greenZoneCount > after + 1 || currFrameCounter > after) { - // clear all savestates that became irrelevant - for (int i = greenZoneCount - 1; i > after; i--) - { - if (savestates[i].size()) - ClearSavestate(i); - } greenZoneCount = after + 1; currMovieData.rerecordCount++; - // either set Playback cursor to the end of Greenzone or run seeking to restore Playback cursor position + // either set Playback cursor to be inside the Greenzone or run seeking to restore Playback cursor position if (currFrameCounter >= greenZoneCount) { if (playback.GetPauseFrame() >= 0 && !FCEUI_EmulationPaused()) @@ -504,10 +524,10 @@ void GREENZONE::InvalidateAndCheck(int after) { playback.SetLostPosition(currFrameCounter); if (taseditor_config.restore_position) - // start seeking + // start seeking to the green arrow playback.jump(playback.GetLostPosition()); else - playback.jump(greenZoneCount - 1); + playback.EnsurePlaybackIsInsideGreenzone(); } } } @@ -523,14 +543,11 @@ void GREENZONE::Invalidate(int after) { if (after >= currMovieData.getNumRecords()) after = currMovieData.getNumRecords() - 1; + // clear all savestates that became irrelevant + for (int i = savestates.size() - 1; i > after; i--) + ClearSavestate(i); if (greenZoneCount > after + 1) { - // clear all savestates that became irrelevant - for (int i = greenZoneCount - 1; i > after; i--) - { - if (savestates[i].size()) - ClearSavestate(i); - } greenZoneCount = after + 1; currMovieData.rerecordCount++; } @@ -568,9 +585,9 @@ void GREENZONE::WriteSavestate(int frame, std::vector& savestate) greenZoneCount = frame + 1; } -bool GREENZONE::SavestateIsEmpty(int frame) +bool GREENZONE::SavestateIsEmpty(unsigned int frame) { - if (frame < greenZoneCount && frame < (int)savestates.size() && savestates[frame].size()) + if ((int)frame < greenZoneCount && frame < savestates.size() && savestates[frame].size()) return false; else return true; diff --git a/src/drivers/win/taseditor/greenzone.h b/src/drivers/win/taseditor/greenzone.h index 8953cf26..08dcbe07 100644 --- a/src/drivers/win/taseditor/greenzone.h +++ b/src/drivers/win/taseditor/greenzone.h @@ -25,14 +25,11 @@ public: void save(EMUFILE *os, bool really_save = true); bool load(EMUFILE *is, unsigned int offset); - void AdjustUp(); - void AdjustDown(); - - bool loadTasSavestate(int frame); + bool LoadSavestate(unsigned int frame); void RunGreenzoneCleaning(); - void ClearSavestate(int index); - void ClearSavestateAndFreeMemory(int index); + + void UnGreenzoneSelectedFrames(); void InvalidateAndCheck(int after); void Invalidate(int after); @@ -42,13 +39,18 @@ public: int GetSize(); std::vector& GetSavestate(int frame); void WriteSavestate(int frame, std::vector& savestate); - bool SavestateIsEmpty(int frame); + bool SavestateIsEmpty(unsigned int frame); // saved data LAGLOG laglog; private: void CollectCurrentState(); + bool ClearSavestate(unsigned int index); + bool ClearSavestateAndFreeMemory(unsigned int index); + + void AdjustUp(); + void AdjustDown(); // saved data int greenZoneCount; diff --git a/src/drivers/win/taseditor/playback.cpp b/src/drivers/win/taseditor/playback.cpp index c008844d..00e48645 100644 --- a/src/drivers/win/taseditor/playback.cpp +++ b/src/drivers/win/taseditor/playback.cpp @@ -240,7 +240,7 @@ void PLAYBACK::update() } // called after saving the project, because saving uses the progressbar for itself -void PLAYBACK::updateProgressbar() +void PLAYBACK::UpdateProgressbar() { if (pause_frame) { @@ -438,11 +438,10 @@ void PLAYBACK::StartFromZero() currMovieData.insertEmpty(-1, 1); } -// external interface for sending Playback cursor -void PLAYBACK::jump(int frame, bool execute_lua, bool follow_cursor) +void PLAYBACK::EnsurePlaybackIsInsideGreenzone(bool execute_lua, bool follow_cursor) { - if (frame < 0) return; - if (JumpToFrame(frame)) + // set the Playback cursor to the frame or at least above the frame + if (SetPlaybackAboveOrToFrame(greenzone.GetSize() - 1)) { // since the game state was changed by this jump, we must update possible Lua callbacks and other tools that would normally only update in FCEUI_Emulate if (execute_lua) @@ -452,44 +451,63 @@ void PLAYBACK::jump(int frame, bool execute_lua, bool follow_cursor) Update_RAM_Search(); // Update_RAM_Watch() is also called. } } -// internal interface -// returns true if the game state was changed (loaded) -bool PLAYBACK::JumpToFrame(int index) + +// an interface for sending Playback cursor to any frame +void PLAYBACK::jump(int frame, bool force_reload, bool execute_lua, bool follow_cursor) { - if (index >= greenzone.GetSize()) + if (frame < 0) return; + + // 1 - set the Playback cursor to the frame or at least above the frame + if (SetPlaybackAboveOrToFrame(frame, force_reload)) { - // make jump outside Greenzone - if (currFrameCounter == greenzone.GetSize() - 1) + // since the game state was changed by this jump, we must update possible Lua callbacks and other tools that would normally only update in FCEUI_Emulate + if (execute_lua) + ForceExecuteLuaFrameFunctions(); + if (follow_cursor) + piano_roll.FollowPlaybackIfNeeded(); + Update_RAM_Search(); // Update_RAM_Watch() is also called. + } + + // 2 - seek from the current frame if we still aren't at the needed frame + if (frame > currFrameCounter) + { + SeekingStart(frame); + } else + { + // the Playback is already at the needed frame + if (pause_frame) // if Playback was seeking, pause emulation right here + SeekingStop(); + } +} + +// returns true if the game state was changed (loaded) +bool PLAYBACK::SetPlaybackAboveOrToFrame(int frame, bool force_reload) +{ + bool state_changed = false; + // search backwards for an earlier frame with valid savestate + int i = greenzone.GetSize() - 1; + if (i > frame) + i = frame; + for (; i >= 0; i--) + { + if (!force_reload && !state_changed && i == currFrameCounter) { - // seek there from the end of Greenzone - SeekingStart(index); - return false; // game state was not changed - } else if (JumpToFrame(greenzone.GetSize() - 1)) + // we can remain at current game state + break; + } else if (!greenzone.SavestateIsEmpty(i)) { - // seek there from the end of Greenzone - SeekingStart(index); - return true; // game state was loaded + state_changed = true; // after we once tried loading a savestate, we cannot use currFrameCounter state anymore, because the game state might have been corrupted by this loading attempt + if (greenzone.LoadSavestate(i)) + break; } } - // make jump inside greenzone - if (greenzone.loadTasSavestate(index)) - { - // successfully restored emulator state at this frame - // if Playback was seeking, pause emulation right here - if (pause_frame) - SeekingStop(); - return true; - } - // search for an earlier frame with savestate - int i = (index > 0) ? index-1 : 0; - for (; i >= 0; i--) - if (greenzone.loadTasSavestate(i)) break; if (i < 0) - StartFromZero(); // couldn't find a savestate - // continue from the frame - if (index != currFrameCounter) - SeekingStart(index); - return true; + { + // couldn't find a savestate + StartFromZero(); + state_changed = true; + } + return state_changed; } void PLAYBACK::SetLostPosition(int frame) diff --git a/src/drivers/win/taseditor/playback.h b/src/drivers/win/taseditor/playback.h index aefefeeb..100e208a 100644 --- a/src/drivers/win/taseditor/playback.h +++ b/src/drivers/win/taseditor/playback.h @@ -16,9 +16,10 @@ public: void reset(); void update(); - void jump(int frame, bool execute_lua = true, bool follow_cursor = true); + void EnsurePlaybackIsInsideGreenzone(bool execute_lua = true, bool follow_cursor = true); + void jump(int frame, bool force_reload = false, bool execute_lua = true, bool follow_cursor = true); - void updateProgressbar(); + void UpdateProgressbar(); void SeekingStart(int finish_frame); void SeekingStop(); @@ -55,7 +56,7 @@ public: HWND hwndPlaybackMarker, hwndPlaybackMarkerEdit; private: - bool JumpToFrame(int index); + bool SetPlaybackAboveOrToFrame(int frame, bool force_reload = false); int pause_frame; int lost_position_frame; diff --git a/src/drivers/win/taseditor/taseditor_config.cpp b/src/drivers/win/taseditor/taseditor_config.cpp index 81dc7d76..09b08906 100644 --- a/src/drivers/win/taseditor/taseditor_config.cpp +++ b/src/drivers/win/taseditor/taseditor_config.cpp @@ -68,6 +68,7 @@ TASEDITOR_CONFIG::TASEDITOR_CONFIG() findnote_search_up = false; enable_auto_function = true; draw_input = true; + enable_greenzoning = true; silent_autosave = true; autopause_at_finish = true; tooltips = true; diff --git a/src/drivers/win/taseditor/taseditor_config.h b/src/drivers/win/taseditor/taseditor_config.h index 2bbfa426..9cd5e81f 100644 --- a/src/drivers/win/taseditor/taseditor_config.h +++ b/src/drivers/win/taseditor/taseditor_config.h @@ -66,6 +66,7 @@ public: bool findnote_search_up; bool enable_auto_function; bool draw_input; + bool enable_greenzoning; bool silent_autosave; bool autopause_at_finish; bool tooltips; diff --git a/src/drivers/win/taseditor/taseditor_lua.cpp b/src/drivers/win/taseditor/taseditor_lua.cpp index a8b10cdd..6a561a06 100644 --- a/src/drivers/win/taseditor/taseditor_lua.cpp +++ b/src/drivers/win/taseditor/taseditor_lua.cpp @@ -243,7 +243,9 @@ int TASEDITOR_LUA::getplaybacktarget() void TASEDITOR_LUA::setplayback(int frame) { if (FCEUMOV_Mode(MOVIEMODE_TASEDITOR)) - playback.jump(frame, false, true); + // force reload if sending to the same frame as current frame + // but don't trigger lua registered functions + playback.jump(frame, true, false, true); } // taseditor.stopseeking() diff --git a/src/drivers/win/taseditor/taseditor_project.cpp b/src/drivers/win/taseditor/taseditor_project.cpp index 4f9af17a..82914f61 100644 --- a/src/drivers/win/taseditor/taseditor_project.cpp +++ b/src/drivers/win/taseditor/taseditor_project.cpp @@ -167,7 +167,7 @@ bool TASEDITOR_PROJECT::save(const char* different_name, bool save_binary, bool write32le(selection_offset, ofs); // finish delete ofs; - playback.updateProgressbar(); + playback.UpdateProgressbar(); // also set project.changed to false, unless it was SaveCompact if (!different_name) reset(); diff --git a/src/drivers/win/taseditor/taseditor_window.cpp b/src/drivers/win/taseditor/taseditor_window.cpp index 1720c0ff..b0c140e5 100644 --- a/src/drivers/win/taseditor/taseditor_window.cpp +++ b/src/drivers/win/taseditor/taseditor_window.cpp @@ -564,6 +564,7 @@ void TASEDITOR_WINDOW::UpdateCheckedItems() CheckMenuItem(hmenu, ID_VIEW_ENABLEHOTCHANGES, taseditor_config.enable_hot_changes?MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, ID_VIEW_JUMPWHENMAKINGUNDO, taseditor_config.jump_to_undo?MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, ID_VIEW_FOLLOWMARKERNOTECONTEXT, taseditor_config.follow_note_context?MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hmenu, ID_CONFIG_ENABLEGREENZONING, taseditor_config.enable_greenzoning?MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, ID_CONFIG_SILENTAUTOSAVE, taseditor_config.silent_autosave?MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, ID_CONFIG_PATTERNSKIPSLAG, taseditor_config.pattern_skips_lag?MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, ID_CONFIG_ADJUSTLAG, taseditor_config.adjust_input_due_to_lag?MF_CHECKED : MF_UNCHECKED); @@ -923,6 +924,12 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara else if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION) selection.SelectAll(); break; + case ID_SELECTED_UNGREENZONE: + if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION) + { + greenzone.UnGreenzoneSelectedFrames(); + } + break; case ACCEL_CTRL_X: case ID_EDIT_CUT: if (markers_manager.marker_note_edit == MARKER_NOTE_EDIT_UPPER) @@ -1089,6 +1096,14 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara } break; } + case ID_CONFIG_ENABLEGREENZONING: + taseditor_config.enable_greenzoning ^= 1; + taseditor_window.UpdateCheckedItems(); + break; + case ID_CONFIG_SILENTAUTOSAVE: + taseditor_config.silent_autosave ^= 1; + taseditor_window.UpdateCheckedItems(); + break; case ID_CONFIG_BRANCHESRESTOREFULLMOVIE: taseditor_config.branch_full_movie ^= 1; taseditor_window.UpdateCheckedItems(); @@ -1131,10 +1146,6 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara taseditor_config.draw_input ^= 1; taseditor_window.UpdateCheckedItems(); break; - case ID_CONFIG_SILENTAUTOSAVE: - taseditor_config.silent_autosave ^= 1; - taseditor_window.UpdateCheckedItems(); - break; case ID_CONFIG_AUTOPAUSEATTHEENDOFMOVIE: taseditor_config.autopause_at_finish ^= 1; taseditor_window.UpdateCheckedItems(); diff --git a/src/version.h b/src/version.h index 8fde7aba..74d6ed04 100644 --- a/src/version.h +++ b/src/version.h @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +//#define PUBLIC_RELEASE // uncommend this when making a public release, but comment back before committing + #ifndef __FCEU_VERSION #define __FCEU_VERSION