* Tasedit: refactoring

* Tasedit: selection << and >>
* Tasedit: Turbo Seek checkbox
* Tasedit: PasteInsert (Shift-V)
* Tasedit: Config->Superimpose affects copy/paste
* Tasedit: list save/load (currently only restoring vscroll position)
* Tasedit: Editing info texts
This commit is contained in:
ansstuff 2011-11-25 19:26:26 +00:00
parent bf31670246
commit 16a625561c
28 changed files with 953 additions and 368 deletions

View File

@ -69,12 +69,14 @@ extern bool oldInputDisplay;
extern bool fullSaveStateLoads;
extern int frameSkipAmt;
extern bool TASEdit_follow_playback;
extern bool TASEdit_turbo_seek;
extern bool TASEdit_show_lag_frames;
extern bool TASEdit_show_markers;
extern bool TASEdit_show_branch_screenshots;
extern bool TASEdit_bind_markers;
extern bool TASEdit_use_1p_rec;
extern bool TASEdit_combine_consecutive_rec;
extern bool TASEdit_superimpose_affects_paste;
extern bool TASEdit_branch_full_movie;
extern bool TASEdit_branch_only_when_rec;
extern bool TASEdit_view_branches_tree;
@ -304,12 +306,14 @@ static CFGSTRUCT fceuconfig[] = {
AC(AutoFireOffset),
AC(DesynchAutoFire),
AC(TASEdit_follow_playback),
AC(TASEdit_turbo_seek),
AC(TASEdit_show_lag_frames),
AC(TASEdit_show_markers),
AC(TASEdit_show_branch_screenshots),
AC(TASEdit_bind_markers),
AC(TASEdit_use_1p_rec),
AC(TASEdit_combine_consecutive_rec),
AC(TASEdit_superimpose_affects_paste),
AC(TASEdit_branch_full_movie),
AC(TASEdit_branch_only_when_rec),
AC(TASEdit_view_branches_tree),

View File

@ -243,6 +243,7 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "&Copy\tCtrl+C", ID_TASEDIT_COPY
MENUITEM "&Paste\tCtrl+V", ID_TASEDIT_PASTE
MENUITEM "PasteInsert\tShift+V", ID_EDIT_PASTEINSERT
MENUITEM "Cu&t\tCtrl+X", ID_TASEDIT_CUT
MENUITEM SEPARATOR
MENUITEM "C&lear\tDel", ID_EDIT_CLEAR
@ -257,7 +258,7 @@ BEGIN
BEGIN
MENUITEM "Highlight &Lag Frames", ID_VIEW_SHOW_LAG_FRAMES
MENUITEM "Show &Markers", ID_VIEW_SHOW_MARKERS
MENUITEM "Show Branch &Screenshots", ID_VIEW_SHOWBRANCHSCREENSHOTS
MENUITEM "Display Branch &Screenshots", ID_VIEW_SHOWBRANCHSCREENSHOTS
MENUITEM "Enable Hot &Changes", ID_VIEW_ENABLEHOTCHANGES
MENUITEM SEPARATOR
MENUITEM "&Follow undo context", ID_VIEW_JUMPWHENMAKINGUNDO
@ -276,6 +277,7 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "&Use 1P keys for all single Recordings", ID_CONFIG_USE1PFORRECORDING
MENUITEM "&Combine consecutive Recordings", ID_CONFIG_COMBINECONSECUTIVERECORDINGS
MENUITEM "&Superimpose affects copy/paste", ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE
MENUITEM SEPARATOR
MENUITEM "Mute &Turbo", ID_CONFIG_MUTETURBO
END
@ -1376,17 +1378,17 @@ BEGIN
PUSHBUTTON "||",TASEDIT_PLAYSTOP,360,10,23,14,NOT WS_TABSTOP
PUSHBUTTON ">",TASEDIT_FORWARD,383,10,23,14,NOT WS_TABSTOP
PUSHBUTTON ">>",TASEDIT_FORWARD_FULL,406,10,23,14,NOT WS_TABSTOP
CONTROL "",IDC_PROGRESS_BUTTON,"Button",BS_OWNERDRAW,314,38,116,10
CONTROL "",IDC_BRANCHES_BUTTON,"Button",BS_OWNERDRAW,320,151,104,11
CONTROL "",IDC_PROGRESS_BUTTON,"Button",BS_OWNERDRAW,314,37,116,12
CONTROL "",IDC_BRANCHES_BUTTON,"Button",BS_OWNERDRAW,320,149,104,11
CONTROL "",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,314,40,115,6
CONTROL " Follow cursor",CHECK_FOLLOW_CURSOR,"Button",BS_AUTOCHECKBOX,316,26,105,12
CONTROL " Follow cursor",CHECK_FOLLOW_CURSOR,"Button",BS_AUTOCHECKBOX,316,26,56,12
CONTROL " Auto-restore last position",CHECK_AUTORESTORE_PLAYBACK,
"Button",BS_AUTOCHECKBOX,316,49,105,12
GROUPBOX " Recording ",IDC_STATIC,310,64,123,48,BS_CENTER,WS_EX_RIGHT
GROUPBOX " Editing ",IDC_STATIC,310,113,123,37,BS_CENTER,WS_EX_RIGHT
GROUPBOX " Bookmarks ",IDC_BOOKMARKS_BOX,310,152,123,103,BS_CENTER,WS_EX_RIGHT
CONTROL "",IDC_BOOKMARKSLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | NOT WS_VISIBLE | WS_BORDER,315,162,113,89
CONTROL "",IDC_HISTORYLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOLABELWRAP | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,315,267,113,100
GROUPBOX " Editing ",IDC_STATIC,310,113,123,35,BS_CENTER,WS_EX_RIGHT
GROUPBOX " Bookmarks ",IDC_BOOKMARKS_BOX,310,150,123,103,BS_CENTER,WS_EX_RIGHT
CONTROL "",IDC_BOOKMARKSLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | NOT WS_VISIBLE | WS_BORDER,315,160,113,89
CONTROL "",IDC_HISTORYLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOLABELWRAP | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,315,265,113,102
CONTROL " OFF",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,316,74,27,10
CONTROL " ON",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,316,87,27,10
CONTROL " 1P",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,373,74,25,10
@ -1394,16 +1396,20 @@ BEGIN
CONTROL " 3P",IDC_RADIO5,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,373,87,25,10
CONTROL " 4P",IDC_RADIO6,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,402,87,23,10
CONTROL " Superimpose",IDC_SUPERIMPOSE,"Button",BS_AUTO3STATE,316,100,56,10
GROUPBOX " History ",IDC_STATIC,310,257,123,114,BS_CENTER,WS_EX_RIGHT
GROUPBOX " History ",IDC_STATIC,310,255,123,116,BS_CENTER,WS_EX_RIGHT
EDITTEXT IDC_EDIT1,54,377,251,13,ES_READONLY | NOT WS_TABSTOP
PUSHBUTTON "<<",TASEDIT_REWIND_FULL2,315,376,23,14,NOT WS_TABSTOP
PUSHBUTTON "Find",TASEDIT_REWIND_FULL3,338,376,34,14,WS_DISABLED | NOT WS_TABSTOP
PUSHBUTTON "Next",TASEDIT_REWIND_FULL4,372,376,34,14,WS_DISABLED | NOT WS_TABSTOP
PUSHBUTTON ">>",TASEDIT_REWIND_FULL5,405,376,23,14,NOT WS_TABSTOP
PUSHBUTTON "<<",TASEDIT_PREV_MARKER,315,376,23,14,NOT WS_TABSTOP
PUSHBUTTON "Find",TASEDIT_FIND_BEST_MARKER,338,376,34,14,WS_DISABLED | NOT WS_TABSTOP
PUSHBUTTON "Next",TASEDIT_FIND_NEXT_MARKER,372,376,34,14,WS_DISABLED | NOT WS_TABSTOP
PUSHBUTTON ">>",TASEDIT_NEXT_MARKER,405,376,23,14,NOT WS_TABSTOP
RTEXT "Marker 99999",IDC_STATIC,6,379,45,10,0,WS_EX_RIGHT
RTEXT "Marker 0",IDC_STATIC,6,3,45,10,0,WS_EX_RIGHT
EDITTEXT IDC_EDIT2,54,1,251,13,ES_READONLY | NOT WS_TABSTOP
CONTROL "",IDC_BRANCHES_BITMAP,"Static",SS_OWNERDRAW | SS_NOTIFY | SS_REALSIZEIMAGE | NOT WS_VISIBLE,315,162,113,89
CONTROL "",IDC_BRANCHES_BITMAP,"Static",SS_OWNERDRAW | SS_NOTIFY | SS_REALSIZEIMAGE | NOT WS_VISIBLE,315,160,113,89
CONTROL " Turbo seek",CHECK_TURBO_SEEK,"Button",BS_AUTOCHECKBOX,379,26,50,12
CONTROL "",IDC_TEXT_SELECTION_BUTTON,"Button",BS_OWNERDRAW,315,121,113,12
LTEXT "Selection: 0 rows, 16 columns",IDC_TEXT_SELECTION,316,123,114,10
LTEXT "Clipboard: 0 rows, 16 columns",IDC_TEXT_CLIPBOARD,316,134,114,10
END
ASSEMBLER DIALOGEX 0, 0, 202, 135
@ -2000,6 +2006,7 @@ END
IDR_ACCELERATOR1 ACCELERATORS
BEGIN
"A", ACCEL_CTRL_A, VIRTKEY, CONTROL, NOINVERT
"B", ACCEL_CTRL_B, VIRTKEY, CONTROL, NOINVERT
"C", ACCEL_CTRL_C, VIRTKEY, CONTROL, NOINVERT
VK_DELETE, ACCEL_CTRL_DELETE, VIRTKEY, CONTROL, NOINVERT
"F", ACCEL_CTRL_F, VIRTKEY, CONTROL, NOINVERT
@ -2016,7 +2023,7 @@ BEGIN
VK_DELETE, ACCEL_DEL, VIRTKEY, NOINVERT
VK_INSERT, ACCEL_INS, VIRTKEY, NOINVERT
VK_INSERT, ACCEL_SHIFT_INS, VIRTKEY, SHIFT, NOINVERT
"B", ACCEL_CTRL_B, VIRTKEY, CONTROL, NOINVERT
"V", ACCEL_SHIFT_V, VIRTKEY, SHIFT, NOINVERT
END
IDR_RWACCELERATOR ACCELERATORS

View File

@ -415,15 +415,21 @@
#define IDC_BUTTON7 1145
#define MEMW_EDIT03FORMULA 1145
#define TASEDIT_REWIND_FULL2 1145
#define TASEDIT_PREV_MARKER 1145
#define IDC_BUTTON8 1146
#define TASEDIT_REWIND_FULL3 1146
#define TASEDIT_FIND_BEST_MARKER 1146
#define IDC_EDIT1 1147
#define IDC_BUTTON9 1148
#define TASEDIT_REWIND_FULL4 1148
#define TASEDIT_FIND_NEXT_MARKER 1148
#define IDC_HISTORYLIST 1149
#define IDC_BOOKMARKSLIST 1150
#define TASEDIT_REWIND_FULL5 1151
#define TASEDIT_NEXT_MARKER 1151
#define IDC_BRANCHES_BUTTON 1152
#define IDC_BRANCHES_BUTTON2 1153
#define IDC_TEXT_SELECTION_BUTTON 1153
#define IDC_EDIT2 1154
#define CHECK_SOUND_MUTETURBO 1179
#define IDC_EDIT_AUTHOR 1180
@ -530,6 +536,9 @@
#define IDC_BOOKMARKS_BOX 1264
#define IDC_BRANCHES_BITMAP 1265
#define IDC_SCREENSHOT_BITMAP 1266
#define CHECK_TURBO_SEEK 1266
#define IDC_TEXT_SELECTION 1267
#define IDC_TEXT_CLIPBOARD 1268
#define MENU_NETWORK 40040
#define MENU_PALETTE 40041
#define MENU_SOUND 40042
@ -904,6 +913,10 @@
#define ID_CONFIG_USE1PFORRECORDING2P 40490
#define ID_CONFIG_USE1PFORRECORDING 40491
#define ID_CONFIG_COMBINECONSECUTIVERECORDINGS 40492
#define ACCEL_SHIFT_V 40493
#define ID_EDIT_PASTEINSERT 40495
#define ID_CONFIG_SUPERIMPOSEAFFECTSCOPY 40496
#define ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE 40497
#define IDC_DEBUGGER_ICONTRAY 55535
#define MW_ValueLabel2 65423
#define MW_ValueLabel1 65426
@ -913,8 +926,8 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 185
#define _APS_NEXT_COMMAND_VALUE 40493
#define _APS_NEXT_CONTROL_VALUE 1267
#define _APS_NEXT_COMMAND_VALUE 40498
#define _APS_NEXT_CONTROL_VALUE 1269
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1,13 +1,9 @@
#include <set> //
#include <fstream>
#include <sstream>
#include "taseditlib/taseditproj.h"
#include "fceu.h" //
#include "replay.h"
#include "utils/xstring.h"
#include "Win32InputBox.h"
#include "window.h" //
#include "keyboard.h"
#include "joystick.h"
#include "help.h"
@ -30,6 +26,7 @@ RECORDER recorder;
GREENZONE greenzone;
MARKERS markers;
BOOKMARKS bookmarks;
SCREENSHOT_DISPLAY screenshot_display;
TASEDIT_LIST tasedit_list;
TASEDIT_SELECTION selection;
@ -39,16 +36,19 @@ int saved_EnableAutosave;
extern int EnableAutosave;
extern EMOVIEMODE movieMode; // maybe we need normal setter for movieMode, to encapsulate it
extern void UpdateCheckedMenuItems();
// vars saved in cfg file (need dedicated storage class?)
int TasEdit_wndx, TasEdit_wndy;
bool TASEdit_follow_playback = true;
bool TASEdit_turbo_seek = true;
bool TASEdit_show_lag_frames = true;
bool TASEdit_show_markers = true;
bool TASEdit_show_branch_screenshots = true;
bool TASEdit_bind_markers = true;
bool TASEdit_use_1p_rec = true;
bool TASEdit_combine_consecutive_rec = true;
bool TASEdit_superimpose_affects_paste = true;
int TASEdit_superimpose = BST_UNCHECKED;
bool TASEdit_branch_full_movie = true;
bool TASEdit_branch_only_when_rec = false;
@ -66,7 +66,7 @@ bool TASEdit_jump_to_undo = true;
string tasedithelp = "{16CDE0C4-02B0-4A60-A88D-076319909A4D}"; //Name of TASEdit Help page
char buttonNames[NUM_JOYPAD_BUTTONS][2] = {"A", "B", "S", "T", "U", "D", "L", "R"};
char windowCaption[] = "TAS Editor";
extern char windowCaptions[5][30];
extern char recordingCaptions[5][30];
// enterframe function
void UpdateTasEdit()
@ -79,6 +79,7 @@ void UpdateTasEdit()
playback.update();
recorder.update();
bookmarks.update();
screenshot_display.update();
selection.update();
history.update();
project.update();
@ -89,7 +90,7 @@ void RedrawWindowCaption()
char windowCapt[300];
strcpy(windowCapt, windowCaption);
if (!movie_readonly)
strcat(windowCapt, windowCaptions[recorder.multitrack_recording_joypad]);
strcat(windowCapt, recordingCaptions[recorder.multitrack_recording_joypad]);
// add project name
std::string projectname = project.GetProjectName();
if (!projectname.empty())
@ -106,16 +107,6 @@ void RedrawTasedit()
{
InvalidateRect(hwndTasEdit, 0, FALSE);
}
void RedrawListAndBookmarks()
{
tasedit_list.RedrawList();
bookmarks.RedrawBookmarksList();
}
void RedrawRowAndBookmark(int index)
{
tasedit_list.RedrawRow(index);
bookmarks.RedrawChangedBookmarks(index);
}
void ShowMenu(ECONTEXTMENU which, POINT& pt)
{
@ -197,7 +188,7 @@ void SingleClick(LPNMITEMACTIVATE info)
{
// reverse MARKER_FLAG_BIT in pointed frame
markers.ToggleMarker(row_index);
if (markers.markers_array[row_index])
if (markers.GetMarker(row_index))
history.RegisterChanges(MODTYPE_MARKER_SET, row_index);
else
history.RegisterChanges(MODTYPE_MARKER_UNSET, row_index);
@ -254,7 +245,7 @@ void CloneFrames()
frames = 1;
} else frames++;
}
//tasedit_list.update();
markers.update();
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_CLONE, *current_selection->begin()));
}
@ -284,7 +275,7 @@ void InsertFrames()
frames = 1;
} else frames++;
}
//tasedit_list.update();
markers.update();
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_INSERT, *current_selection->begin()));
}
@ -331,7 +322,7 @@ void DeleteFrames()
{
currMovieData.records.erase(currMovieData.records.begin() + *it);
if (TASEdit_bind_markers)
markers.markers_array.erase(markers.markers_array.begin() + *it);
markers.EraseMarker(*it);
}
// check if user deleted all frames
if (!currMovieData.getNumRecords())
@ -408,7 +399,7 @@ void ColumnSet(int column)
bool unset_found = false;
for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++)
{
if(!(markers.markers_array[*it] & MARKER_FLAG_BIT))
if(!markers.GetMarker(*it))
{
unset_found = true;
break;
@ -418,13 +409,13 @@ void ColumnSet(int column)
{
// set all
for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++)
markers.markers_array[*it] |= MARKER_FLAG_BIT;
markers.SetMarker(*it);
history.RegisterChanges(MODTYPE_MARKER_SET, *current_selection_begin, *current_selection->rbegin());
} else
{
// unset all
for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++)
markers.markers_array[*it] &= ~MARKER_FLAG_BIT;
markers.ClearMarker(*it);
history.RegisterChanges(MODTYPE_MARKER_UNSET, *current_selection_begin, *current_selection->rbegin());
}
project.SetProjectChanged();
@ -484,7 +475,7 @@ bool Copy(SelectionFrames* current_selection)
cframe=*it;
int cjoy=0;
for (int joy=0; joy<NUM_JOYPADS; ++joy)
for (int joy = 0; joy < NUM_JOYPADS; ++joy)
{
while (currMovieData.records[*it].joysticks[joy] && cjoy<joy)
{
@ -557,15 +548,118 @@ bool Paste()
// TAS recording info starts with "TAS ".
if (pGlobal[0]=='T' && pGlobal[1]=='A' && pGlobal[2]=='S')
{
int range;
// Extract number of frames
int range;
sscanf (pGlobal+3, "%d", &range);
if (currMovieData.getNumRecords() < pos+range)
{
currMovieData.insertEmpty(currMovieData.getNumRecords(),pos+range-currMovieData.getNumRecords());
markers.update();
}
pGlobal = strchr(pGlobal, '\n');
int joy = 0;
uint8 new_buttons = 0;
char* frame;
--pos;
while (pGlobal++ && *pGlobal!='\0')
{
frame = pGlobal;
// Detect skipped frames in paste.
if (frame[0]=='+')
{
pos += atoi(frame+1);
while (*frame && *frame != '\n' && *frame!='|')
++frame;
if (*frame=='|') ++frame;
} else
{
++pos;
}
if (!TASEdit_superimpose_affects_paste || TASEdit_superimpose == BST_UNCHECKED)
{
currMovieData.records[pos].joysticks[0] = 0;
currMovieData.records[pos].joysticks[1] = 0;
currMovieData.records[pos].joysticks[2] = 0;
currMovieData.records[pos].joysticks[3] = 0;
}
// read this frame input
joy = 0;
new_buttons = 0;
while (*frame && *frame != '\n' && *frame !='\r')
{
switch (*frame)
{
case '|': // Joystick mark
// flush buttons to movie data
if (TASEdit_superimpose_affects_paste && (TASEdit_superimpose == BST_CHECKED || (TASEdit_superimpose == BST_INDETERMINATE && new_buttons == 0)))
currMovieData.records[pos].joysticks[joy] |= new_buttons;
else
currMovieData.records[pos].joysticks[joy] = new_buttons;
++joy;
new_buttons = 0;
break;
default:
for (int bit=0; bit<NUM_JOYPAD_BUTTONS; ++bit)
{
if (*frame == buttonNames[bit][0])
{
new_buttons |= (1<<bit);
break;
}
}
break;
}
++frame;
}
// before going to next frame, flush buttons to movie data
if (TASEdit_superimpose_affects_paste && (TASEdit_superimpose == BST_CHECKED || (TASEdit_superimpose == BST_INDETERMINATE && new_buttons == 0)))
currMovieData.records[pos].joysticks[joy] |= new_buttons;
else
currMovieData.records[pos].joysticks[joy] = new_buttons;
// find CRLF
pGlobal = strchr(pGlobal, '\n');
}
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_PASTE, *current_selection_begin));
result = true;
}
GlobalUnlock(hGlobal);
}
CloseClipboard();
return result;
}
bool PasteInsert()
{
SelectionFrames* current_selection = selection.MakeStrobe();
if (current_selection->size() == 0) return false;
if (!OpenClipboard(hwndTasEdit)) return false;
SelectionFrames::iterator current_selection_begin(current_selection->begin());
bool result = false;
int pos = *current_selection_begin;
HANDLE hGlobal = GetClipboardData(CF_TEXT);
if (hGlobal)
{
char *pGlobal = (char*)GlobalLock((HGLOBAL)hGlobal);
// TAS recording info starts with "TAS ".
if (pGlobal[0]=='T' && pGlobal[1]=='A' && pGlobal[2]=='S')
{
// make sure markers have the same size as movie
markers.update();
// init inserted_set (for input history hot changes)
selection.GetInsertedSet().clear();
// Extract number of frames
int range;
sscanf (pGlobal+3, "%d", &range);
pGlobal = strchr(pGlobal, '\n');
int joy=0;
--pos;
@ -578,31 +672,39 @@ bool Paste()
if (frame[0]=='+')
{
pos += atoi(frame+1);
while (*frame && *frame != '\n' && *frame!='|')
if (currMovieData.getNumRecords() < pos)
{
currMovieData.insertEmpty(currMovieData.getNumRecords(), pos - currMovieData.getNumRecords());
markers.update();
}
while (*frame && *frame != '\n' && *frame != '|')
++frame;
if (*frame=='|') ++frame;
} else
{
++pos;
}
// insert new frame
currMovieData.insertEmpty(pos, 1);
if (TASEdit_bind_markers) markers.insertEmpty(pos, 1);
selection.GetInsertedSet().insert(pos);
currMovieData.records[pos].joysticks[0]=0;
currMovieData.records[pos].joysticks[1]=0;
int joy=0;
// read this frame input
int joy = 0;
while (*frame && *frame != '\n' && *frame !='\r')
{
switch (*frame)
{
case '|': // Joystick marker
case '|': // Joystick mark
++joy;
break;
default:
for (int bit=0; bit<NUM_JOYPAD_BUTTONS; ++bit)
for (int bit = 0; bit < NUM_JOYPAD_BUTTONS; ++bit)
{
if (*frame == buttonNames[bit][0])
{
currMovieData.records[pos].joysticks[joy]|=(1<<bit);
currMovieData.records[pos].joysticks[joy] |= (1<<bit);
break;
}
}
@ -613,10 +715,10 @@ bool Paste()
pGlobal = strchr(pGlobal, '\n');
}
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_PASTE, *current_selection_begin));
markers.update();
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_PASTEINSERT, *current_selection_begin));
result = true;
}
GlobalUnlock(hGlobal);
}
CloseClipboard();
@ -629,9 +731,10 @@ void OpenProject()
const char TPfilter[]="TASEdit Project (*.tas)\0*.tas\0\0";
OPENFILENAME ofn;
memset(&ofn,0,sizeof(ofn));
ofn.lStructSize=sizeof(ofn);
OPENFILENAME ofn;
memset(&ofn,0,sizeof(ofn));
ofn.lStructSize=sizeof(ofn);
ofn.hwndOwner = hwndTasEdit;
ofn.hInstance=fceu_hInstance;
ofn.lpstrTitle="Open TASEdit Project...";
ofn.lpstrFilter=TPfilter;
@ -658,8 +761,6 @@ void OpenProject()
std::string thisfm2name = name;
thisfm2name.append(".fm2");
project.SetFM2Name(thisfm2name);
recorder.reset();
playback.reset();
// remember to update fourscore status
bool last_fourscore = currMovieData.fourscore;
// Load project
@ -669,7 +770,6 @@ void OpenProject()
tasedit_list.RemoveFourscore();
else if (!last_fourscore && currMovieData.fourscore)
tasedit_list.AddFourscore();
tasedit_list.FollowPlayback();
RedrawTasedit();
RedrawWindowCaption();
}
@ -680,9 +780,10 @@ bool SaveProjectAs()
{
const char TPfilter[]="TASEdit Project (*.tas)\0*.tas\0All Files (*.*)\0*.*\0\0"; //Filetype filter
OPENFILENAME ofn;
memset(&ofn,0,sizeof(ofn));
ofn.lStructSize=sizeof(ofn);
OPENFILENAME ofn;
memset(&ofn,0,sizeof(ofn));
ofn.lStructSize=sizeof(ofn);
ofn.hwndOwner = hwndTasEdit;
ofn.hInstance=fceu_hInstance;
ofn.lpstrTitle="Save TASEdit Project As...";
ofn.lpstrFilter=TPfilter;
@ -742,8 +843,8 @@ bool AskSaveProject()
void Import()
{
}
//Takes current inputlog and saves it as a .fm2 file
void Export()
{
//TODO: redesign this
@ -754,6 +855,7 @@ void Export()
OPENFILENAME ofn;
memset(&ofn,0,sizeof(ofn));
ofn.lStructSize=sizeof(ofn);
ofn.hwndOwner = hwndTasEdit;
ofn.hInstance=fceu_hInstance;
ofn.lpstrTitle="Export TAS as...";
ofn.lpstrFilter=filter;
@ -791,9 +893,8 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
TasEdit_wndx = wrect.left;
TasEdit_wndy = wrect.top;
WindowBoundsCheckNoResize(TasEdit_wndx,TasEdit_wndy,wrect.right);
// also move screenshot bitmap if it's open
if (bookmarks.hwndScrBmp)
SetWindowPos(bookmarks.hwndScrBmp, 0, TasEdit_wndx + bookmarks.scr_bmp_x, TasEdit_wndy + bookmarks.scr_bmp_y, 0, 0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
// also move screenshot display if it's open
screenshot_display.ParentWindowMoved();
}
break;
}
@ -903,8 +1004,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
SaveProjectAs();
break;
case ID_FILE_IMPORTFM2:
Replay_LoadMovie(true);
//Import(); //adelikat: Putting the play movie dialog in its place until the import concept is refined.
Import();
break;
case ID_FILE_EXPORTFM2:
Export();
@ -927,6 +1027,10 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
case ID_TASEDIT_PASTE:
Paste();
break;
case ACCEL_SHIFT_V:
case ID_EDIT_PASTEINSERT:
PasteInsert();
break;
case ACCEL_CTRL_DELETE:
case ID_TASEDIT_DELETE:
case ID_CONTEXT_SELECTED_DELETEFRAMES:
@ -974,11 +1078,20 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
else if (playback.GetPauseFrame())
tasedit_list.FollowPauseframe();
break;
case CHECK_TURBO_SEEK:
//switch "Turbo seek" flag
TASEdit_turbo_seek ^= 1;
CheckDlgButton(hwndTasEdit, CHECK_TURBO_SEEK, TASEdit_turbo_seek?MF_CHECKED : MF_UNCHECKED);
// if currently seeking, apply this option immediately
if (playback.pause_frame)
turbo = TASEdit_turbo_seek;
break;
case ID_VIEW_SHOW_LAG_FRAMES:
//switch "Highlight lag frames" flag
TASEdit_show_lag_frames ^= 1;
CheckMenuItem(hmenu, ID_VIEW_SHOW_LAG_FRAMES, TASEdit_show_lag_frames?MF_CHECKED : MF_UNCHECKED);
RedrawListAndBookmarks();
tasedit_list.RedrawList();
bookmarks.RedrawBookmarksList();
break;
case ID_VIEW_SHOW_MARKERS:
//switch "Show Markers" flag
@ -1088,6 +1201,10 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
TASEdit_combine_consecutive_rec ^= 1;
CheckMenuItem(hmenu, ID_CONFIG_COMBINECONSECUTIVERECORDINGS, TASEdit_combine_consecutive_rec?MF_CHECKED : MF_UNCHECKED);
break;
case ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE:
TASEdit_superimpose_affects_paste ^= 1;
CheckMenuItem(hmenu, ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE, TASEdit_superimpose_affects_paste?MF_CHECKED : MF_UNCHECKED);
break;
case ID_CONFIG_MUTETURBO:
muteTurbo ^= 1;
CheckMenuItem(hmenu, ID_CONFIG_MUTETURBO, muteTurbo?MF_CHECKED : MF_UNCHECKED);
@ -1194,6 +1311,11 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
tasedit_list.FollowSelection();
break;
}
case IDC_TEXT_SELECTION_BUTTON:
{
tasedit_list.FollowSelection();
break;
}
}
break;
@ -1235,6 +1357,7 @@ void EnterTasEdit()
hrmenu = LoadMenu(fceu_hInstance,"TASEDITCONTEXTMENUS");
// check option ticks
CheckDlgButton(hwndTasEdit, CHECK_FOLLOW_CURSOR, TASEdit_follow_playback?MF_CHECKED : MF_UNCHECKED);
CheckDlgButton(hwndTasEdit, CHECK_TURBO_SEEK, TASEdit_turbo_seek?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_VIEW_SHOW_LAG_FRAMES, TASEdit_show_lag_frames?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_VIEW_SHOW_MARKERS, TASEdit_show_markers?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_VIEW_SHOWBRANCHSCREENSHOTS, TASEdit_show_branch_screenshots?MF_CHECKED : MF_UNCHECKED);
@ -1242,10 +1365,11 @@ void EnterTasEdit()
CheckMenuItem(hmenu, ID_VIEW_ENABLEHOTCHANGES, TASEdit_enable_hot_changes?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_CONFIG_BRANCHESRESTOREFULLMOVIE, TASEdit_branch_full_movie?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_CONFIG_BRANCHESWORKONLYWHENRECORDING, TASEdit_branch_only_when_rec?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_CONFIG_COMBINECONSECUTIVERECORDINGS, TASEdit_combine_consecutive_rec?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_CONFIG_HUDINBRANCHSCREENSHOTS, TASEdit_branch_scr_hud?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_CONFIG_BINDMARKERSTOINPUT, TASEdit_bind_markers?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_CONFIG_USE1PFORRECORDING, TASEdit_use_1p_rec?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_CONFIG_COMBINECONSECUTIVERECORDINGS, TASEdit_combine_consecutive_rec?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE, TASEdit_superimpose_affects_paste?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_CONFIG_MUTETURBO, muteTurbo?MF_CHECKED : MF_UNCHECKED);
CheckDlgButton(hwndTasEdit,CHECK_AUTORESTORE_PLAYBACK,TASEdit_restore_position?BST_CHECKED:BST_UNCHECKED);
CheckDlgButton(hwndTasEdit, IDC_SUPERIMPOSE, TASEdit_superimpose);
@ -1274,6 +1398,7 @@ void EnterTasEdit()
markers.init();
project.init();
bookmarks.init();
screenshot_display.init();
history.init(TasEdit_undo_levels);
selection.init(TasEdit_undo_levels);
SetFocus(history.hwndHistoryList); // set focus only once, to show selection cursor
@ -1303,6 +1428,7 @@ bool ExitTasEdit()
markers.free();
greenzone.clearGreenzone();
bookmarks.free();
screenshot_display.free();
history.free();
playback.SeekingStop();
selection.free();

