* Tasedit: progressbar

* Tasedit: "||" button accepts double clicks
* Tasedit: holding "<" and ">" buttons
* Tasedit: Ctrl-Delete leaves selection
This commit is contained in:
ansstuff 2011-09-25 18:17:26 +00:00
parent 8e19af540e
commit 92ff246e15
7 changed files with 306 additions and 170 deletions

View File

@ -953,6 +953,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
//Show the record movie dialog and record a movie. //Show the record movie dialog and record a movie.
void FCEUD_MovieRecordTo() void FCEUD_MovieRecordTo()
{ {
if (!GameInfo) return;
static struct CreateMovieParameters p; static struct CreateMovieParameters p;
p.szFilename = strdup(FCEU_MakeFName(FCEUMKF_MOVIE,0,0).c_str()); p.szFilename = strdup(FCEU_MakeFName(FCEUMKF_MOVIE,0,0).c_str());
if(p.recordFrom >= 2) p.recordFrom=1; if(p.recordFrom >= 2) p.recordFrom=1;

View File

@ -1344,20 +1344,22 @@ MENU TASEDITMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSORTHEADER | WS_BORDER,6,5,310,370 CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSORTHEADER | WS_BORDER,6,5,310,370
GROUPBOX "Playback control",IDC_STATIC,322,5,118,40,BS_CENTER,WS_EX_RIGHT GROUPBOX "Playback control",IDC_STATIC,322,5,118,49,BS_CENTER,WS_EX_RIGHT
PUSHBUTTON "<<",TASEDIT_REWIND_FULL,326,14,22,14,NOT WS_TABSTOP PUSHBUTTON "<<",TASEDIT_REWIND_FULL,326,14,22,14,NOT WS_TABSTOP
PUSHBUTTON "<",TASEDIT_REWIND,348,14,22,14,NOT WS_TABSTOP PUSHBUTTON "<",TASEDIT_REWIND,348,14,22,14,NOT WS_TABSTOP
PUSHBUTTON "||",TASEDIT_PLAYSTOP,370,14,22,14,NOT WS_TABSTOP PUSHBUTTON "||",TASEDIT_PLAYSTOP,370,14,22,14,NOT WS_TABSTOP
PUSHBUTTON ">",TASEDIT_FOWARD,392,14,22,14,NOT WS_TABSTOP PUSHBUTTON ">",TASEDIT_FORWARD,392,14,22,14,NOT WS_TABSTOP
PUSHBUTTON ">>",TASEDIT_FOWARD_FULL,414,14,22,14,NOT WS_TABSTOP PUSHBUTTON ">>",TASEDIT_FORWARD_FULL,414,14,22,14,NOT WS_TABSTOP
CONTROL " Auto-restore last position",CHECK_AUTORESTORE_PLAYBACK, CONTROL " Auto-restore last position",CHECK_AUTORESTORE_PLAYBACK,
"Button",BS_AUTOCHECKBOX,328,31,105,12 "Button",BS_AUTOCHECKBOX,328,31,105,12
GROUPBOX "Recording input",IDC_STATIC,322,46,118,62,BS_CENTER,WS_EX_RIGHT GROUPBOX "Recording input",IDC_STATIC,322,55,118,58,BS_CENTER,WS_EX_RIGHT
GROUPBOX "Editing input",IDC_STATIC,322,109,118,38,BS_CENTER,WS_EX_RIGHT GROUPBOX "Editing input",IDC_STATIC,322,114,118,33,BS_CENTER,WS_EX_RIGHT
GROUPBOX "Bookmarks",IDC_STATIC,322,148,118,103,BS_CENTER,WS_EX_RIGHT GROUPBOX "Bookmarks",IDC_STATIC,322,148,118,103,BS_CENTER,WS_EX_RIGHT
CONTROL "",IDC_LIST3,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,327,159,108,88 CONTROL "",IDC_LIST3,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,327,159,108,88
GROUPBOX "Project Input Logs",IDC_STATIC,322,252,118,123,BS_CENTER,WS_EX_RIGHT GROUPBOX "Project Input Logs",IDC_STATIC,322,252,118,123,BS_CENTER,WS_EX_RIGHT
CONTROL "",IDC_LIST2,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,327,263,108,108,WS_EX_LEFTSCROLLBAR CONTROL "",IDC_LIST2,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,327,263,108,108,WS_EX_LEFTSCROLLBAR
CONTROL "",IDC_PROGRESS_BUTTON,"Button",BS_OWNERDRAW | WS_TABSTOP,326,41,110,12
CONTROL "",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,326,44,110,6
END END
ASSEMBLER DIALOGEX 0, 0, 202, 135 ASSEMBLER DIALOGEX 0, 0, 202, 135

View File

@ -374,11 +374,11 @@
#define MEMW_EXPANDCOLLAPSE 1133 #define MEMW_EXPANDCOLLAPSE 1133
#define IDC_SOUND_RESTOREDEFAULTVOL 1133 #define IDC_SOUND_RESTOREDEFAULTVOL 1133
#define IDC_BUTTON2 1134 #define IDC_BUTTON2 1134
#define TASEDIT_FOWARD 1134 #define TASEDIT_FORWARD 1134
#define IDC_BUTTON3 1135 #define IDC_BUTTON3 1135
#define TASEDIT_REWIND_FULL 1135 #define TASEDIT_REWIND_FULL 1135
#define IDC_BUTTON4 1136 #define IDC_BUTTON4 1136
#define TASEDIT_FOWARD_FULL 1136 #define TASEDIT_FORWARD_FULL 1136
#define TASEDIT_REWIND2 1137 #define TASEDIT_REWIND2 1137
#define TASEDIT_PLAYSTOP 1137 #define TASEDIT_PLAYSTOP 1137
#define IDC_RADIO1 1138 #define IDC_RADIO1 1138
@ -386,7 +386,7 @@
#define IDC_RADIO3 1140 #define IDC_RADIO3 1140
#define MEMW_EDIT00FORMULA 1142 #define MEMW_EDIT00FORMULA 1142
#define MEMW_EDIT01FORMULA 1143 #define MEMW_EDIT01FORMULA 1143
#define IDC_BUTTON5 1144 #define IDC_PROGRESS_BUTTON 1144
#define MEMW_EDIT02FORMULA 1144 #define MEMW_EDIT02FORMULA 1144
#define IDC_BUTTON7 1145 #define IDC_BUTTON7 1145
#define MEMW_EDIT03FORMULA 1145 #define MEMW_EDIT03FORMULA 1145
@ -493,6 +493,7 @@
#define IDC_C_WATCH_SEPARATE 1259 #define IDC_C_WATCH_SEPARATE 1259
#define IDC_TWEAKCOUNT 1260 #define IDC_TWEAKCOUNT 1260
#define CHECK_AUTORESTORE_PLAYBACK 1261 #define CHECK_AUTORESTORE_PLAYBACK 1261
#define IDC_PROGRESS1 1262
#define MENU_NETWORK 40040 #define MENU_NETWORK 40040
#define MENU_PALETTE 40041 #define MENU_PALETTE 40041
#define MENU_SOUND 40042 #define MENU_SOUND 40042
@ -839,7 +840,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 160 #define _APS_NEXT_RESOURCE_VALUE 160
#define _APS_NEXT_COMMAND_VALUE 40441 #define _APS_NEXT_COMMAND_VALUE 40441
#define _APS_NEXT_CONTROL_VALUE 1262 #define _APS_NEXT_CONTROL_VALUE 1263
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101
#endif #endif
#endif #endif

View File

@ -25,9 +25,13 @@ using namespace std;
int old_movie_readonly = -1; int old_movie_readonly = -1;
int lastCursor; int lastCursor;
bool old_emu_paused;
int old_pauseframe; int old_pauseframe;
bool old_show_pauseframe; bool old_show_pauseframe, show_pauseframe;
bool show_pauseframe; bool old_rewind_button_state, rewind_button_state;
bool old_forward_button_state, forward_button_state;
int button_hold_time;
int seeking_start_frame = 0;
bool TASEdit_focus = false; bool TASEdit_focus = false;
int saved_eoptions = 0; int saved_eoptions = 0;
@ -44,7 +48,7 @@ char buttonNames[NUM_JOYPAD_BUTTONS][2] = {"A", "B", "S", "T", "U", "D", "L", "R
HWND hwndTasEdit = 0; HWND hwndTasEdit = 0;
static HMENU hmenu, hrmenu; static HMENU hmenu, hrmenu;
static HWND hwndList, hwndHeader; static HWND hwndList, hwndHeader, hwndProgressbar, hwndRewind, hwndForward;
static WNDPROC hwndHeader_oldWndproc, hwndList_oldWndProc; static WNDPROC hwndHeader_oldWndproc, hwndList_oldWndProc;
typedef std::set<int> TSelectionFrames; typedef std::set<int> TSelectionFrames;
@ -186,22 +190,39 @@ static LONG CustomDraw(NMLVCUSTOMDRAW* msg)
void UpdateTasEdit() void UpdateTasEdit()
{ {
if(!hwndTasEdit) return; if(!hwndTasEdit) return;
// pause when seeking hit pauseframe
if(!FCEUI_EmulationPaused())
if(pauseframe && pauseframe <= currFrameCounter + 1)
SeekingStop();
if(FCEUI_EmulationPaused()==0) // update seeking progressbar
if (pauseframe)
{ {
if (FCEUMOV_ShouldPause()) SendMessage(hwndProgressbar, PBM_SETPOS, PROGRESSBAR_WIDTH * (currFrameCounter-seeking_start_frame) / (pauseframe-seeking_start_frame), 0);
{ } else if (old_emu_paused != (bool)FCEUI_EmulationPaused())
FCEUI_ToggleEmulationPause(); {
turbo = false; // emulator got paused/unpaused externally
} if (old_emu_paused && !FCEUI_EmulationPaused())
// externally unpaused - progressbar should be empty
SendMessage(hwndProgressbar, PBM_SETPOS, 0, 0);
else
// externally paused - progressbar should be full
SendMessage(hwndProgressbar, PBM_SETPOS, PROGRESSBAR_WIDTH, 0);
} }
old_emu_paused = (bool)FCEUI_EmulationPaused();
//update the number of items // update flashing pauseframe
int currLVItemCount = ListView_GetItemCount(hwndList); if (old_pauseframe != pauseframe && old_pauseframe) RedrawRow(old_pauseframe-1);
if(currMovieData.getNumRecords() != currLVItemCount) old_pauseframe = pauseframe;
{ old_show_pauseframe = show_pauseframe;
ListView_SetItemCountEx(hwndList,currMovieData.getNumRecords(),LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL); if (pauseframe)
} show_pauseframe = (int)(clock() / PAUSEFRAME_BLINKING_PERIOD) & 1;
else
show_pauseframe = false;
if (old_show_pauseframe != show_pauseframe) RedrawRow(pauseframe-1);
UpdateList();
//update the cursor //update the cursor
if(currFrameCounter != lastCursor) if(currFrameCounter != lastCursor)
@ -213,17 +234,7 @@ void UpdateTasEdit()
UpdateWindow(hwndList); UpdateWindow(hwndList);
lastCursor = currFrameCounter; lastCursor = currFrameCounter;
} }
// update flashing pauseframe
if (old_pauseframe != pauseframe && old_pauseframe > 0) RedrawRow(old_pauseframe-1);
old_pauseframe = pauseframe;
old_show_pauseframe = show_pauseframe;
if (pauseframe > 0)
show_pauseframe = (int)(clock() / PAUSEFRAME_BLINKING_PERIOD) & 1;
else
show_pauseframe = false;
if (old_show_pauseframe != show_pauseframe) RedrawRow(pauseframe-1);
// update window caption // update window caption
if ((!old_movie_readonly) == movie_readonly) if ((!old_movie_readonly) == movie_readonly)
{ {
@ -236,6 +247,47 @@ void UpdateTasEdit()
SetWindowText(hwndTasEdit, "TAS Editor (Recording)"); SetWindowText(hwndTasEdit, "TAS Editor (Recording)");
} }
} }
// update < and > buttons
if(FCEUI_EmulationPaused())
{
old_rewind_button_state = rewind_button_state;
rewind_button_state = Button_GetState(hwndRewind) & BST_PUSHED;
if (rewind_button_state)
{
if (!old_rewind_button_state)
{
button_hold_time = clock();
Tasedit_RewindFrame();
} else if (button_hold_time + HOLD_REPEAT_DELAY < clock())
{
Tasedit_RewindFrame();
}
}
old_forward_button_state = forward_button_state;
forward_button_state = Button_GetState(hwndForward) & BST_PUSHED;
if (forward_button_state)
{
if (!old_forward_button_state)
{
button_hold_time = clock();
Tasedit_ForwardFrame();
} else if (button_hold_time + HOLD_REPEAT_DELAY < clock())
{
Tasedit_ForwardFrame();
}
}
}
}
void UpdateList()
{
//update the number of items in the list
int currLVItemCount = ListView_GetItemCount(hwndList);
if(currMovieData.getNumRecords() != currLVItemCount)
{
ListView_SetItemCountEx(hwndList,currMovieData.getNumRecords(),LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL);
}
} }
void RedrawTasedit() void RedrawTasedit()
@ -251,6 +303,50 @@ void RedrawRow(int index)
ListView_RedrawItems(hwndList,index,index); ListView_RedrawItems(hwndList,index,index);
} }
void Tasedit_RewindFrame()
{
if (currFrameCounter > 0) JumpToFrame(currFrameCounter-1);
FollowPlayback();
}
void Tasedit_ForwardFrame()
{
JumpToFrame(currFrameCounter+1);
FollowPlayback();
}
void Tasedit_ToggleEmulationPause()
{
if (FCEUI_EmulationPaused())
UnpauseEmulation();
else
PauseEmulation();
}
void PauseEmulation()
{
FCEUI_SetEmulationPaused(1);
// make some additional stuff
}
void UnpauseEmulation()
{
FCEUI_SetEmulationPaused(0);
// make some additional stuff
}
void SeekingStart(int finish_frame)
{
seeking_start_frame = currFrameCounter;
pauseframe = finish_frame;
turbo = (seeking_start_frame + FRAMES_TOO_FAR < finish_frame);
UnpauseEmulation();
}
void SeekingStop()
{
pauseframe = 0;
turbo = false;
PauseEmulation();
SendMessage(hwndProgressbar, PBM_SETPOS, PROGRESSBAR_WIDTH, 0);
}
enum ECONTEXTMENU enum ECONTEXTMENU
{ {
CONTEXTMENU_STRAY = 0, CONTEXTMENU_STRAY = 0,
@ -310,7 +406,7 @@ void InvalidateGreenZone(int after)
{ {
if (TASEdit_restore_position) if (TASEdit_restore_position)
{ {
if (pauseframe-1 > currFrameCounter) if (pauseframe)
JumpToFrame(pauseframe-1); JumpToFrame(pauseframe-1);
else else
JumpToFrame(currFrameCounter); JumpToFrame(currFrameCounter);
@ -335,10 +431,8 @@ bool JumpToFrame(int index)
/* Handle jumps outside greenzone. */ /* Handle jumps outside greenzone. */
if (JumpToFrame(currMovieData.greenZoneCount-1)) if (JumpToFrame(currMovieData.greenZoneCount-1))
{ {
// continue from the end of greenzone // seek from the end of greenzone
if (FCEUI_EmulationPaused()) FCEUI_ToggleEmulationPause(); SeekingStart(index+1);
turbo = (currMovieData.greenZoneCount-1+FRAMES_TOO_FAR < index);
pauseframe = index+1;
return true; return true;
} }
return false; return false;
@ -347,13 +441,9 @@ bool JumpToFrame(int index)
if (currMovieData.loadTasSavestate(index)) if (currMovieData.loadTasSavestate(index))
{ {
currFrameCounter = index; currFrameCounter = index;
// if playback was seeking, pause emulation right here
if (pauseframe > 0)
{
if (!FCEUI_EmulationPaused()) FCEUI_ToggleEmulationPause();
pauseframe = -1;
}
turbo = false; turbo = false;
// if playback was seeking, pause emulation right here
if (pauseframe) SeekingStop();
return true; return true;
} }
//Search for an earlier frame with savestate //Search for an earlier frame with savestate
@ -362,31 +452,54 @@ bool JumpToFrame(int index)
{ {
if (currMovieData.loadTasSavestate(i)) break; if (currMovieData.loadTasSavestate(i)) break;
} }
// continue from the frame
currFrameCounter = i;
if (FCEUI_EmulationPaused()) FCEUI_ToggleEmulationPause();
turbo = (i+FRAMES_TOO_FAR < index);
pauseframe=index+1;
if (!i) if (!i)
{ StartFromZero();
//starting from frame 0 else
poweron(true); currFrameCounter = i;
MovieData::dumpSavestateTo(&currMovieData.savestates[0],0); // continue from the frame
} SeekingStart(index+1);
return true; return true;
} }
void StartFromZero()
{
poweron(true);
currFrameCounter = 0;
currMovieData.TryDumpIncremental();
}
void ToggleJoypadBit(int column_index, int row_index, UINT KeyFlags)
{
int joy = (column_index - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
int bit = (column_index - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
if (KeyFlags & (LVKF_SHIFT|LVKF_CONTROL))
{
//update multiple rows
for(TSelectionFrames::iterator it(selectionFrames.begin()); it != selectionFrames.end(); it++)
{
currMovieData.records[*it].toggleBit(joy,bit);
}
row_index = *selectionFrames.begin();
}
else
{
//update one row
currMovieData.records[row_index].toggleBit(joy,bit);
}
InvalidateGreenZone(row_index);
}
void SingleClick(LPNMITEMACTIVATE info) void SingleClick(LPNMITEMACTIVATE info)
{ {
int index = info->iItem; int row_index = info->iItem;
if(index == -1) return; if(row_index == -1) return;
int column_index = info->iSubItem; int column_index = info->iSubItem;
if(column_index == COLUMN_ICONS) if(column_index == COLUMN_ICONS)
{ {
// click on the "icons" column - jump to the frame // click on the "icons" column - jump to the frame
ClearSelection(); ClearSelection();
JumpToFrame(index); JumpToFrame(row_index);
RedrawList(); RedrawList();
} else if(column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2) } else if(column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2)
{ {
@ -394,51 +507,36 @@ void SingleClick(LPNMITEMACTIVATE info)
} }
else if(column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R) else if(column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R)
{ {
//toggle the bit ToggleJoypadBit(column_index, row_index, info->uKeyFlags);
int joy = (column_index - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
int bit = (column_index - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
if (info->uKeyFlags & (LVKF_SHIFT|LVKF_CONTROL))
{
//update multiple rows
for(TSelectionFrames::iterator it(selectionFrames.begin()); it != selectionFrames.end(); it++)
{
currMovieData.records[*it].toggleBit(joy,bit);
}
index=*selectionFrames.begin();
}
else
{
//update one row
currMovieData.records[index].toggleBit(joy,bit);
}
InvalidateGreenZone(index);
} }
} }
void DoubleClick(LPNMITEMACTIVATE info) void DoubleClick(LPNMITEMACTIVATE info)
{ {
int index = info->iItem; int row_index = info->iItem;
if(index == -1) return; if(row_index == -1) return;
int column_index = info->iSubItem; int column_index = info->iSubItem;
if(column_index == COLUMN_ICONS || column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2) if(column_index == COLUMN_ICONS || column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2)
{ {
// double click sends playback to the frame // double click sends playback to the frame
ClearSelection(); ClearSelection();
JumpToFrame(index); JumpToFrame(row_index);
RedrawList(); RedrawList();
} else if(column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R)
{
ToggleJoypadBit(column_index, row_index, info->uKeyFlags);
} }
} }
//removes all selections
static void ClearSelection() static void ClearSelection()
{ {
int frameCount = ListView_GetItemCount(hwndList);
ListView_SetItemState(hwndList,-1,0, LVIS_FOCUSED|LVIS_SELECTED); ListView_SetItemState(hwndList,-1,0, LVIS_FOCUSED|LVIS_SELECTED);
//selectionFrames.clear();
selectionFrames.clear(); }
static void ClearRowSelection(int index)
{
ListView_SetItemState(hwndList,index,0, LVIS_FOCUSED|LVIS_SELECTED);
} }
//insert frames at the currently selected positions. //insert frames at the currently selected positions.
@ -457,35 +555,39 @@ static void InsertFrames()
currMovieData.insertEmpty(*it,1); currMovieData.insertEmpty(*it,1);
} }
UpdateList();
InvalidateGreenZone(*selectionFrames.begin()); InvalidateGreenZone(*selectionFrames.begin());
UpdateTasEdit();
RedrawList();
} }
//delete frames at the currently selected positions. //delete frames at the currently selected positions.
static void DeleteFrames() static void DeleteFrames()
{ {
int frames = selectionFrames.size(); //delete frames on each selection, going backwards
if(frames == currMovieData.records.size())
{
MessageBox(hwndTasEdit,"Please don't delete all of the frames in the movie. This violates an internal invariant we need to keep.","Error deleting",0);
return; ///adelikat: why not just add an empty frame in the event of deleting all frames?
}
//this is going to be _really_ slow.
//insert frames before each selection
int ctr=0;
for(TSelectionFrames::reverse_iterator it(selectionFrames.rbegin()); it != selectionFrames.rend(); it++) for(TSelectionFrames::reverse_iterator it(selectionFrames.rbegin()); it != selectionFrames.rend(); it++)
{ {
currMovieData.records.erase(currMovieData.records.begin()+*it); currMovieData.records.erase(currMovieData.records.begin() + *it);
} }
// check if user deleted all frames
if (!currMovieData.records.size())
StartFromZero();
// reduce list
UpdateList();
int index = *selectionFrames.begin(); int index = *selectionFrames.begin();
if (index>0) --index; int delete_index;
ClearSelection(); // reduce selection if needed
for(TSelectionFrames::reverse_iterator it(selectionFrames.rbegin()); it != selectionFrames.rend(); it++)
{
if ((int)*it < (int)currMovieData.records.size()) break;
delete_index = *it;
// reduce selection manually, because reduced list won't call ItemChanged for these rows
selectionFrames.erase(delete_index);
if (!selectionFrames.size()) break;
//ClearRowSelection(delete_index);
}
// reduce greenzone
if (index>0) index--;
InvalidateGreenZone(index); InvalidateGreenZone(index);
UpdateTasEdit();
} }
//the column set operation, for setting a button for a span of selected values //the column set operation, for setting a button for a span of selected values
@ -523,7 +625,7 @@ static void ColumnSet(int column)
//a mix. set them. //a mix. set them.
else newValue = true; else newValue = true;
//operate on the data and update the listview //operate on the data
for(TSelectionFrames::iterator it(selectionFrames.begin()); it != selectionFrames.end(); it++) for(TSelectionFrames::iterator it(selectionFrames.begin()); it != selectionFrames.end(); it++)
{ {
currMovieData.records[*it].setBitValue(joy,button,newValue); currMovieData.records[*it].setBitValue(joy,button,newValue);
@ -721,10 +823,10 @@ static LRESULT APIENTRY HeaderWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lP
{ {
switch(msg) switch(msg)
{ {
case WM_LBUTTONDBLCLK:
case WM_SETCURSOR: case WM_SETCURSOR:
return true; // no column resizing return true; // no column resizing
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
{ {
//perform hit test //perform hit test
HD_HITTESTINFO info; HD_HITTESTINFO info;
@ -734,6 +836,7 @@ static LRESULT APIENTRY HeaderWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lP
if(info.iItem >= COLUMN_JOYPAD1_A && info.iItem <= COLUMN_JOYPAD4_R) if(info.iItem >= COLUMN_JOYPAD1_A && info.iItem <= COLUMN_JOYPAD4_R)
ColumnSet(info.iItem); ColumnSet(info.iItem);
} }
return true;
} }
return CallWindowProc(hwndHeader_oldWndproc,hWnd,msg,wParam,lParam); return CallWindowProc(hwndHeader_oldWndproc,hWnd,msg,wParam,lParam);
} }
@ -919,7 +1022,7 @@ static void OpenProject()
RemoveFourscoreColumns(); RemoveFourscoreColumns();
else if (!last_fourscore && currMovieData.fourscore) else if (!last_fourscore && currMovieData.fourscore)
AddFourscoreColumns(); AddFourscoreColumns();
if (!FCEUI_EmulationPaused()) FCEUI_ToggleEmulationPause(); PauseEmulation();
FollowPlayback(); FollowPlayback();
RedrawTasedit(); RedrawTasedit();
} }
@ -1016,17 +1119,15 @@ static void Export()
static void Truncate() static void Truncate()
{ {
int frame = currFrameCounter; int frame = currFrameCounter;
if (selectionFrames.size())
if (selectionFrames.size()>0)
{ {
frame=*selectionFrames.begin(); frame=*selectionFrames.begin();
JumpToFrame(frame); JumpToFrame(frame);
ClearSelection();
} }
ClearSelection();
currMovieData.truncateAt(frame+1); currMovieData.truncateAt(frame+1);
UpdateList();
InvalidateGreenZone(frame); InvalidateGreenZone(frame);
UpdateTasEdit();
} }
//likewise, handles a changed item range from the listview //likewise, handles a changed item range from the listview
@ -1084,7 +1185,10 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
if (TasEdit_wndy==-32000) TasEdit_wndy=0; if (TasEdit_wndy==-32000) TasEdit_wndy=0;
SetWindowPos(hwndDlg,0,TasEdit_wndx,TasEdit_wndy,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER); SetWindowPos(hwndDlg,0,TasEdit_wndx,TasEdit_wndy,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER);
hwndList = GetDlgItem(hwndDlg,IDC_LIST1); hwndList = GetDlgItem(hwndDlg, IDC_LIST1);
hwndProgressbar = GetDlgItem(hwndDlg, IDC_PROGRESS1);
hwndRewind = GetDlgItem(hwndDlg, TASEDIT_REWIND);
hwndForward = GetDlgItem(hwndDlg, TASEDIT_FORWARD);
InitDialog(); InitDialog();
break; break;
@ -1130,7 +1234,33 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
case LVN_ODSTATECHANGED: case LVN_ODSTATECHANGED:
ItemRangeChanged((LPNMLVODSTATECHANGE) lParam); ItemRangeChanged((LPNMLVODSTATECHANGE) lParam);
break; break;
}
break;
case TASEDIT_REWIND:
switch(((LPNMHDR)lParam)->code)
{
case NM_CLICK:
case NM_DBLCLK:
Tasedit_RewindFrame();
break;
}
break;
case TASEDIT_PLAYSTOP:
switch(((LPNMHDR)lParam)->code)
{
case NM_CLICK:
case NM_DBLCLK:
Tasedit_ToggleEmulationPause();
break;
}
break;
case TASEDIT_FORWARD:
switch(((LPNMHDR)lParam)->code)
{
case NM_CLICK:
case NM_DBLCLK:
Tasedit_ForwardFrame();
break;
} }
break; break;
} }
@ -1147,6 +1277,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
else else
TASEdit_focus = false; TASEdit_focus = false;
return DefWindowProc(hwndDlg,uMsg,wParam,lParam); return DefWindowProc(hwndDlg,uMsg,wParam,lParam);
case WM_COMMAND: case WM_COMMAND:
switch(LOWORD(wParam)) switch(LOWORD(wParam))
{ {
@ -1257,32 +1388,15 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
if (selectionFrames.size()) InsertFrames(); if (selectionFrames.size()) InsertFrames();
break; break;
case TASEDIT_FOWARD:
//advance 1 frame
JumpToFrame(currFrameCounter+1);
FollowPlayback();
break;
case TASEDIT_REWIND:
//rewinds 1 frame
if (currFrameCounter>0) JumpToFrame(currFrameCounter-1);
FollowPlayback();
break;
case TASEDIT_PLAYSTOP:
//Pause/Unpses (Play/Stop) movie
FCEUI_ToggleEmulationPause();
// also cancel turbo-seeking
if (FCEUI_EmulationPaused())
{
turbo = false;
pauseframe = -1;
}
break;
case TASEDIT_REWIND_FULL: case TASEDIT_REWIND_FULL:
//rewinds to beginning of greenzone //rewinds to beginning of greenzone
JumpToFrame(FindBeginningOfGreenZone(0)); JumpToFrame(FindBeginningOfGreenZone(0));
FollowPlayback(); FollowPlayback();
break; break;
case TASEDIT_FOWARD_FULL: case TASEDIT_PLAYSTOP:
Tasedit_ToggleEmulationPause();
break;
case TASEDIT_FORWARD_FULL:
//moves to the end of greenzone //moves to the end of greenzone
JumpToFrame(currMovieData.greenZoneCount-1); JumpToFrame(currMovieData.greenZoneCount-1);
FollowPlayback(); FollowPlayback();
@ -1335,7 +1449,13 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
CheckMenuItem(hmenu, ID_CONFIG_MUTETURBO, muteTurbo?MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, ID_CONFIG_MUTETURBO, muteTurbo?MF_CHECKED : MF_UNCHECKED);
break; break;
case IDC_PROGRESS_BUTTON:
if (pauseframe) SeekingStop();
break;
} }
break;
default: default:
break; break;
} }
@ -1358,30 +1478,6 @@ void FollowPlayback()
void EnterTasEdit() void EnterTasEdit()
{ {
if(!FCEU_IsValidUI(FCEUI_TASEDIT)) return; if(!FCEU_IsValidUI(FCEUI_TASEDIT)) return;
// init variables
lastCursor = old_pauseframe = -1;
old_show_pauseframe = show_pauseframe = false;
// either start new project or use current movie
if (movieMode == MOVIEMODE_INACTIVE)
{
FCEUI_StopMovie();
CreateCleanMovie();
//reset the rom
poweron(true);
currFrameCounter = 0;
}
else
{
//use current movie to create a new project
FCEUI_StopMovie();
}
// pause the emulator and enter tasedit mode
FCEUI_SetEmulationPaused(1);
FCEU_DispMessage("Tasedit engaged",0);
movieMode = MOVIEMODE_TASEDIT;
currMovieData.TryDumpIncremental();
// window stuff // window stuff
if(!hwndTasEdit) hwndTasEdit = CreateDialog(fceu_hInstance,"TASEDIT",hAppWnd,WndprocTasEdit); if(!hwndTasEdit) hwndTasEdit = CreateDialog(fceu_hInstance,"TASEDIT",hAppWnd,WndprocTasEdit);
if(hwndTasEdit) if(hwndTasEdit)
@ -1410,14 +1506,38 @@ void EnterTasEdit()
SetWindowPos(hwndTasEdit,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER); SetWindowPos(hwndTasEdit,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
} }
// either start new project or use current movie
if (movieMode == MOVIEMODE_INACTIVE)
{
FCEUI_StopMovie();
CreateCleanMovie();
StartFromZero();
}
else
{
//use current movie to create a new project
FCEUI_StopMovie();
}
// set progressbar property
SendMessage(hwndProgressbar, PBM_SETRANGE, 0, MAKELPARAM(0, PROGRESSBAR_WIDTH));
// init variables
lastCursor = -1;
old_pauseframe = 0;
old_show_pauseframe = show_pauseframe = false;
old_rewind_button_state = rewind_button_state = false;
old_forward_button_state = forward_button_state = false;
old_emu_paused = true;
SeekingStop();
FCEU_DispMessage("Tasedit engaged",0);
movieMode = MOVIEMODE_TASEDIT;
currMovieData.TryDumpIncremental();
} }
void ExitTasEdit() void ExitTasEdit()
{ {
if (!CheckSaveChanges()) return; if (!CheckSaveChanges()) return;
DestroyWindow(hwndTasEdit); DestroyWindow(hwndTasEdit);
hwndTasEdit = 0; hwndTasEdit = 0;
turbo = false; SeekingStop();
pauseframe = -1;
TASEdit_focus = false; TASEdit_focus = false;
// restore "eoptions" // restore "eoptions"
eoptions = saved_eoptions; eoptions = saved_eoptions;

View File

@ -7,6 +7,8 @@
#define GREENZONE_MIN_CAPACITY 1 #define GREENZONE_MIN_CAPACITY 1
#define GREENZONE_MAX_CAPACITY 200000 // maybe even more #define GREENZONE_MAX_CAPACITY 200000 // maybe even more
#define PAUSEFRAME_BLINKING_PERIOD 100 #define PAUSEFRAME_BLINKING_PERIOD 100
#define PROGRESSBAR_WIDTH 200
#define HOLD_REPEAT_DELAY 250 // in milliseconds
// listview column names // listview column names
#define COLUMN_ICONS 0 #define COLUMN_ICONS 0
#define COLUMN_FRAMENUM 1 #define COLUMN_FRAMENUM 1
@ -62,6 +64,7 @@
void EnterTasEdit(); void EnterTasEdit();
void ExitTasEdit(); void ExitTasEdit();
void UpdateTasEdit(); void UpdateTasEdit();
void UpdateList();
void InvalidateGreenZone(int after); void InvalidateGreenZone(int after);
bool JumpToFrame(int index); bool JumpToFrame(int index);
int FindBeginningOfGreenZone(int starting_index); int FindBeginningOfGreenZone(int starting_index);
@ -71,4 +74,13 @@ void AddFourscoreColumns();
void RemoveFourscoreColumns(); void RemoveFourscoreColumns();
void RedrawTasedit(); void RedrawTasedit();
void RedrawList(); void RedrawList();
void RedrawRow(int index); void RedrawRow(int index);
void SeekingStart(int finish_frame);
void SeekingStop();
void Tasedit_ToggleEmulationPause();
void PauseEmulation();
void UnpauseEmulation();
void ToggleJoypadBit(int column_index, int row_index, UINT KeyFlags);
void Tasedit_RewindFrame();
void Tasedit_ForwardFrame();
void StartFromZero();

View File

@ -649,9 +649,9 @@ bool FCEUI_GetLagged(void)
bool FCEUMOV_ShouldPause(void) bool FCEUMOV_ShouldPause(void)
{ {
if(pauseframe && currFrameCounter == (pauseframe-1)) //adelikat: changed to pauseframe -1 to prevent an off by 1 error. THis is probably the hackiest solution but I think it would cause some major restructuring to fix it properly. if(pauseframe && currFrameCounter+1 == pauseframe)
{ {
pauseframe = 0; //only pause once! pauseframe = 0;
return true; return true;
} }
else else
@ -950,7 +950,8 @@ bool MovieData::loadTasSavestate(int frame)
if ((int)savestates.size()<=frame || savestates[frame].empty()) if ((int)savestates.size()<=frame || savestates[frame].empty())
return false; return false;
return MovieData::loadSavestateFrom(&savestates[frame]); EMUFILE_MEMORY ms(&savestates[frame]);
return FCEUSS_LoadFP(&ms, SSLOADPARAM_NOBACKUP);
} }
void MovieData::storeTasSavestate(int frame, int compression_level) void MovieData::storeTasSavestate(int frame, int compression_level)

View File

@ -617,18 +617,17 @@ int FCEUSS_LoadFP_old(EMUFILE* is, ENUM_SSLOADPARAMS params)
bool FCEUSS_LoadFP(EMUFILE* is, ENUM_SSLOADPARAMS params) bool FCEUSS_LoadFP(EMUFILE* is, ENUM_SSLOADPARAMS params)
{ {
if(!is) return false;
//maybe make a backup savestate //maybe make a backup savestate
EMUFILE_MEMORY msBackupSavestate;
bool backup = (params == SSLOADPARAM_BACKUP); bool backup = (params == SSLOADPARAM_BACKUP);
EMUFILE_MEMORY msBackupSavestate;
if(!is)
return false;
if(backup) if(backup)
{
FCEUSS_SaveMS(&msBackupSavestate,Z_NO_COMPRESSION); FCEUSS_SaveMS(&msBackupSavestate,Z_NO_COMPRESSION);
}
uint8 header[16]; uint8 header[16];
//read and analyze the header //read and analyze the header
is->fread((char*)&header,16); is->fread((char*)&header,16);
if(memcmp(header,"FCSX",4)) { if(memcmp(header,"FCSX",4)) {