View File

@ -1,14 +1,14 @@
#define GREENZONE_CAPACITY_DEFAULT 10000
#define GREENZONE_CAPACITY_MIN 1
#define GREENZONE_CAPACITY_MAX 50000
#define GREENZONE_CAPACITY_DEFAULT 10000
#define UNDO_LEVELS_MIN 1
#define UNDO_LEVELS_MAX 999
#define UNDO_LEVELS_DEFAULT 100
#define UNDO_LEVELS_DEFAULT 99
#define AUTOSAVE_PERIOD_DEFAULT 10 // in minutes
#define AUTOSAVE_PERIOD_MIN 0 // 0 = no autosave
#define AUTOSAVE_PERIOD_MAX 60 // 1 hour
#define AUTOSAVE_PERIOD_DEFAULT 10 // in minutes
enum ECONTEXTMENU
{
@ -20,15 +20,15 @@ void EnterTasEdit();
void InitDialog();
bool ExitTasEdit();
void UpdateTasEdit();
void RedrawWindowCaption();
void RedrawTasedit();
void RedrawListAndBookmarks();
void RedrawRowAndBookmark(int index);
void RedrawWindowCaption();
void ToggleJoypadBit(int column_index, int row_index, UINT KeyFlags);
void OpenProject();
bool SaveProject();
bool SaveProjectAs();
bool AskSaveProject();
void Import();
void Export();
void CloneFrames();
void InsertFrames();
void InsertNumFrames();
@ -39,6 +39,7 @@ void ColumnSet(int column);
bool Copy(SelectionFrames* current_selection = 0);
void Cut();
bool Paste();
bool PasteInsert();
void GotFocus();
void LostFocus();

View File

@ -7,16 +7,25 @@
#pragma comment(lib, "msimg32.lib")
extern HWND hwndTasEdit;
extern int TasEdit_wndx, TasEdit_wndy;
extern void RedrawRowAndBookmark(int index);
LRESULT APIENTRY BookmarksListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT APIENTRY BranchesBitmapWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
WNDPROC hwndBookmarksList_oldWndProc, hwndBranchesBitmap_oldWndProc;
extern SCREENSHOT_DISPLAY screenshot_display;
extern PLAYBACK playback;
extern GREENZONE greenzone;
extern TASEDIT_PROJECT project;
extern INPUT_HISTORY history;
extern TASEDIT_LIST tasedit_list;
extern bool TASEdit_show_lag_frames;
extern bool TASEdit_bind_markers;
extern bool TASEdit_branch_full_movie;
extern bool TASEdit_branch_only_when_rec;
extern bool TASEdit_view_branches_tree;
// resources
char szClassName[] = "ScrBmp";
char bookmarks_save_id[BOOKMARKS_ID_LEN] = "BOOKMARKS";
char bookmarksCaption[3][23] = { " Bookmarks ", " Bookmarks / Branches ", " Branches " };
// color tables for flashing when saving/loading bookmarks
@ -30,20 +39,6 @@ COLORREF bookmark_flash_colors[3][FLASH_PHASE_MAX+1] = {
// corners cursor animation
int corners_cursor_shift[BRANCHES_ANIMATION_FRAMES] = {0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0 };
extern PLAYBACK playback;
extern GREENZONE greenzone;
extern TASEDIT_PROJECT project;
extern INPUT_HISTORY history;
extern MARKERS markers;
extern TASEDIT_LIST tasedit_list;
extern bool TASEdit_show_lag_frames;
extern bool TASEdit_bind_markers;
extern bool TASEdit_branch_full_movie;
extern bool TASEdit_branch_only_when_rec;
extern bool TASEdit_view_branches_tree;
extern bool TASEdit_show_branch_screenshots;
BOOKMARKS::BOOKMARKS()
{
// create font
@ -61,39 +56,6 @@ BOOKMARKS::BOOKMARKS()
list_tme.cbSize = sizeof(tme);
list_tme.dwFlags = TME_LEAVE;
list_tme.hwndTrack = hwndBookmarksList;
// create BITMAPINFO for scr_bmp
scr_bmi = (LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
scr_bmi->bmiHeader.biSize = sizeof(scr_bmi->bmiHeader);
scr_bmi->bmiHeader.biWidth = SCREENSHOT_WIDTH;
scr_bmi->bmiHeader.biHeight = -SCREENSHOT_HEIGHT; // negative value = top-down bmp
scr_bmi->bmiHeader.biPlanes = 1;
scr_bmi->bmiHeader.biBitCount = 8;
scr_bmi->bmiHeader.biCompression = BI_RGB;
scr_bmi->bmiHeader.biSizeImage = 0;
// register ScrBmp window class
wincl.hInstance = fceu_hInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = ScrBmpWndProc;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof(WNDCLASSEX);
wincl.hIcon = 0;
wincl.hIconSm = 0;
wincl.hCursor = 0;
wincl.lpszMenuName = 0;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = 0;
if(!RegisterClassEx(&wincl))
FCEU_printf("Error registering ScrBmp window class\n");
// create blendfunction
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.AlphaFormat = 0;
blend.SourceConstantAlpha = 255;
}
void BOOKMARKS::init()
@ -185,28 +147,16 @@ void BOOKMARKS::init()
// create pens
normal_pen = CreatePen(PS_SOLID, 1, 0x0);
select_pen = CreatePen(PS_SOLID, 2, 0xFF9080);
// prepare screenshot bitmap
// fill scr_bmp palette with current palette colors
extern PALETTEENTRY *color_palette;
for (int i = 0; i < 256; ++i)
{
scr_bmi->bmiColors[i].rgbRed = color_palette[i].peRed;
scr_bmi->bmiColors[i].rgbGreen = color_palette[i].peGreen;
scr_bmi->bmiColors[i].rgbBlue = color_palette[i].peBlue;
}
scr_bmp = CreateDIBSection(win_hdc, scr_bmi, DIB_RGB_COLORS, (void**)&scr_ptr, 0, 0);
RedrawBookmarksCaption();
next_animation_time = 0;
update();
}
void BOOKMARKS::reset()
{
transition_phase = animation_frame = 0;
mouse_x = mouse_y = -1;
screenshot_currently_shown = item_under_mouse = ITEM_UNDER_MOUSE_NONE;
scr_bmp_phase = 0;
item_under_mouse = ITEM_UNDER_MOUSE_NONE;
mouse_over_bitmap = false;
must_recalculate_branches_tree = must_redraw_branches_tree = must_check_item_under_mouse = true;
check_flash_shedule = clock() + BOOKMARKS_FLASH_TICK;
@ -257,13 +207,6 @@ void BOOKMARKS::free()
DeleteObject(branchesSpritesheet);
branchesSpritesheet = NULL;
}
if (scr_bmp)
{
DeleteObject(scr_bmp);
scr_bmp = NULL;
}
}
void BOOKMARKS::update()
@ -286,7 +229,7 @@ void BOOKMARKS::update()
if (must_recalculate_branches_tree)
RecalculateBranchesTree();
// once per 50 milliseconds update branches_bitmap and scr_bmp
// once per 50 milliseconds update branches_bitmap
if (clock() > next_animation_time)
{
// animate branches_bitmap
@ -321,58 +264,6 @@ void BOOKMARKS::update()
// render branches_bitmap
if (edit_mode == EDIT_MODE_BRANCHES && must_redraw_branches_tree)
RedrawBranchesTree();
// change screenshot_bitmap alpha if needed
if (item_under_mouse >= 0 && item_under_mouse < TOTAL_BOOKMARKS && TASEdit_show_branch_screenshots)
{
if (!hwndScrBmp)
{
// create window
hwndScrBmp = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT, szClassName, szClassName, WS_POPUP, TasEdit_wndx + scr_bmp_x, TasEdit_wndy + scr_bmp_y, SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT, hwndTasEdit, NULL, fceu_hInstance, NULL);
RedrawScreenshotBitmap();
ShowWindow(hwndScrBmp, SW_SHOWNA);
}
// change screenshot_bitmap pic if needed
if (item_under_mouse != screenshot_currently_shown)
{
if (bookmarks_array[item_under_mouse].not_empty)
ChangeScreenshotBitmap();
}
if (scr_bmp_phase < SCR_BMP_PHASE_MAX)
{
scr_bmp_phase++;
// update alpha
int phase_alpha = scr_bmp_phase;
if (phase_alpha > SCR_BMP_PHASE_ALPHA_MAX) phase_alpha = SCR_BMP_PHASE_ALPHA_MAX;
SetLayeredWindowAttributes(hwndScrBmp, 0, (255 * phase_alpha) / SCR_BMP_PHASE_ALPHA_MAX, LWA_ALPHA);
UpdateLayeredWindow(hwndScrBmp, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA);
}
} else
{
// fade and finally hide screenshot
if (scr_bmp_phase > 0)
scr_bmp_phase--;
if (scr_bmp_phase > 0)
{
if (hwndScrBmp)
{
// update alpha
int phase_alpha = scr_bmp_phase;
if (phase_alpha > SCR_BMP_PHASE_ALPHA_MAX) phase_alpha = SCR_BMP_PHASE_ALPHA_MAX;
SetLayeredWindowAttributes(hwndScrBmp, 0, (255 * phase_alpha) / SCR_BMP_PHASE_ALPHA_MAX, LWA_ALPHA);
UpdateLayeredWindow(hwndScrBmp, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA);
}
} else
{
// destroy screenshot bitmap window
scr_bmp_phase = 0;
if (hwndScrBmp)
{
DestroyWindow(hwndScrBmp);
hwndScrBmp = 0;
}
}
}
}
}
@ -390,8 +281,8 @@ void BOOKMARKS::set(int slot)
bookmarks_array[slot].set();
// if this screenshot is shown on screen - reinit and redraw it
if (screenshot_currently_shown == slot)
screenshot_currently_shown = ITEM_UNDER_MOUSE_NONE;
if (screenshot_display.screenshot_currently_shown == slot)
screenshot_display.screenshot_currently_shown = ITEM_UNDER_MOUSE_NONE;
// inherit current branch
if (slot != current_branch)
@ -421,7 +312,10 @@ void BOOKMARKS::set(int slot)
// switch current branch to this branch
if (slot != current_branch && current_branch >= 0)
RedrawRowAndBookmark(bookmarks_array[current_branch].snapshot.jump_frame);
{
tasedit_list.RedrawRow(bookmarks_array[current_branch].snapshot.jump_frame);
RedrawChangedBookmarks(bookmarks_array[current_branch].snapshot.jump_frame);
}
if (slot != current_branch || changes_since_current_branch)
must_recalculate_branches_tree = true;
current_branch = slot;
@ -429,8 +323,12 @@ void BOOKMARKS::set(int slot)
project.SetProjectChanged();
if (previous_frame >= 0 && previous_frame != currFrameCounter)
RedrawRowAndBookmark(previous_frame);
RedrawRowAndBookmark(currFrameCounter);
{
tasedit_list.RedrawRow(previous_frame);
RedrawChangedBookmarks(previous_frame);
}
tasedit_list.RedrawRow(currFrameCounter);
RedrawChangedBookmarks(currFrameCounter);
FCEU_DispMessage("Branch %d saved.", 0, slot);
}
@ -470,7 +368,7 @@ void BOOKMARKS::unleash(int slot)
{
if (bookmarks_array[slot].snapshot.checkMarkersDiff())
{
bookmarks_array[slot].snapshot.toMarkers();
bookmarks_array[slot].snapshot.copyToMarkers();
project.SetProjectChanged();
markers_changed = true;
}
@ -496,7 +394,7 @@ void BOOKMARKS::unleash(int slot)
// didn't restore anything
bookmarks_array[slot].jump();
}
} else
} else if (jump_frame > 0)
{
// update Markers
if (TASEdit_bind_markers)
@ -554,8 +452,10 @@ void BOOKMARKS::unleash(int slot)
// switch current branch to this branch
if (slot != current_branch && current_branch >= 0)
{
RedrawRowAndBookmark(bookmarks_array[current_branch].snapshot.jump_frame);
RedrawRowAndBookmark(bookmarks_array[slot].snapshot.jump_frame);
tasedit_list.RedrawRow(bookmarks_array[current_branch].snapshot.jump_frame);
RedrawChangedBookmarks(bookmarks_array[current_branch].snapshot.jump_frame);
tasedit_list.RedrawRow(bookmarks_array[slot].snapshot.jump_frame);
RedrawChangedBookmarks(bookmarks_array[slot].snapshot.jump_frame);
}
current_branch = slot;
changes_since_current_branch = false;
@ -806,28 +706,6 @@ void BOOKMARKS::RedrawBranchesTree()
InvalidateRect(hwndBranchesBitmap, 0, FALSE);
}
void BOOKMARKS::ChangeScreenshotBitmap()
{
// uncompress
uLongf destlen = SCREENSHOT_SIZE;
int e = uncompress(&scr_ptr[0], &destlen, &bookmarks_array[item_under_mouse].saved_screenshot[0], bookmarks_array[item_under_mouse].saved_screenshot.size());
if (e != Z_OK && e != Z_BUF_ERROR)
{
// error decompressing
FCEU_printf("Error decompressing screenshot %d\n", item_under_mouse);
// at least fill bitmap with zeros
memset(&scr_ptr[0], 0, SCREENSHOT_SIZE);
}
screenshot_currently_shown = item_under_mouse;
RedrawScreenshotBitmap();
}
void BOOKMARKS::RedrawScreenshotBitmap()
{
HBITMAP temp_bmp = (HBITMAP)SendMessage(scr_bmp_pic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)scr_bmp);
if (temp_bmp && temp_bmp != scr_bmp)
DeleteObject(temp_bmp);
}
// this is called by wndproc on WM_PAINT
void BOOKMARKS::PaintBranchesBitmap(HDC hdc)
{
@ -1414,21 +1292,5 @@ LRESULT APIENTRY BranchesBitmapWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARA
}
return CallWindowProc(hwndBranchesBitmap_oldWndProc, hWnd, msg, wParam, lParam);
}
// ----------------------------------------------------------------------------------------
LRESULT APIENTRY ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
extern BOOKMARKS bookmarks;
switch(message)
{
case WM_CREATE:
{
// create static bitmap placeholder
bookmarks.scr_bmp_pic = CreateWindow(WC_STATIC, NULL, SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 255, 255, hwnd, NULL, NULL, NULL);
return 0;
}
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}

View File

@ -1,5 +1,4 @@
//Specification file for Bookmarks class
#include "bookmark.h"
#define TOTAL_BOOKMARKS 10
@ -85,10 +84,6 @@
#define BOOKMARKS_ID_LEN 10
#define TIME_DESC_LENGTH 9 // "HH:MM:SS"
// screenshot bitmap
#define SCR_BMP_PHASE_MAX 11
#define SCR_BMP_PHASE_ALPHA_MAX 8
class BOOKMARKS
{
public:
@ -129,9 +124,6 @@ public:
void RecursiveAddHeight(int branch_num, int amount);
void RecursiveSetYPos(int parent, int parentY);
void ChangeScreenshotBitmap();
void RedrawScreenshotBitmap();
std::vector<BOOKMARK> bookmarks_array;
// not saved vars
@ -139,17 +131,7 @@ public:
int branch_row_left;
int branch_row_height;
bool mouse_over_bitmap, mouse_over_bookmarkslist;
// screenshot bmp stuff
LPBITMAPINFO scr_bmi;
HBITMAP scr_bmp;
uint8* scr_ptr;
int scr_bmp_x;
int scr_bmp_y;
int scr_bmp_phase;
int screenshot_currently_shown;
HWND hwndScrBmp, scr_bmp_pic;
WNDCLASSEX wincl;
BLENDFUNCTION blend;
int item_under_mouse;
TRACKMOUSEEVENT tme, list_tme;
private:
@ -164,7 +146,7 @@ private:
// not saved vars
int check_flash_shedule;
int edit_mode;
int animation_frame; // 0-13
int animation_frame;
int next_animation_time;
bool must_check_item_under_mouse;
bool must_redraw_branches_tree;
@ -180,7 +162,6 @@ private:
int transition_phase;
int fireball_size;
int mouse_x, mouse_y;
int item_under_mouse;
HWND hwndBookmarksList, hwndBookmarks;
HWND hwndBranchesBitmap;
@ -193,12 +174,10 @@ private:
HBITMAP branches_hbitmap, hOldBitmap, buffer_hbitmap, hOldBitmap1, branchesSpritesheet, hOldBitmap2;
HDC hBitmapDC, hBufferDC, hSpritesheetDC;
// temps
std::vector<int> GridX; // in grid units
std::vector<int> GridY;
std::vector<int> GridHeight;
std::vector<std::vector<uint8>> Children;
};

View File

@ -6,11 +6,14 @@
extern TASEDIT_PROJECT project;
extern PLAYBACK playback;
extern BOOKMARKS bookmarks;
extern TASEDIT_LIST tasedit_list;
extern int TASEdit_greenzone_capacity;
extern bool TASEdit_restore_position;
extern void FCEU_printf(char *format, ...);
extern void RedrawListAndBookmarks();
char greenzone_save_id[GREENZONE_ID_LEN] = "GREENZONE";
@ -151,7 +154,11 @@ void GREENZONE::GreenzoneCleaning()
}
}
finish:
if (changed) RedrawListAndBookmarks();
if (changed)
{
tasedit_list.RedrawList();
bookmarks.RedrawBookmarksList();
}
// shedule next cleaning
next_cleaning_time = clock() + TIME_BETWEEN_CLEANINGS;
}
@ -334,7 +341,8 @@ void GREENZONE::InvalidateAndCheck(int after)
}
}
// redraw list even if greenzone didn't change
RedrawListAndBookmarks();
tasedit_list.RedrawList();
bookmarks.RedrawBookmarksList();
}
// This version doesn't restore playback, may be used only by Branching and Recording functions!
void GREENZONE::Invalidate(int after)
@ -349,7 +357,8 @@ void GREENZONE::Invalidate(int after)
}
}
// redraw list even if greenzone didn't change
RedrawListAndBookmarks();
tasedit_list.RedrawList();
bookmarks.RedrawBookmarksList();
}
int GREENZONE::FindBeginningOfGreenZone(int starting_index)

View File

@ -148,7 +148,7 @@ int INPUT_HISTORY::jump(int new_pos)
{
if (input_snapshots[real_pos].checkMarkersDiff())
{
input_snapshots[real_pos].toMarkers();
input_snapshots[real_pos].copyToMarkers();
project.SetProjectChanged();
markers_changed = true;
}
@ -313,10 +313,12 @@ int INPUT_HISTORY::RegisterChanges(int mod_type, int start, int end)
inp.inheritHotChanges_DeleteSelection(&input_snapshots[real_pos]);
break;
case MODTYPE_INSERT:
case MODTYPE_PASTEINSERT:
case MODTYPE_CLONE:
inp.inheritHotChanges_InsertSelection(&input_snapshots[real_pos]);
break;
case MODTYPE_PASTEINSERT:
inp.inheritHotChanges_PasteInsert(&input_snapshots[real_pos]);
break;
case MODTYPE_CHANGE:
case MODTYPE_SET:
case MODTYPE_UNSET:

View File

@ -53,8 +53,7 @@ void INPUT_SNAPSHOT::init(MovieData& md, bool hotchanges)
}
}
// make a copy of markers.markers_array
markers_array = markers.markers_array;
markers.MakeCopy(markers_array);
coherent = true;
// save time to description
time_t raw_time;
@ -63,20 +62,11 @@ void INPUT_SNAPSHOT::init(MovieData& md, bool hotchanges)
strftime(description, 10, "%H:%M:%S", timeinfo);
}
// copy all stored markers to Markers
void INPUT_SNAPSHOT::toMarkers()
{
markers.markers_array = markers_array;
}
// copy some stored markers to Markers manually, from Frame 0 to end frame (including end frame)
void INPUT_SNAPSHOT::copyToMarkers(int end)
{
if ((int)markers.markers_array.size() <= end) markers.markers_array.resize(end+1);
for (int i = end; i >= 0; i--)
markers.markers_array[i] = markers_array[i];
markers.RestoreFromCopy(markers_array, end);
}
void INPUT_SNAPSHOT::toMovie(MovieData& md, int start, int end)
{
if (end < 0) end = size-1;
@ -327,17 +317,17 @@ bool INPUT_SNAPSHOT::checkMarkersDiff(INPUT_SNAPSHOT& inp)
// return true if any difference in markers_array is found, comparing to markers.markers_array
bool INPUT_SNAPSHOT::checkMarkersDiff()
{
if (markers_array.size() != markers.markers_array.size()) return true;
if (markers_array.size() != markers.GetMarkersSize()) return true;
for (int i = markers_array.size()-1; i >= 0; i--)
if ((markers_array[i] - markers.markers_array[i]) & MARKER_FLAG_BIT) return true;
if ((bool)(markers_array[i] & MARKER_FLAG_BIT) != markers.GetMarker(i)) return true;
return false;
}
// return true only when difference is found before end frame (not including end frame)
bool INPUT_SNAPSHOT::checkMarkersDiff(int end)
{
if (markers_array.size() != markers.markers_array.size() && ((int)markers_array.size()-1 < end || (int)markers.markers_array.size()-1 < end)) return true;
if (markers_array.size() != markers.GetMarkersSize() && ((int)markers_array.size()-1 < end || (int)markers.GetMarkersSize()-1 < end)) return true;
for (int i = end-1; i >= 0; i--)
if ((markers_array[i] - markers.markers_array[i]) & MARKER_FLAG_BIT) return true;
if ((bool)(markers_array[i] & MARKER_FLAG_BIT) != markers.GetMarker(i)) return true;
return false;
}
@ -527,7 +517,7 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of
int this_size = hot_changes.size(), source_size = source_of_hotchanges->hot_changes.size();
SelectionFrames::iterator it(selection.GetStrobedSelection().begin());
SelectionFrames::iterator current_selection_end(selection.GetStrobedSelection().end());
while (pos < this_size && source_pos < source_size)
while (pos < this_size)
{
if (it != current_selection_end && frame == *it)
{
@ -536,17 +526,16 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of
region_len++;
// set filled line to the frame
memset(&hot_changes[pos], 0xFF, bytes);
pos += bytes;
} else
} else if (source_pos < source_size)
{
// this frame is not selected
frame -= region_len;
region_len = 0;
// copy hotchanges of this frame
memcpy(&hot_changes[pos], &source_of_hotchanges->hot_changes[source_pos], bytes);
pos += bytes;
source_pos += bytes;
}
pos += bytes;
frame++;
}
FadeHotChanges();
@ -567,7 +556,6 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of
region_len++;
// set filled line to the frame
memset(&hot_changes[pos], 0xFF, bytes);
pos += bytes;
// exit loop when all selection frames are handled
if (it == current_selection_end) break;
} else
@ -576,6 +564,62 @@ void INPUT_SNAPSHOT::inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of
frame -= region_len;
region_len = 0;
// leave zeros in this frame
}
pos += bytes;
frame++;
}
}
}
void INPUT_SNAPSHOT::inheritHotChanges_PasteInsert(INPUT_SNAPSHOT* source_of_hotchanges)
{
// copy hot changes from source snapshot and insert filled lines for inserted frames (which are represented by inserted_set)
if (source_of_hotchanges && source_of_hotchanges->has_hot_changes)
{
int bytes = bytes_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY;
int frame = 0, pos = 0, source_pos = 0;
int this_size = hot_changes.size(), source_size = source_of_hotchanges->hot_changes.size();
SelectionFrames::iterator it(selection.GetInsertedSet().begin());
SelectionFrames::iterator inserted_set_end(selection.GetInsertedSet().end());
while (pos < this_size)
{
if (it != inserted_set_end && frame == *it)
{
// this frame was inserted
it++;
// set filled line to the frame
memset(&hot_changes[pos], 0xFF, bytes);
} else if (source_pos < source_size)
{
// copy hotchanges of this frame
memcpy(&hot_changes[pos], &source_of_hotchanges->hot_changes[source_pos], bytes);
source_pos += bytes;
}
pos += bytes;
frame++;
}
FadeHotChanges();
} else
{
// no old data, just fill selected lines
int bytes = bytes_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY;
int frame = 0, pos = 0;
int this_size = hot_changes.size();
SelectionFrames::iterator it(selection.GetInsertedSet().begin());
SelectionFrames::iterator inserted_set_end(selection.GetInsertedSet().end());
while (pos < this_size)
{
if (it != inserted_set_end && frame == *it)
{
// this frame was inserted
it++;
// set filled line to the frame
memset(&hot_changes[pos], 0xFF, bytes);
pos += bytes;
// exit loop when all inserted_set frames are handled
if (it == inserted_set_end) break;
} else
{
// leave zeros in this frame
pos += bytes;
}
frame++;

View File

@ -15,7 +15,7 @@ public:
void toMovie(MovieData& md, int start = 0, int end = -1);
void toMarkers();
void copyToMarkers(int end);
void copyToMarkers(int end = -1);
void save(EMUFILE *os);
bool load(EMUFILE *is);
@ -37,6 +37,7 @@ public:
void inheritHotChanges(INPUT_SNAPSHOT* source_of_hotchanges);
void inheritHotChanges_DeleteSelection(INPUT_SNAPSHOT* source_of_hotchanges);
void inheritHotChanges_InsertSelection(INPUT_SNAPSHOT* source_of_hotchanges);
void inheritHotChanges_PasteInsert(INPUT_SNAPSHOT* source_of_hotchanges);
void fillHotChanges(INPUT_SNAPSHOT& inp, int start = 0, int end = -1);
void SetMaxHotChange_Bits(int frame, int joypad, uint8 joy_bits);

View File

@ -66,12 +66,66 @@ error:
return true;
}
// ----------------------------------------------------------
void MARKERS::MakeCopy(std::vector<uint8> &destination_array)
{
// copy array
destination_array = markers_array;
// copy notes
}
void MARKERS::RestoreFromCopy(std::vector<uint8> &source_array, int until_frame)
{
if (until_frame >= 0)
{
// restore array up to and including the frame
if ((int)markers_array.size() <= until_frame) markers_array.resize(until_frame+1);
for (int i = until_frame; i >= 0; i--)
markers_array[i] = source_array[i];
// restore notes
} else
{
// restore array
markers_array = source_array;
// restore notes
}
}
int MARKERS::GetMarkersSize()
{
return markers_array.size();
}
bool MARKERS::GetMarker(int frame)
{
if (frame >= 0 && frame < (int)markers_array.size())
return markers_array[frame] & MARKER_FLAG_BIT;
return false;
}
void MARKERS::SetMarker(int frame)
{
markers_array[frame] |= MARKER_FLAG_BIT;
}
void MARKERS::ClearMarker(int frame)
{
markers_array[frame] &= ~MARKER_FLAG_BIT;
}
void MARKERS::EraseMarker(int frame)
{
// check if there's a marker, delete note if needed
markers_array.erase(markers_array.begin() + frame);
}
void MARKERS::ToggleMarker(int frame)
{
if (markers_array[frame] & MARKER_FLAG_BIT)
markers_array[frame] &= ~MARKER_FLAG_BIT;
else
markers_array[frame] |= MARKER_FLAG_BIT;
if (frame >= 0 && frame < (int)markers_array.size())
{
if (markers_array[frame] & MARKER_FLAG_BIT)
markers_array[frame] &= ~MARKER_FLAG_BIT;
else
markers_array[frame] |= MARKER_FLAG_BIT;
}
}
void MARKERS::insertEmpty(int at, int frames)

View File

@ -15,12 +15,21 @@ public:
void save(EMUFILE *os);
bool load(EMUFILE *is);
void MakeCopy(std::vector<uint8> &destination_array);
void RestoreFromCopy(std::vector<uint8> &source_array, int until_frame = -1);
bool GetMarker(int frame);
int GetMarkersSize();
void SetMarker(int frame);
void ClearMarker(int frame);
void EraseMarker(int frame);
void ToggleMarker(int frame);
void insertEmpty(int at, int frames);
void truncateAt(int frame);
private:
std::vector<uint8> markers_array;
private:
};

View File

@ -1,5 +1,4 @@
//Implementation file of Playback class
#include "taseditproj.h"
#ifdef _S9XLUA_H
@ -7,16 +6,14 @@ extern void ForceExecuteLuaFrameFunctions();
#endif
extern HWND hwndTasEdit;
extern void FCEU_printf(char *format, ...);
extern void RedrawListAndBookmarks();
extern void RedrawRowAndBookmark(int index);
extern bool Tasedit_rewind_now;
extern bool turbo;
extern bool TASEdit_turbo_seek;
extern MARKERS markers;
extern GREENZONE greenzone;
extern TASEDIT_LIST tasedit_list;
extern bool Tasedit_rewind_now;
extern BOOKMARKS bookmarks;
PLAYBACK::PLAYBACK()
{
@ -35,7 +32,7 @@ void PLAYBACK::init()
}
void PLAYBACK::reset()
{
lastCursor = -1;
lastCursor = currFrameCounter;
pause_frame = old_pauseframe = 0;
old_show_pauseframe = show_pauseframe = false;
old_rewind_button_state = rewind_button_state = false;
@ -53,7 +50,12 @@ void PLAYBACK::update()
SeekingStop();
// update flashing pauseframe
if (old_pauseframe != pause_frame && old_pauseframe) RedrawRowAndBookmark(old_pauseframe-1);
if (old_pauseframe != pause_frame && old_pauseframe)
{
// pause_frame was changed, clear old_pauseframe gfx
tasedit_list.RedrawRow(old_pauseframe-1);
bookmarks.RedrawChangedBookmarks(old_pauseframe-1);
}
old_pauseframe = pause_frame;
old_show_pauseframe = show_pauseframe;
if (pause_frame)
@ -63,7 +65,12 @@ void PLAYBACK::update()
else
show_pauseframe = (int)(clock() / PAUSEFRAME_BLINKING_PERIOD_SEEKING) & 1;
} else show_pauseframe = false;
if (old_show_pauseframe != show_pauseframe) RedrawRowAndBookmark(pause_frame-1);
if (old_show_pauseframe != show_pauseframe)
{
// update pauseframe gfx
tasedit_list.RedrawRow(pause_frame-1);
bookmarks.RedrawChangedBookmarks(pause_frame-1);
}
// update seeking progressbar
old_emu_paused = emu_paused;
@ -83,13 +90,16 @@ void PLAYBACK::update()
SetProgressbar(1, 1);
}
//update the playback cursor
// update the playback cursor
if(currFrameCounter != lastCursor)
{
tasedit_list.FollowPlayback();
//update the old and new rows
RedrawRowAndBookmark(lastCursor);
RedrawRowAndBookmark(currFrameCounter);
// update gfx of the old and new rows
tasedit_list.RedrawRow(lastCursor);
bookmarks.RedrawChangedBookmarks(lastCursor);
tasedit_list.RedrawRow(currFrameCounter);
bookmarks.RedrawChangedBookmarks(currFrameCounter);
// enforce redrawing now
UpdateWindow(tasedit_list.hwndList);
lastCursor = currFrameCounter;
}
@ -187,7 +197,8 @@ void PLAYBACK::SeekingStart(int finish_frame)
{
seeking_start_frame = currFrameCounter;
pause_frame = finish_frame;
turbo = true;
if (TASEdit_turbo_seek)
turbo = true;
UnpauseEmulation();
}
void PLAYBACK::SeekingStop()
@ -201,7 +212,10 @@ void PLAYBACK::SeekingStop()
void PLAYBACK::RewindFrame()
{
if (pause_frame && !emu_paused) return;
if (currFrameCounter > 0) jump(currFrameCounter-1);
if (currFrameCounter > 0)
jump(currFrameCounter-1);
else
tasedit_list.FollowPlayback();
if (!pause_frame) PauseEmulation();
}
void PLAYBACK::ForwardFrame()
@ -214,31 +228,25 @@ void PLAYBACK::ForwardFrame()
void PLAYBACK::RewindFull()
{
// jump to previous marker
if (currFrameCounter > 0)
{
int index = currFrameCounter - 1;
for (; index >= 0; index--)
if (markers.markers_array[index] & MARKER_FLAG_BIT) break;
if (index >= 0)
jump(index);
else if (currFrameCounter > 0)
jump(0);
}
int index = currFrameCounter - 1;
for (; index >= 0; index--)
if (markers.GetMarker(index)) break;
if (index >= 0)
jump(index);
else
jump(0);
}
void PLAYBACK::ForwardFull()
{
// jump to next marker
int last_frame = currMovieData.getNumRecords()-1;
if (currFrameCounter < last_frame)
{
int index = currFrameCounter + 1;
for (; index < last_frame; ++index)
if (markers.markers_array[index] & MARKER_FLAG_BIT) break;
if (index <= last_frame)
jump(index);
else if (currFrameCounter < last_frame)
jump(last_frame);
}
int index = currFrameCounter + 1;
for (; index <= last_frame; ++index)
if (markers.GetMarker(index)) break;
if (index <= last_frame)
jump(index);
else
jump(last_frame);
}
void PLAYBACK::StartFromZero()

View File

@ -38,14 +38,14 @@ public:
int GetPauseFrame();
void SetProgressbar(int a, int b);
int pause_frame;
HWND hwndProgressbar, hwndRewind, hwndForward, hwndRewindFull, hwndForwardFull;
private:
bool JumpToFrame(int index);
int pause_frame;
int lastCursor; // for currentCursor we use external variable currFrameCounter
int lastCursor; // but for currentCursor we use external variable currFrameCounter
bool old_emu_paused, emu_paused;
int old_pauseframe;
bool old_show_pauseframe, show_pauseframe;

View File

@ -14,7 +14,7 @@ extern bool TASEdit_use_1p_rec;
extern int TASEdit_superimpose;
// resources
char windowCaptions[5][30] = { " (Recording All)",
char recordingCaptions[5][30] = { " (Recording All)",
" (Recording 1P)",
" (Recording 2P)",
" (Recording 3P)",
@ -100,7 +100,7 @@ void RECORDER::RecheckRecordingRadioButtons()
}
}
void RECORDER::InputChangedRec()
void RECORDER::InputChanged()
{
bool changes_made = false;
// take previous values from current snapshot, new input from current movie

View File

@ -17,7 +17,7 @@ public:
void UncheckRecordingRadioButtons();
void RecheckRecordingRadioButtons();
void InputChangedRec();
void InputChanged();
int multitrack_recording_joypad;
HWND hwndRB_RecOff, hwndRB_RecAll, hwndRB_Rec1P, hwndRB_Rec2P, hwndRB_Rec3P, hwndRB_Rec4P;

View File

@ -0,0 +1,195 @@
//Implementation file of SCREENSHOT_DISPLAY class
#include "taseditproj.h"
#include "zlib.h"
extern HWND hwndTasEdit;
extern int TasEdit_wndx, TasEdit_wndy;
extern bool TASEdit_show_branch_screenshots;
extern BOOKMARKS bookmarks;
extern TASEDIT_LIST tasedit_list;
LRESULT CALLBACK ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
// resources
char szClassName[] = "ScrBmp";
SCREENSHOT_DISPLAY::SCREENSHOT_DISPLAY()
{
// create BITMAPINFO
scr_bmi = (LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); // 256 color in palette
scr_bmi->bmiHeader.biSize = sizeof(scr_bmi->bmiHeader);
scr_bmi->bmiHeader.biWidth = SCREENSHOT_WIDTH;
scr_bmi->bmiHeader.biHeight = -SCREENSHOT_HEIGHT; // negative value = top-down bmp
scr_bmi->bmiHeader.biPlanes = 1;
scr_bmi->bmiHeader.biBitCount = 8;
scr_bmi->bmiHeader.biCompression = BI_RGB;
scr_bmi->bmiHeader.biSizeImage = 0;
// register ScrBmp window class
wincl.hInstance = fceu_hInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = ScrBmpWndProc;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof(WNDCLASSEX);
wincl.hIcon = 0;
wincl.hIconSm = 0;
wincl.hCursor = 0;
wincl.lpszMenuName = 0;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = 0;
if(!RegisterClassEx(&wincl))
FCEU_printf("Error registering SCR_DISPLAY window class\n");
// create blendfunction
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.AlphaFormat = 0;
blend.SourceConstantAlpha = 255;
}
void SCREENSHOT_DISPLAY::init()
{
free();
// fill scr_bmp palette with current palette colors
extern PALETTEENTRY *color_palette;
for (int i = 0; i < 256; ++i)
{
scr_bmi->bmiColors[i].rgbRed = color_palette[i].peRed;
scr_bmi->bmiColors[i].rgbGreen = color_palette[i].peGreen;
scr_bmi->bmiColors[i].rgbBlue = color_palette[i].peBlue;
}
HDC win_hdc = GetWindowDC(tasedit_list.hwndList);
scr_bmp = CreateDIBSection(win_hdc, scr_bmi, DIB_RGB_COLORS, (void**)&scr_ptr, 0, 0);
// calculate coordinates (relative to the listview top-left corner)
RECT temp_rect, parent_rect;
GetWindowRect(hwndTasEdit, &parent_rect);
GetWindowRect(tasedit_list.hwndHeader, &temp_rect);
scr_bmp_x = temp_rect.left - parent_rect.left;
scr_bmp_y = temp_rect.bottom - parent_rect.top;
}
void SCREENSHOT_DISPLAY::free()
{
reset();
if (scr_bmp)
{
DeleteObject(scr_bmp);
scr_bmp = 0;
}
}
void SCREENSHOT_DISPLAY::reset()
{
screenshot_currently_shown = ITEM_UNDER_MOUSE_NONE;
next_update_time = scr_bmp_phase = 0;
if (hwndScrBmp)
{
DestroyWindow(hwndScrBmp);
hwndScrBmp = 0;
}
}
void SCREENSHOT_DISPLAY::update()
{
// once per 40 milliseconds update screenshot_bitmap alpha
if (clock() > next_update_time)
{
next_update_time = clock() + DISPLAY_UPDATE_TICK;
if (bookmarks.item_under_mouse >= 0 && bookmarks.item_under_mouse < TOTAL_BOOKMARKS && TASEdit_show_branch_screenshots)
{
if (!hwndScrBmp)
{
// create window
hwndScrBmp = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT, szClassName, szClassName, WS_POPUP, TasEdit_wndx + scr_bmp_x, TasEdit_wndy + scr_bmp_y, SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT, hwndTasEdit, NULL, fceu_hInstance, NULL);
RedrawScreenshotBitmap();
ShowWindow(hwndScrBmp, SW_SHOWNA);
}
// change screenshot_bitmap pic if needed
if (bookmarks.item_under_mouse != screenshot_currently_shown)
{
if (bookmarks.bookmarks_array[bookmarks.item_under_mouse].not_empty)
ChangeScreenshotBitmap();
}
if (scr_bmp_phase < SCR_BMP_PHASE_MAX)
{
scr_bmp_phase++;
// update alpha
int phase_alpha = scr_bmp_phase;
if (phase_alpha > SCR_BMP_PHASE_ALPHA_MAX) phase_alpha = SCR_BMP_PHASE_ALPHA_MAX;
SetLayeredWindowAttributes(hwndScrBmp, 0, (255 * phase_alpha) / SCR_BMP_PHASE_ALPHA_MAX, LWA_ALPHA);
UpdateLayeredWindow(hwndScrBmp, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA);
}
} else
{
// fade and finally hide screenshot
if (scr_bmp_phase > 0)
scr_bmp_phase--;
if (scr_bmp_phase > 0)
{
if (hwndScrBmp)
{
// update alpha
int phase_alpha = scr_bmp_phase;
if (phase_alpha > SCR_BMP_PHASE_ALPHA_MAX) phase_alpha = SCR_BMP_PHASE_ALPHA_MAX;
SetLayeredWindowAttributes(hwndScrBmp, 0, (255 * phase_alpha) / SCR_BMP_PHASE_ALPHA_MAX, LWA_ALPHA);
UpdateLayeredWindow(hwndScrBmp, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA);
}
} else
{
// destroy screenshot bitmap window
scr_bmp_phase = 0;
if (hwndScrBmp)
{
DestroyWindow(hwndScrBmp);
hwndScrBmp = 0;
}
}
}
}
}
void SCREENSHOT_DISPLAY::ChangeScreenshotBitmap()
{
// uncompress
uLongf destlen = SCREENSHOT_SIZE;
int e = uncompress(&scr_ptr[0], &destlen, &bookmarks.bookmarks_array[bookmarks.item_under_mouse].saved_screenshot[0], bookmarks.bookmarks_array[bookmarks.item_under_mouse].saved_screenshot.size());
if (e != Z_OK && e != Z_BUF_ERROR)
{
// error decompressing
FCEU_printf("Error decompressing screenshot %d\n", bookmarks.item_under_mouse);
// at least fill bitmap with zeros
memset(&scr_ptr[0], 0, SCREENSHOT_SIZE);
}
screenshot_currently_shown = bookmarks.item_under_mouse;
RedrawScreenshotBitmap();
}
void SCREENSHOT_DISPLAY::RedrawScreenshotBitmap()
{
HBITMAP temp_bmp = (HBITMAP)SendMessage(scr_bmp_pic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)scr_bmp);
if (temp_bmp && temp_bmp != scr_bmp)
DeleteObject(temp_bmp);
}
void SCREENSHOT_DISPLAY::ParentWindowMoved()
{
if (hwndScrBmp)
SetWindowPos(hwndScrBmp, 0, TasEdit_wndx + scr_bmp_x, TasEdit_wndy + scr_bmp_y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
}
// ----------------------------------------------------------------------------------------
LRESULT APIENTRY ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
extern SCREENSHOT_DISPLAY screenshot_display;
switch(message)
{
case WM_CREATE:
{
// create static bitmap placeholder
screenshot_display.scr_bmp_pic = CreateWindow(WC_STATIC, NULL, SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 255, 255, hwnd, NULL, NULL, NULL);
return 0;
}
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}

View File

@ -0,0 +1,37 @@
//Specification file for SCREENSHOT_DISPLAY class
#define SCR_BMP_PHASE_MAX 13
#define SCR_BMP_PHASE_ALPHA_MAX 10
#define DISPLAY_UPDATE_TICK 40 // update at 25FPS
class SCREENSHOT_DISPLAY
{
public:
SCREENSHOT_DISPLAY();
void init();
void free();
void reset();
void update();
void ChangeScreenshotBitmap();
void RedrawScreenshotBitmap();
void ParentWindowMoved();
int screenshot_currently_shown;
HWND hwndScrBmp, scr_bmp_pic;
private:
int scr_bmp_x;
int scr_bmp_y;
int scr_bmp_phase;
int next_update_time;
WNDCLASSEX wincl;
BLENDFUNCTION blend;
LPBITMAPINFO scr_bmi;
HBITMAP scr_bmp;
uint8* scr_ptr;
};

View File

@ -27,6 +27,7 @@ WNDPROC hwndList_oldWndProc, hwndHeader_oldWndproc;
// resources
COLORREF hot_changes_colors[16] = { 0x0, 0x661212, 0x842B4E, 0x652C73, 0x48247D, 0x383596, 0x2947AE, 0x1E53C1, 0x135DD2, 0x116EDA, 0x107EE3, 0x0F8EEB, 0x209FF4, 0x3DB1FD, 0x51C2FF, 0x4DCDFF };
char list_save_id[LIST_ID_LEN] = "LIST";
TASEDIT_LIST::TASEDIT_LIST()
{
@ -49,7 +50,7 @@ TASEDIT_LIST::TASEDIT_LIST()
void TASEDIT_LIST::init()
{
//free();
free();
hwndList = GetDlgItem(hwndTasEdit, IDC_LIST1);
// prepare the main listview
@ -153,18 +154,16 @@ void TASEDIT_LIST::init()
if (currMovieData.fourscore) AddFourscore();
listItems = ListView_GetCountPerPage(hwndList);
// calculate scr_bmp coordinates (relative to the listview top-left corner
RECT temp_rect, parent_rect;
GetWindowRect(hwndTasEdit, &parent_rect);
GetWindowRect(hwndHeader, &temp_rect);
bookmarks.scr_bmp_x = temp_rect.left - parent_rect.left;
bookmarks.scr_bmp_y = temp_rect.bottom - parent_rect.top;
update();
}
void TASEDIT_LIST::free()
{
if (himglist)
{
ImageList_Destroy(himglist);
himglist = 0;
}
}
@ -178,6 +177,36 @@ void TASEDIT_LIST::update()
}
void TASEDIT_LIST::save(EMUFILE *os)
{
// write "LIST" string
os->fwrite(list_save_id, LIST_ID_LEN);
// write current top item
int top_item = ListView_GetTopIndex(hwndList);
write32le(top_item, os);
}
// returns true if couldn't load
bool TASEDIT_LIST::load(EMUFILE *is)
{
update();
// read "LIST" string
char save_id[LIST_ID_LEN];
if ((int)is->fread(save_id, LIST_ID_LEN) < LIST_ID_LEN) goto error;
if (strcmp(list_save_id, save_id)) goto error; // string is not valid
// read current top item and scroll list there
int top_item;
if (!read32le(&top_item, is)) goto error;
ListView_EnsureVisible(hwndList, currMovieData.getNumRecords() - 1, FALSE);
ListView_EnsureVisible(hwndList, top_item, FALSE);
return false;
error:
// scroll to the beginning
ListView_EnsureVisible(hwndList, 0, FALSE);
return true;
}
// ----------------------------------------------------------------------
void TASEDIT_LIST::AddFourscore()
{
@ -413,19 +442,19 @@ LONG TASEDIT_LIST::CustomDraw(NMLVCUSTOMDRAW* msg)
if (cell_y == history.GetUndoHint())
{
// undo hint here
if(TASEdit_show_markers && (int)markers.markers_array.size() > cell_y && (markers.markers_array[cell_y] & MARKER_FLAG_BIT))
if(TASEdit_show_markers && markers.GetMarker(cell_y))
msg->clrTextBk = MARKED_UNDOHINT_FRAMENUM_COLOR;
else
msg->clrTextBk = UNDOHINT_FRAMENUM_COLOR;
} else if (cell_y == currFrameCounter || cell_y == (playback.GetPauseFrame() - 1))
{
// current frame
if(TASEdit_show_markers && (int)markers.markers_array.size() > cell_y && (markers.markers_array[cell_y] & MARKER_FLAG_BIT))
if(TASEdit_show_markers && markers.GetMarker(cell_y))
// this frame is also marked
msg->clrTextBk = CUR_MARKED_FRAMENUM_COLOR;
else
msg->clrTextBk = CUR_FRAMENUM_COLOR;
} else if(TASEdit_show_markers && (int)markers.markers_array.size() > cell_y && (markers.markers_array[cell_y] & MARKER_FLAG_BIT))
} else if(TASEdit_show_markers && markers.GetMarker(cell_y))
{
// marked frame
msg->clrTextBk = MARKED_FRAMENUM_COLOR;

View File

@ -1,4 +1,6 @@
//Specification file for TASEDIT_LIST class
#define LIST_ID_LEN 5
#define CDDS_SUBITEMPREPAINT (CDDS_SUBITEM | CDDS_ITEMPREPAINT)
#define CDDS_SUBITEMPOSTPAINT (CDDS_SUBITEM | CDDS_ITEMPOSTPAINT)
#define CDDS_SUBITEMPREERASE (CDDS_SUBITEM | CDDS_ITEMPREERASE)
@ -90,6 +92,9 @@ public:
void free();
void update();
void save(EMUFILE *os);
bool load(EMUFILE *is);
void AddFourscore();
void RemoveFourscore();

View File

@ -4,15 +4,33 @@
char selection_save_id[SELECTION_ID_LEN] = "SELECTION";
extern HWND hwndTasEdit;
extern MARKERS markers;
extern TASEDIT_LIST tasedit_list;
// resources
char selectionText[] = "Selection: ";
char selectionEmptyText[] = "Selection: no";
char numTextRow[] = "1 row, ";
char numTextRows[] = " rows, ";
char numTextColumn[] = "1 column";
char numTextColumns[] = " columns";
char clipboardText[] = "Clipboard: ";
char clipboardEmptyText[] = "Clipboard: empty";
TASEDIT_SELECTION::TASEDIT_SELECTION()
{
}
void TASEDIT_SELECTION::init(int new_size)
{
hwndPrevMarker = GetDlgItem(hwndTasEdit, TASEDIT_PREV_MARKER);
hwndNextMarker = GetDlgItem(hwndTasEdit, TASEDIT_NEXT_MARKER);
hwndFindBestMarker = GetDlgItem(hwndTasEdit, TASEDIT_FIND_BEST_MARKER);
hwndFindNextMarker = GetDlgItem(hwndTasEdit, TASEDIT_FIND_NEXT_MARKER);
hwndTextSelection = GetDlgItem(hwndTasEdit, IDC_TEXT_SELECTION);
hwndTextClipboard = GetDlgItem(hwndTasEdit, IDC_TEXT_CLIPBOARD);
// init vars
if (new_size > 0)
history_size = new_size + 1;
@ -23,16 +41,24 @@ void TASEDIT_SELECTION::init(int new_size)
history_cursor_pos = -1;
// create initial selection
AddNewSelectionToHistory();
track_selection_changes = true;
reset();
RedrawTextClipboard();
}
void TASEDIT_SELECTION::free()
{
// clear history
selections_history.resize(0);
history_total_items = 0;
temp_selection.clear();
clipboard_selection.clear();
}
void TASEDIT_SELECTION::reset()
{
old_prev_marker_button_state = prev_marker_button_state = false;
old_next_marker_button_state = next_marker_button_state = false;
must_redraw_text = true;
}
void TASEDIT_SELECTION::update()
{
@ -49,9 +75,138 @@ void TASEDIT_SELECTION::update()
if (!CurrentSelection().size()) break;
}
}
// update << and >> buttons
old_prev_marker_button_state = prev_marker_button_state;
prev_marker_button_state = ((Button_GetState(hwndPrevMarker) & BST_PUSHED) != 0);
if (prev_marker_button_state)
{
if (!old_prev_marker_button_state)
{
button_hold_time = clock();
JumpPrevMarker();
} else if (button_hold_time + HOLD_REPEAT_DELAY < clock())
{
JumpPrevMarker();
}
}
old_next_marker_button_state = next_marker_button_state;
next_marker_button_state = (Button_GetState(hwndNextMarker) & BST_PUSHED) != 0;
if (next_marker_button_state)
{
if (!old_next_marker_button_state)
{
button_hold_time = clock();
JumpNextMarker();
} else if (button_hold_time + HOLD_REPEAT_DELAY < clock())
{
JumpNextMarker();
}
}
// redraw selection info text of needed
if (must_redraw_text)
{
if (CurrentSelection().size())
{
char new_text[100];
strcpy(new_text, selectionText);
char num[11];
// rows
if (CurrentSelection().size() > 1)
{
_itoa(CurrentSelection().size(), num, 10);
strcat(new_text, num);
strcat(new_text, numTextRows);
} else
{
strcat(new_text, numTextRow);
}
// columns
int columns; // in future the number of columns will depend on selected columns
if (currMovieData.fourscore) columns = 32; else columns = 16;
if (columns > 1)
{
_itoa(columns, num, 10);
strcat(new_text, num);
strcat(new_text, numTextColumns);
} else
{
strcat(new_text, numTextColumn);
}
SetWindowText(hwndTextSelection, new_text);
} else
SetWindowText(hwndTextSelection, selectionEmptyText);
must_redraw_text = false;
}
}
void TASEDIT_SELECTION::RedrawTextClipboard()
{
if (clipboard_selection.size())
{
char new_text[100];
strcpy(new_text, clipboardText);
char num[11];
// rows
if (clipboard_selection.size() > 1)
{
_itoa(clipboard_selection.size(), num, 10);
strcat(new_text, num);
strcat(new_text, numTextRows);
} else
{
strcat(new_text, numTextRow);
}
// columns
int columns; // in future the number of columns will depend on selected columns
if (currMovieData.fourscore) columns = 32; else columns = 16;
if (columns > 1)
{
_itoa(columns, num, 10);
strcat(new_text, num);
strcat(new_text, numTextColumns);
} else
{
strcat(new_text, numTextColumn);
}
SetWindowText(hwndTextClipboard, new_text);
} else
SetWindowText(hwndTextClipboard, clipboardEmptyText);
}
void TASEDIT_SELECTION::JumpPrevMarker()
{
// jump to previous marker
int index = GetCurrentSelectionBeginning();
if (index < 0) index = currFrameCounter; // if nothing is selected, consider playback cursor as current selection
for (index--; index >= 0; index--)
if (markers.GetMarker(index)) break;
if (index >= 0)
JumpToFrame(index);
else
JumpToFrame(0);
}
void TASEDIT_SELECTION::JumpNextMarker()
{
// jump to next marker
int index = GetCurrentSelectionBeginning();
if (index < 0) index = currFrameCounter; // if nothing is selected, consider playback cursor as current selection
int last_frame = currMovieData.getNumRecords()-1;
for (++index; index <= last_frame; ++index)
if (markers.GetMarker(index)) break;
if (index <= last_frame)
JumpToFrame(index);
else
JumpToFrame(last_frame);
}
void TASEDIT_SELECTION::JumpToFrame(int frame)
{
ClearSelection();
SetRowSelection(frame);
tasedit_list.FollowSelection();
}
// ----------------------------------------------------------
void TASEDIT_SELECTION::save(EMUFILE *os)
{
// write "SELECTION" string
@ -114,6 +269,7 @@ bool TASEDIT_SELECTION::load(EMUFILE *is)
if (loadSelection(clipboard_selection, is)) goto error;
// all ok
EnforceSelectionToList();
reset();
return false;
error:
return true;
@ -162,6 +318,8 @@ void TASEDIT_SELECTION::ItemRangeChanged(NMLVODSTATECHANGE* info)
else
for(int i = info->iFrom; i <= info->iTo; ++i)
CurrentSelection().erase(i);
must_redraw_text = true;
}
void TASEDIT_SELECTION::ItemChanged(NMLISTVIEW* info)
{
@ -193,6 +351,8 @@ void TASEDIT_SELECTION::ItemChanged(NMLISTVIEW* info)
else if(OFF)
CurrentSelection().erase(item);
}
must_redraw_text = true;
}
// ----------------------------------------------------------
void TASEDIT_SELECTION::AddNewSelectionToHistory()
@ -242,6 +402,7 @@ void TASEDIT_SELECTION::MemorizeClipboardSelection()
{
// copy currently strobed selection data to clipboard_selection
clipboard_selection = temp_selection;
RedrawTextClipboard();
}
void TASEDIT_SELECTION::ReselectClipboard()
{
@ -277,7 +438,6 @@ void TASEDIT_SELECTION::EnforceSelectionToList()
void TASEDIT_SELECTION::SelectAll()
{
ListView_SetItemState(tasedit_list.hwndList, -1, LVIS_SELECTED, LVIS_SELECTED);
//RedrawList();
}
void TASEDIT_SELECTION::SetRowSelection(int index)
{
@ -304,10 +464,10 @@ void TASEDIT_SELECTION::SelectMidMarkers()
// find markers
// searching up starting from center-0
for (upper_marker = center; upper_marker >= 0; upper_marker--)
if (markers.markers_array[upper_marker] & MARKER_FLAG_BIT) break;
if (markers.GetMarker(upper_marker)) break;
// searching down starting from center+1
for (lower_marker = center+1; lower_marker < movie_size; ++lower_marker)
if (markers.markers_array[lower_marker] & MARKER_FLAG_BIT) break;
if (markers.GetMarker(lower_marker)) break;
// clear selection without clearing focused, because otherwise there's strange bug when quickly pressing Ctrl+A right after clicking on already selected row
ListView_SetItemState(tasedit_list.hwndList, -1, 0, LVIS_SELECTED);
@ -388,6 +548,11 @@ SelectionFrames& TASEDIT_SELECTION::GetStrobedSelection()
{
return temp_selection;
}
SelectionFrames& TASEDIT_SELECTION::GetInsertedSet()
{
return inserted_set;
}
// this getter is only for inside-class use
SelectionFrames& TASEDIT_SELECTION::CurrentSelection()
{

View File

@ -8,8 +8,11 @@ public:
TASEDIT_SELECTION();
void init(int new_size = 0);
void free();
void reset();
void update();
void RedrawTextClipboard();
void save(EMUFILE *os);
bool load(EMUFILE *is);
void saveSelection(SelectionFrames& selection, EMUFILE *os);
@ -38,6 +41,10 @@ public:
void SetRegionSelection(int start, int end);
void SelectMidMarkers();
void JumpPrevMarker();
void JumpNextMarker();
void JumpToFrame(int frame);
// getters
int GetCurrentSelectionSize();
int GetCurrentSelectionBeginning();
@ -45,14 +52,23 @@ public:
SelectionFrames* MakeStrobe();
SelectionFrames& GetStrobedSelection();
SelectionFrames& GetInsertedSet();
private:
SelectionFrames& CurrentSelection();
bool track_selection_changes;
bool must_redraw_text;
bool old_prev_marker_button_state, prev_marker_button_state;
bool old_next_marker_button_state, next_marker_button_state;
int button_hold_time;
std::vector<SelectionFrames> selections_history;
SelectionFrames clipboard_selection;
SelectionFrames inserted_set;
int history_cursor_pos;
int history_start_pos;
int history_total_items;
@ -60,4 +76,7 @@ private:
SelectionFrames temp_selection;
HWND hwndPrevMarker, hwndNextMarker, hwndFindBestMarker, hwndFindNextMarker;
HWND hwndTextSelection, hwndTextClipboard;
};

View File

@ -1,11 +1,12 @@
//Implementation file of TASEdit Project class
#include "taseditproj.h"
extern MARKERS markers;
extern BOOKMARKS bookmarks;
extern SCREENSHOT_DISPLAY screenshot_display;
extern GREENZONE greenzone;
extern PLAYBACK playback;
extern RECORDER recorder;
extern INPUT_HISTORY history;
extern TASEDIT_LIST tasedit_list;
extern TASEDIT_SELECTION selection;
@ -59,6 +60,7 @@ bool TASEDIT_PROJECT::saveProject()
greenzone.save(ofs);
history.save(ofs);
selection.save(ofs);
tasedit_list.save(ofs);
delete ofs;
@ -81,7 +83,6 @@ bool TASEDIT_PROJECT::LoadProject(std::string PFN)
bool error;
LoadFM2(currMovieData, &ifs, ifs.size(), false);
LoadSubtitles(currMovieData);
tasedit_list.update();
// try to load markers
error = markers.load(&ifs);
if (error)
@ -125,14 +126,23 @@ bool TASEDIT_PROJECT::LoadProject(std::string PFN)
{
FCEU_printf("Error loading selection\n");
selection.init();
} else
{
// update and try to load list
error = tasedit_list.load(&ifs);
}
if (error)
{
FCEU_printf("Error loading list\n");
}
playback.reset();
recorder.reset();
screenshot_display.reset();
reset();
playback.updateProgressbar();
return true;
}
// -----------------------------------------------------------------
//All the get/set functions...
std::string TASEDIT_PROJECT::GetProjectName()
{
return projectName;

View File

@ -14,6 +14,7 @@ typedef std::set<int> SelectionFrames;
#include "bookmarks.h"
#include "tasedit_list.h"
#include "tasedit_sel.h"
#include "screenshot_display.h"
#define AUTOSAVE_PERIOD_SCALE 60000 // = 1 minute in milliseconds

View File

@ -984,7 +984,7 @@ static int _currCommand = 0;
//either dumps the current joystick state or loads one state from the movie
void FCEUMOV_AddInputState()
{
#ifdef _WIN32
#ifdef _WIN32
if(movieMode == MOVIEMODE_TASEDIT)
{
// if movie length is less than currFrame, pad it with empty frames
@ -992,7 +992,7 @@ void FCEUMOV_AddInputState()
currMovieData.insertEmpty(-1, 1 + currFrameCounter - (int)currMovieData.records.size());
MovieRecord* mr = &currMovieData.records[currFrameCounter];
if(movie_readonly || turbo || pauseframe > currFrameCounter)
if(movie_readonly || turbo || playback.pause_frame > currFrameCounter)
{
// do not record buttons
if(mr->command_reset())
@ -1008,10 +1008,11 @@ void FCEUMOV_AddInputState()
// record buttons
joyports[0].log(mr);
joyports[1].log(mr);
recorder.InputChangedRec();
recorder.InputChanged();
}
_currCommand = 0;
} else
#endif
#endif
if(movieMode == MOVIEMODE_PLAY)
{
//stop when we run out of frames

View File

@ -429,6 +429,7 @@
<ClCompile Include="..\src\drivers\win\taseditlib\markers.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\playback.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\recorder.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\screenshot_display.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\tasedit_list.cpp" />
<ClCompile Include="..\src\drivers\win\taseditlib\tasedit_sel.cpp" />
<ClCompile Include="..\src\drivers\win\texthook.cpp" />
@ -749,6 +750,7 @@
<ClInclude Include="..\src\drivers\win\taseditlib\markers.h" />
<ClInclude Include="..\src\drivers\win\taseditlib\playback.h" />
<ClInclude Include="..\src\drivers\win\taseditlib\recorder.h" />
<ClInclude Include="..\src\drivers\win\taseditlib\screenshot_display.h" />
<ClInclude Include="..\src\drivers\win\taseditlib\tasedit_list.h" />
<ClInclude Include="..\src\drivers\win\taseditlib\tasedit_sel.h" />
<ClInclude Include="..\src\drivers\win\texthook.h" />

View File

@ -937,6 +937,7 @@
<ClCompile Include="..\src\drivers\win\taseditlib\recorder.cpp">
<Filter>drivers\win\taseditlib</Filter>
</ClCompile>
<ClCompile Include="..\src\drivers\win\taseditlib\screenshot_display.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\cart.h">
@ -1408,6 +1409,7 @@
<ClInclude Include="..\src\drivers\win\taseditlib\recorder.h">
<Filter>drivers\win\taseditlib</Filter>
</ClInclude>
<ClInclude Include="..\src\drivers\win\taseditlib\screenshot_display.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\src\drivers\win\res.rc">